(req *http.Request, dumps []*dump.Dumper)
| 1688 | } |
| 1689 | |
| 1690 | func (cs *clientStream) writeRequestBody(req *http.Request, dumps []*dump.Dumper) (err error) { |
| 1691 | cc := cs.cc |
| 1692 | body := cs.reqBody |
| 1693 | sentEnd := false // whether we sent the final DATA frame w/ END_STREAM |
| 1694 | |
| 1695 | hasTrailers := req.Trailer != nil |
| 1696 | remainLen := cs.reqBodyContentLength |
| 1697 | hasContentLen := remainLen != -1 |
| 1698 | |
| 1699 | cc.mu.Lock() |
| 1700 | maxFrameSize := int(cc.maxFrameSize) |
| 1701 | cc.mu.Unlock() |
| 1702 | |
| 1703 | // Scratch buffer for reading into & writing from. |
| 1704 | scratchLen := cs.frameScratchBufferLen(maxFrameSize) |
| 1705 | var buf []byte |
| 1706 | index := bufPoolIndex(scratchLen) |
| 1707 | if bp, ok := bufPools[index].Get().(*[]byte); ok && len(*bp) >= scratchLen { |
| 1708 | defer bufPools[index].Put(bp) |
| 1709 | buf = *bp |
| 1710 | } else { |
| 1711 | buf = make([]byte, scratchLen) |
| 1712 | defer bufPools[index].Put(&buf) |
| 1713 | } |
| 1714 | |
| 1715 | writeData := cc.fr.WriteData |
| 1716 | if len(dumps) > 0 { |
| 1717 | writeData = func(streamID uint32, endStream bool, data []byte) error { |
| 1718 | for _, dump := range dumps { |
| 1719 | dump.DumpRequestBody(data) |
| 1720 | } |
| 1721 | return cc.fr.WriteData(streamID, endStream, data) |
| 1722 | } |
| 1723 | } |
| 1724 | |
| 1725 | var sawEOF bool |
| 1726 | for !sawEOF { |
| 1727 | n, err := body.Read(buf[:]) |
| 1728 | if hasContentLen { |
| 1729 | remainLen -= int64(n) |
| 1730 | if remainLen == 0 && err == nil { |
| 1731 | // The request body's Content-Length was predeclared and |
| 1732 | // we just finished reading it all, but the underlying io.textprotoReader |
| 1733 | // returned the final chunk with a nil error (which is one of |
| 1734 | // the two valid things a textprotoReader can do at EOF). Because we'd prefer |
| 1735 | // to send the END_STREAM bit early, double-check that we're actually |
| 1736 | // at EOF. Subsequent reads should return (0, EOF) at this point. |
| 1737 | // If either value is different, we return an error in one of two ways below. |
| 1738 | var scratch [1]byte |
| 1739 | var n1 int |
| 1740 | n1, err = body.Read(scratch[:]) |
| 1741 | remainLen -= int64(n1) |
| 1742 | } |
| 1743 | if remainLen < 0 { |
| 1744 | err = errReqBodyTooLong |
| 1745 | return err |
| 1746 | } |
| 1747 | } |
no test coverage detected