]> Cypherpunks.ru repositories - gostls13.git/blob - src/net/http/transfer.go
net/http: add NoBody, don't return nil from NewRequest on zero bodies
[gostls13.git] / src / net / http / transfer.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package http
6
7 import (
8         "bufio"
9         "bytes"
10         "errors"
11         "fmt"
12         "io"
13         "io/ioutil"
14         "net/http/internal"
15         "net/textproto"
16         "sort"
17         "strconv"
18         "strings"
19         "sync"
20
21         "golang_org/x/net/lex/httplex"
22 )
23
24 // ErrLineTooLong is returned when reading request or response bodies
25 // with malformed chunked encoding.
26 var ErrLineTooLong = internal.ErrLineTooLong
27
28 type errorReader struct {
29         err error
30 }
31
32 func (r errorReader) Read(p []byte) (n int, err error) {
33         return 0, r.err
34 }
35
36 // transferWriter inspects the fields of a user-supplied Request or Response,
37 // sanitizes them without changing the user object and provides methods for
38 // writing the respective header, body and trailer in wire format.
39 type transferWriter struct {
40         Method           string
41         Body             io.Reader
42         BodyCloser       io.Closer
43         ResponseToHEAD   bool
44         ContentLength    int64 // -1 means unknown, 0 means exactly none
45         Close            bool
46         TransferEncoding []string
47         Trailer          Header
48         IsResponse       bool
49 }
50
51 func newTransferWriter(r interface{}) (t *transferWriter, err error) {
52         t = &transferWriter{}
53
54         // Extract relevant fields
55         atLeastHTTP11 := false
56         switch rr := r.(type) {
57         case *Request:
58                 if rr.ContentLength != 0 && rr.Body == nil {
59                         return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength)
60                 }
61                 t.Method = valueOrDefault(rr.Method, "GET")
62                 t.Close = rr.Close
63                 t.TransferEncoding = rr.TransferEncoding
64                 t.Trailer = rr.Trailer
65                 atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
66
67                 t.Body = rr.Body
68                 t.ContentLength = rr.outgoingLength()
69                 if t.Body != nil {
70                         t.BodyCloser = rr.Body
71                 }
72                 if t.ContentLength < 0 && len(t.TransferEncoding) == 0 && atLeastHTTP11 {
73                         t.TransferEncoding = []string{"chunked"}
74                 }
75         case *Response:
76                 t.IsResponse = true
77                 if rr.Request != nil {
78                         t.Method = rr.Request.Method
79                 }
80                 t.Body = rr.Body
81                 t.BodyCloser = rr.Body
82                 t.ContentLength = rr.ContentLength
83                 t.Close = rr.Close
84                 t.TransferEncoding = rr.TransferEncoding
85                 t.Trailer = rr.Trailer
86                 atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
87                 t.ResponseToHEAD = noBodyExpected(t.Method)
88         }
89
90         // Sanitize Body,ContentLength,TransferEncoding
91         if t.ResponseToHEAD {
92                 t.Body = nil
93                 if chunked(t.TransferEncoding) {
94                         t.ContentLength = -1
95                 }
96         } else {
97                 if !atLeastHTTP11 || t.Body == nil {
98                         t.TransferEncoding = nil
99                 }
100                 if chunked(t.TransferEncoding) {
101                         t.ContentLength = -1
102                 } else if t.Body == nil { // no chunking, no body
103                         t.ContentLength = 0
104                 }
105         }
106
107         // Sanitize Trailer
108         if !chunked(t.TransferEncoding) {
109                 t.Trailer = nil
110         }
111
112         return t, nil
113 }
114
115 func noBodyExpected(requestMethod string) bool {
116         return requestMethod == "HEAD"
117 }
118
119 func (t *transferWriter) shouldSendContentLength() bool {
120         if chunked(t.TransferEncoding) {
121                 return false
122         }
123         if t.ContentLength > 0 {
124                 return true
125         }
126         if t.ContentLength < 0 {
127                 return false
128         }
129         // Many servers expect a Content-Length for these methods
130         if t.Method == "POST" || t.Method == "PUT" {
131                 return true
132         }
133         if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
134                 if t.Method == "GET" || t.Method == "HEAD" {
135                         return false
136                 }
137                 return true
138         }
139
140         return false
141 }
142
143 func (t *transferWriter) WriteHeader(w io.Writer) error {
144         if t.Close {
145                 if _, err := io.WriteString(w, "Connection: close\r\n"); err != nil {
146                         return err
147                 }
148         }
149
150         // Write Content-Length and/or Transfer-Encoding whose values are a
151         // function of the sanitized field triple (Body, ContentLength,
152         // TransferEncoding)
153         if t.shouldSendContentLength() {
154                 if _, err := io.WriteString(w, "Content-Length: "); err != nil {
155                         return err
156                 }
157                 if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil {
158                         return err
159                 }
160         } else if chunked(t.TransferEncoding) {
161                 if _, err := io.WriteString(w, "Transfer-Encoding: chunked\r\n"); err != nil {
162                         return err
163                 }
164         }
165
166         // Write Trailer header
167         if t.Trailer != nil {
168                 keys := make([]string, 0, len(t.Trailer))
169                 for k := range t.Trailer {
170                         k = CanonicalHeaderKey(k)
171                         switch k {
172                         case "Transfer-Encoding", "Trailer", "Content-Length":
173                                 return &badStringError{"invalid Trailer key", k}
174                         }
175                         keys = append(keys, k)
176                 }
177                 if len(keys) > 0 {
178                         sort.Strings(keys)
179                         // TODO: could do better allocation-wise here, but trailers are rare,
180                         // so being lazy for now.
181                         if _, err := io.WriteString(w, "Trailer: "+strings.Join(keys, ",")+"\r\n"); err != nil {
182                                 return err
183                         }
184                 }
185         }
186
187         return nil
188 }
189
190 func (t *transferWriter) WriteBody(w io.Writer) error {
191         var err error
192         var ncopy int64
193
194         // Write body
195         if t.Body != nil {
196                 if chunked(t.TransferEncoding) {
197                         if bw, ok := w.(*bufio.Writer); ok && !t.IsResponse {
198                                 w = &internal.FlushAfterChunkWriter{Writer: bw}
199                         }
200                         cw := internal.NewChunkedWriter(w)
201                         _, err = io.Copy(cw, t.Body)
202                         if err == nil {
203                                 err = cw.Close()
204                         }
205                 } else if t.ContentLength == -1 {
206                         ncopy, err = io.Copy(w, t.Body)
207                 } else {
208                         ncopy, err = io.Copy(w, io.LimitReader(t.Body, t.ContentLength))
209                         if err != nil {
210                                 return err
211                         }
212                         var nextra int64
213                         nextra, err = io.Copy(ioutil.Discard, t.Body)
214                         ncopy += nextra
215                 }
216                 if err != nil {
217                         return err
218                 }
219                 if err = t.BodyCloser.Close(); err != nil {
220                         return err
221                 }
222         }
223
224         if !t.ResponseToHEAD && t.ContentLength != -1 && t.ContentLength != ncopy {
225                 return fmt.Errorf("http: ContentLength=%d with Body length %d",
226                         t.ContentLength, ncopy)
227         }
228
229         if chunked(t.TransferEncoding) {
230                 // Write Trailer header
231                 if t.Trailer != nil {
232                         if err := t.Trailer.Write(w); err != nil {
233                                 return err
234                         }
235                 }
236                 // Last chunk, empty trailer
237                 _, err = io.WriteString(w, "\r\n")
238         }
239         return err
240 }
241
242 type transferReader struct {
243         // Input
244         Header        Header
245         StatusCode    int
246         RequestMethod string
247         ProtoMajor    int
248         ProtoMinor    int
249         // Output
250         Body             io.ReadCloser
251         ContentLength    int64
252         TransferEncoding []string
253         Close            bool
254         Trailer          Header
255 }
256
257 func (t *transferReader) protoAtLeast(m, n int) bool {
258         return t.ProtoMajor > m || (t.ProtoMajor == m && t.ProtoMinor >= n)
259 }
260
261 // bodyAllowedForStatus reports whether a given response status code
262 // permits a body. See RFC 2616, section 4.4.
263 func bodyAllowedForStatus(status int) bool {
264         switch {
265         case status >= 100 && status <= 199:
266                 return false
267         case status == 204:
268                 return false
269         case status == 304:
270                 return false
271         }
272         return true
273 }
274
275 var (
276         suppressedHeaders304    = []string{"Content-Type", "Content-Length", "Transfer-Encoding"}
277         suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"}
278 )
279
280 func suppressedHeaders(status int) []string {
281         switch {
282         case status == 304:
283                 // RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers"
284                 return suppressedHeaders304
285         case !bodyAllowedForStatus(status):
286                 return suppressedHeadersNoBody
287         }
288         return nil
289 }
290
291 // msg is *Request or *Response.
292 func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
293         t := &transferReader{RequestMethod: "GET"}
294
295         // Unify input
296         isResponse := false
297         switch rr := msg.(type) {
298         case *Response:
299                 t.Header = rr.Header
300                 t.StatusCode = rr.StatusCode
301                 t.ProtoMajor = rr.ProtoMajor
302                 t.ProtoMinor = rr.ProtoMinor
303                 t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true)
304                 isResponse = true
305                 if rr.Request != nil {
306                         t.RequestMethod = rr.Request.Method
307                 }
308         case *Request:
309                 t.Header = rr.Header
310                 t.RequestMethod = rr.Method
311                 t.ProtoMajor = rr.ProtoMajor
312                 t.ProtoMinor = rr.ProtoMinor
313                 // Transfer semantics for Requests are exactly like those for
314                 // Responses with status code 200, responding to a GET method
315                 t.StatusCode = 200
316                 t.Close = rr.Close
317         default:
318                 panic("unexpected type")
319         }
320
321         // Default to HTTP/1.1
322         if t.ProtoMajor == 0 && t.ProtoMinor == 0 {
323                 t.ProtoMajor, t.ProtoMinor = 1, 1
324         }
325
326         // Transfer encoding, content length
327         err = t.fixTransferEncoding()
328         if err != nil {
329                 return err
330         }
331
332         realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding)
333         if err != nil {
334                 return err
335         }
336         if isResponse && t.RequestMethod == "HEAD" {
337                 if n, err := parseContentLength(t.Header.get("Content-Length")); err != nil {
338                         return err
339                 } else {
340                         t.ContentLength = n
341                 }
342         } else {
343                 t.ContentLength = realLength
344         }
345
346         // Trailer
347         t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding)
348         if err != nil {
349                 return err
350         }
351
352         // If there is no Content-Length or chunked Transfer-Encoding on a *Response
353         // and the status is not 1xx, 204 or 304, then the body is unbounded.
354         // See RFC 2616, section 4.4.
355         switch msg.(type) {
356         case *Response:
357                 if realLength == -1 &&
358                         !chunked(t.TransferEncoding) &&
359                         bodyAllowedForStatus(t.StatusCode) {
360                         // Unbounded body.
361                         t.Close = true
362                 }
363         }
364
365         // Prepare body reader. ContentLength < 0 means chunked encoding
366         // or close connection when finished, since multipart is not supported yet
367         switch {
368         case chunked(t.TransferEncoding):
369                 if noBodyExpected(t.RequestMethod) {
370                         t.Body = NoBody
371                 } else {
372                         t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}
373                 }
374         case realLength == 0:
375                 t.Body = NoBody
376         case realLength > 0:
377                 t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close}
378         default:
379                 // realLength < 0, i.e. "Content-Length" not mentioned in header
380                 if t.Close {
381                         // Close semantics (i.e. HTTP/1.0)
382                         t.Body = &body{src: r, closing: t.Close}
383                 } else {
384                         // Persistent connection (i.e. HTTP/1.1)
385                         t.Body = NoBody
386                 }
387         }
388
389         // Unify output
390         switch rr := msg.(type) {
391         case *Request:
392                 rr.Body = t.Body
393                 rr.ContentLength = t.ContentLength
394                 rr.TransferEncoding = t.TransferEncoding
395                 rr.Close = t.Close
396                 rr.Trailer = t.Trailer
397         case *Response:
398                 rr.Body = t.Body
399                 rr.ContentLength = t.ContentLength
400                 rr.TransferEncoding = t.TransferEncoding
401                 rr.Close = t.Close
402                 rr.Trailer = t.Trailer
403         }
404
405         return nil
406 }
407
408 // Checks whether chunked is part of the encodings stack
409 func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
410
411 // Checks whether the encoding is explicitly "identity".
412 func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
413
414 // fixTransferEncoding sanitizes t.TransferEncoding, if needed.
415 func (t *transferReader) fixTransferEncoding() error {
416         raw, present := t.Header["Transfer-Encoding"]
417         if !present {
418                 return nil
419         }
420         delete(t.Header, "Transfer-Encoding")
421
422         // Issue 12785; ignore Transfer-Encoding on HTTP/1.0 requests.
423         if !t.protoAtLeast(1, 1) {
424                 return nil
425         }
426
427         encodings := strings.Split(raw[0], ",")
428         te := make([]string, 0, len(encodings))
429         // TODO: Even though we only support "identity" and "chunked"
430         // encodings, the loop below is designed with foresight. One
431         // invariant that must be maintained is that, if present,
432         // chunked encoding must always come first.
433         for _, encoding := range encodings {
434                 encoding = strings.ToLower(strings.TrimSpace(encoding))
435                 // "identity" encoding is not recorded
436                 if encoding == "identity" {
437                         break
438                 }
439                 if encoding != "chunked" {
440                         return &badStringError{"unsupported transfer encoding", encoding}
441                 }
442                 te = te[0 : len(te)+1]
443                 te[len(te)-1] = encoding
444         }
445         if len(te) > 1 {
446                 return &badStringError{"too many transfer encodings", strings.Join(te, ",")}
447         }
448         if len(te) > 0 {
449                 // RFC 7230 3.3.2 says "A sender MUST NOT send a
450                 // Content-Length header field in any message that
451                 // contains a Transfer-Encoding header field."
452                 //
453                 // but also:
454                 // "If a message is received with both a
455                 // Transfer-Encoding and a Content-Length header
456                 // field, the Transfer-Encoding overrides the
457                 // Content-Length. Such a message might indicate an
458                 // attempt to perform request smuggling (Section 9.5)
459                 // or response splitting (Section 9.4) and ought to be
460                 // handled as an error. A sender MUST remove the
461                 // received Content-Length field prior to forwarding
462                 // such a message downstream."
463                 //
464                 // Reportedly, these appear in the wild.
465                 delete(t.Header, "Content-Length")
466                 t.TransferEncoding = te
467                 return nil
468         }
469
470         return nil
471 }
472
473 // Determine the expected body length, using RFC 2616 Section 4.4. This
474 // function is not a method, because ultimately it should be shared by
475 // ReadResponse and ReadRequest.
476 func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) {
477         isRequest := !isResponse
478         contentLens := header["Content-Length"]
479
480         // Hardening against HTTP request smuggling
481         if len(contentLens) > 1 {
482                 // Per RFC 7230 Section 3.3.2, prevent multiple
483                 // Content-Length headers if they differ in value.
484                 // If there are dups of the value, remove the dups.
485                 // See Issue 16490.
486                 first := strings.TrimSpace(contentLens[0])
487                 for _, ct := range contentLens[1:] {
488                         if first != strings.TrimSpace(ct) {
489                                 return 0, fmt.Errorf("http: message cannot contain multiple Content-Length headers; got %q", contentLens)
490                         }
491                 }
492
493                 // deduplicate Content-Length
494                 header.Del("Content-Length")
495                 header.Add("Content-Length", first)
496
497                 contentLens = header["Content-Length"]
498         }
499
500         // Logic based on response type or status
501         if noBodyExpected(requestMethod) {
502                 // For HTTP requests, as part of hardening against request
503                 // smuggling (RFC 7230), don't allow a Content-Length header for
504                 // methods which don't permit bodies. As an exception, allow
505                 // exactly one Content-Length header if its value is "0".
506                 if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == "0") {
507                         return 0, fmt.Errorf("http: method cannot contain a Content-Length; got %q", contentLens)
508                 }
509                 return 0, nil
510         }
511         if status/100 == 1 {
512                 return 0, nil
513         }
514         switch status {
515         case 204, 304:
516                 return 0, nil
517         }
518
519         // Logic based on Transfer-Encoding
520         if chunked(te) {
521                 return -1, nil
522         }
523
524         // Logic based on Content-Length
525         var cl string
526         if len(contentLens) == 1 {
527                 cl = strings.TrimSpace(contentLens[0])
528         }
529         if cl != "" {
530                 n, err := parseContentLength(cl)
531                 if err != nil {
532                         return -1, err
533                 }
534                 return n, nil
535         } else {
536                 header.Del("Content-Length")
537         }
538
539         if isRequest {
540                 // RFC 2616 neither explicitly permits nor forbids an
541                 // entity-body on a GET request so we permit one if
542                 // declared, but we default to 0 here (not -1 below)
543                 // if there's no mention of a body.
544                 // Likewise, all other request methods are assumed to have
545                 // no body if neither Transfer-Encoding chunked nor a
546                 // Content-Length are set.
547                 return 0, nil
548         }
549
550         // Body-EOF logic based on other methods (like closing, or chunked coding)
551         return -1, nil
552 }
553
554 // Determine whether to hang up after sending a request and body, or
555 // receiving a response and body
556 // 'header' is the request headers
557 func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool {
558         if major < 1 {
559                 return true
560         }
561
562         conv := header["Connection"]
563         hasClose := httplex.HeaderValuesContainsToken(conv, "close")
564         if major == 1 && minor == 0 {
565                 return hasClose || !httplex.HeaderValuesContainsToken(conv, "keep-alive")
566         }
567
568         if hasClose && removeCloseHeader {
569                 header.Del("Connection")
570         }
571
572         return hasClose
573 }
574
575 // Parse the trailer header
576 func fixTrailer(header Header, te []string) (Header, error) {
577         vv, ok := header["Trailer"]
578         if !ok {
579                 return nil, nil
580         }
581         header.Del("Trailer")
582
583         trailer := make(Header)
584         var err error
585         for _, v := range vv {
586                 foreachHeaderElement(v, func(key string) {
587                         key = CanonicalHeaderKey(key)
588                         switch key {
589                         case "Transfer-Encoding", "Trailer", "Content-Length":
590                                 if err == nil {
591                                         err = &badStringError{"bad trailer key", key}
592                                         return
593                                 }
594                         }
595                         trailer[key] = nil
596                 })
597         }
598         if err != nil {
599                 return nil, err
600         }
601         if len(trailer) == 0 {
602                 return nil, nil
603         }
604         if !chunked(te) {
605                 // Trailer and no chunking
606                 return nil, ErrUnexpectedTrailer
607         }
608         return trailer, nil
609 }
610
611 // body turns a Reader into a ReadCloser.
612 // Close ensures that the body has been fully read
613 // and then reads the trailer if necessary.
614 type body struct {
615         src          io.Reader
616         hdr          interface{}   // non-nil (Response or Request) value means read trailer
617         r            *bufio.Reader // underlying wire-format reader for the trailer
618         closing      bool          // is the connection to be closed after reading body?
619         doEarlyClose bool          // whether Close should stop early
620
621         mu         sync.Mutex // guards following, and calls to Read and Close
622         sawEOF     bool
623         closed     bool
624         earlyClose bool   // Close called and we didn't read to the end of src
625         onHitEOF   func() // if non-nil, func to call when EOF is Read
626 }
627
628 // ErrBodyReadAfterClose is returned when reading a Request or Response
629 // Body after the body has been closed. This typically happens when the body is
630 // read after an HTTP Handler calls WriteHeader or Write on its
631 // ResponseWriter.
632 var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")
633
634 func (b *body) Read(p []byte) (n int, err error) {
635         b.mu.Lock()
636         defer b.mu.Unlock()
637         if b.closed {
638                 return 0, ErrBodyReadAfterClose
639         }
640         return b.readLocked(p)
641 }
642
643 // Must hold b.mu.
644 func (b *body) readLocked(p []byte) (n int, err error) {
645         if b.sawEOF {
646                 return 0, io.EOF
647         }
648         n, err = b.src.Read(p)
649
650         if err == io.EOF {
651                 b.sawEOF = true
652                 // Chunked case. Read the trailer.
653                 if b.hdr != nil {
654                         if e := b.readTrailer(); e != nil {
655                                 err = e
656                                 // Something went wrong in the trailer, we must not allow any
657                                 // further reads of any kind to succeed from body, nor any
658                                 // subsequent requests on the server connection. See
659                                 // golang.org/issue/12027
660                                 b.sawEOF = false
661                                 b.closed = true
662                         }
663                         b.hdr = nil
664                 } else {
665                         // If the server declared the Content-Length, our body is a LimitedReader
666                         // and we need to check whether this EOF arrived early.
667                         if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 {
668                                 err = io.ErrUnexpectedEOF
669                         }
670                 }
671         }
672
673         // If we can return an EOF here along with the read data, do
674         // so. This is optional per the io.Reader contract, but doing
675         // so helps the HTTP transport code recycle its connection
676         // earlier (since it will see this EOF itself), even if the
677         // client doesn't do future reads or Close.
678         if err == nil && n > 0 {
679                 if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
680                         err = io.EOF
681                         b.sawEOF = true
682                 }
683         }
684
685         if b.sawEOF && b.onHitEOF != nil {
686                 b.onHitEOF()
687         }
688
689         return n, err
690 }
691
692 var (
693         singleCRLF = []byte("\r\n")
694         doubleCRLF = []byte("\r\n\r\n")
695 )
696
697 func seeUpcomingDoubleCRLF(r *bufio.Reader) bool {
698         for peekSize := 4; ; peekSize++ {
699                 // This loop stops when Peek returns an error,
700                 // which it does when r's buffer has been filled.
701                 buf, err := r.Peek(peekSize)
702                 if bytes.HasSuffix(buf, doubleCRLF) {
703                         return true
704                 }
705                 if err != nil {
706                         break
707                 }
708         }
709         return false
710 }
711
712 var errTrailerEOF = errors.New("http: unexpected EOF reading trailer")
713
714 func (b *body) readTrailer() error {
715         // The common case, since nobody uses trailers.
716         buf, err := b.r.Peek(2)
717         if bytes.Equal(buf, singleCRLF) {
718                 b.r.Discard(2)
719                 return nil
720         }
721         if len(buf) < 2 {
722                 return errTrailerEOF
723         }
724         if err != nil {
725                 return err
726         }
727
728         // Make sure there's a header terminator coming up, to prevent
729         // a DoS with an unbounded size Trailer. It's not easy to
730         // slip in a LimitReader here, as textproto.NewReader requires
731         // a concrete *bufio.Reader. Also, we can't get all the way
732         // back up to our conn's LimitedReader that *might* be backing
733         // this bufio.Reader. Instead, a hack: we iteratively Peek up
734         // to the bufio.Reader's max size, looking for a double CRLF.
735         // This limits the trailer to the underlying buffer size, typically 4kB.
736         if !seeUpcomingDoubleCRLF(b.r) {
737                 return errors.New("http: suspiciously long trailer after chunked body")
738         }
739
740         hdr, err := textproto.NewReader(b.r).ReadMIMEHeader()
741         if err != nil {
742                 if err == io.EOF {
743                         return errTrailerEOF
744                 }
745                 return err
746         }
747         switch rr := b.hdr.(type) {
748         case *Request:
749                 mergeSetHeader(&rr.Trailer, Header(hdr))
750         case *Response:
751                 mergeSetHeader(&rr.Trailer, Header(hdr))
752         }
753         return nil
754 }
755
756 func mergeSetHeader(dst *Header, src Header) {
757         if *dst == nil {
758                 *dst = src
759                 return
760         }
761         for k, vv := range src {
762                 (*dst)[k] = vv
763         }
764 }
765
766 // unreadDataSizeLocked returns the number of bytes of unread input.
767 // It returns -1 if unknown.
768 // b.mu must be held.
769 func (b *body) unreadDataSizeLocked() int64 {
770         if lr, ok := b.src.(*io.LimitedReader); ok {
771                 return lr.N
772         }
773         return -1
774 }
775
776 func (b *body) Close() error {
777         b.mu.Lock()
778         defer b.mu.Unlock()
779         if b.closed {
780                 return nil
781         }
782         var err error
783         switch {
784         case b.sawEOF:
785                 // Already saw EOF, so no need going to look for it.
786         case b.hdr == nil && b.closing:
787                 // no trailer and closing the connection next.
788                 // no point in reading to EOF.
789         case b.doEarlyClose:
790                 // Read up to maxPostHandlerReadBytes bytes of the body, looking for
791                 // for EOF (and trailers), so we can re-use this connection.
792                 if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > maxPostHandlerReadBytes {
793                         // There was a declared Content-Length, and we have more bytes remaining
794                         // than our maxPostHandlerReadBytes tolerance. So, give up.
795                         b.earlyClose = true
796                 } else {
797                         var n int64
798                         // Consume the body, or, which will also lead to us reading
799                         // the trailer headers after the body, if present.
800                         n, err = io.CopyN(ioutil.Discard, bodyLocked{b}, maxPostHandlerReadBytes)
801                         if err == io.EOF {
802                                 err = nil
803                         }
804                         if n == maxPostHandlerReadBytes {
805                                 b.earlyClose = true
806                         }
807                 }
808         default:
809                 // Fully consume the body, which will also lead to us reading
810                 // the trailer headers after the body, if present.
811                 _, err = io.Copy(ioutil.Discard, bodyLocked{b})
812         }
813         b.closed = true
814         return err
815 }
816
817 func (b *body) didEarlyClose() bool {
818         b.mu.Lock()
819         defer b.mu.Unlock()
820         return b.earlyClose
821 }
822
823 // bodyRemains reports whether future Read calls might
824 // yield data.
825 func (b *body) bodyRemains() bool {
826         b.mu.Lock()
827         defer b.mu.Unlock()
828         return !b.sawEOF
829 }
830
831 func (b *body) registerOnHitEOF(fn func()) {
832         b.mu.Lock()
833         defer b.mu.Unlock()
834         b.onHitEOF = fn
835 }
836
837 // bodyLocked is a io.Reader reading from a *body when its mutex is
838 // already held.
839 type bodyLocked struct {
840         b *body
841 }
842
843 func (bl bodyLocked) Read(p []byte) (n int, err error) {
844         if bl.b.closed {
845                 return 0, ErrBodyReadAfterClose
846         }
847         return bl.b.readLocked(p)
848 }
849
850 // parseContentLength trims whitespace from s and returns -1 if no value
851 // is set, or the value if it's >= 0.
852 func parseContentLength(cl string) (int64, error) {
853         cl = strings.TrimSpace(cl)
854         if cl == "" {
855                 return -1, nil
856         }
857         n, err := strconv.ParseInt(cl, 10, 64)
858         if err != nil || n < 0 {
859                 return 0, &badStringError{"bad Content-Length", cl}
860         }
861         return n, nil
862
863 }