]> Cypherpunks.ru repositories - gostls13.git/blob - src/net/http/transfer.go
[dev.boringcrypto] all: merge master into dev.boringcrypto
[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/httptrace"
15         "net/http/internal"
16         "net/textproto"
17         "reflect"
18         "sort"
19         "strconv"
20         "strings"
21         "sync"
22         "time"
23
24         "golang_org/x/net/http/httpguts"
25 )
26
27 // ErrLineTooLong is returned when reading request or response bodies
28 // with malformed chunked encoding.
29 var ErrLineTooLong = internal.ErrLineTooLong
30
31 type errorReader struct {
32         err error
33 }
34
35 func (r errorReader) Read(p []byte) (n int, err error) {
36         return 0, r.err
37 }
38
39 type byteReader struct {
40         b    byte
41         done bool
42 }
43
44 func (br *byteReader) Read(p []byte) (n int, err error) {
45         if br.done {
46                 return 0, io.EOF
47         }
48         if len(p) == 0 {
49                 return 0, nil
50         }
51         br.done = true
52         p[0] = br.b
53         return 1, io.EOF
54 }
55
56 // transferBodyReader is an io.Reader that reads from tw.Body
57 // and records any non-EOF error in tw.bodyReadError.
58 // It is exactly 1 pointer wide to avoid allocations into interfaces.
59 type transferBodyReader struct{ tw *transferWriter }
60
61 func (br transferBodyReader) Read(p []byte) (n int, err error) {
62         n, err = br.tw.Body.Read(p)
63         if err != nil && err != io.EOF {
64                 br.tw.bodyReadError = err
65         }
66         return
67 }
68
69 // transferWriter inspects the fields of a user-supplied Request or Response,
70 // sanitizes them without changing the user object and provides methods for
71 // writing the respective header, body and trailer in wire format.
72 type transferWriter struct {
73         Method           string
74         Body             io.Reader
75         BodyCloser       io.Closer
76         ResponseToHEAD   bool
77         ContentLength    int64 // -1 means unknown, 0 means exactly none
78         Close            bool
79         TransferEncoding []string
80         Header           Header
81         Trailer          Header
82         IsResponse       bool
83         bodyReadError    error // any non-EOF error from reading Body
84
85         FlushHeaders bool            // flush headers to network before body
86         ByteReadCh   chan readResult // non-nil if probeRequestBody called
87 }
88
89 func newTransferWriter(r interface{}) (t *transferWriter, err error) {
90         t = &transferWriter{}
91
92         // Extract relevant fields
93         atLeastHTTP11 := false
94         switch rr := r.(type) {
95         case *Request:
96                 if rr.ContentLength != 0 && rr.Body == nil {
97                         return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength)
98                 }
99                 t.Method = valueOrDefault(rr.Method, "GET")
100                 t.Close = rr.Close
101                 t.TransferEncoding = rr.TransferEncoding
102                 t.Header = rr.Header
103                 t.Trailer = rr.Trailer
104                 t.Body = rr.Body
105                 t.BodyCloser = rr.Body
106                 t.ContentLength = rr.outgoingLength()
107                 if t.ContentLength < 0 && len(t.TransferEncoding) == 0 && t.shouldSendChunkedRequestBody() {
108                         t.TransferEncoding = []string{"chunked"}
109                 }
110                 // If there's a body, conservatively flush the headers
111                 // to any bufio.Writer we're writing to, just in case
112                 // the server needs the headers early, before we copy
113                 // the body and possibly block. We make an exception
114                 // for the common standard library in-memory types,
115                 // though, to avoid unnecessary TCP packets on the
116                 // wire. (Issue 22088.)
117                 if t.ContentLength != 0 && !isKnownInMemoryReader(t.Body) {
118                         t.FlushHeaders = true
119                 }
120
121                 atLeastHTTP11 = true // Transport requests are always 1.1 or 2.0
122         case *Response:
123                 t.IsResponse = true
124                 if rr.Request != nil {
125                         t.Method = rr.Request.Method
126                 }
127                 t.Body = rr.Body
128                 t.BodyCloser = rr.Body
129                 t.ContentLength = rr.ContentLength
130                 t.Close = rr.Close
131                 t.TransferEncoding = rr.TransferEncoding
132                 t.Header = rr.Header
133                 t.Trailer = rr.Trailer
134                 atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
135                 t.ResponseToHEAD = noResponseBodyExpected(t.Method)
136         }
137
138         // Sanitize Body,ContentLength,TransferEncoding
139         if t.ResponseToHEAD {
140                 t.Body = nil
141                 if chunked(t.TransferEncoding) {
142                         t.ContentLength = -1
143                 }
144         } else {
145                 if !atLeastHTTP11 || t.Body == nil {
146                         t.TransferEncoding = nil
147                 }
148                 if chunked(t.TransferEncoding) {
149                         t.ContentLength = -1
150                 } else if t.Body == nil { // no chunking, no body
151                         t.ContentLength = 0
152                 }
153         }
154
155         // Sanitize Trailer
156         if !chunked(t.TransferEncoding) {
157                 t.Trailer = nil
158         }
159
160         return t, nil
161 }
162
163 // shouldSendChunkedRequestBody reports whether we should try to send a
164 // chunked request body to the server. In particular, the case we really
165 // want to prevent is sending a GET or other typically-bodyless request to a
166 // server with a chunked body when the body has zero bytes, since GETs with
167 // bodies (while acceptable according to specs), even zero-byte chunked
168 // bodies, are approximately never seen in the wild and confuse most
169 // servers. See Issue 18257, as one example.
170 //
171 // The only reason we'd send such a request is if the user set the Body to a
172 // non-nil value (say, ioutil.NopCloser(bytes.NewReader(nil))) and didn't
173 // set ContentLength, or NewRequest set it to -1 (unknown), so then we assume
174 // there's bytes to send.
175 //
176 // This code tries to read a byte from the Request.Body in such cases to see
177 // whether the body actually has content (super rare) or is actually just
178 // a non-nil content-less ReadCloser (the more common case). In that more
179 // common case, we act as if their Body were nil instead, and don't send
180 // a body.
181 func (t *transferWriter) shouldSendChunkedRequestBody() bool {
182         // Note that t.ContentLength is the corrected content length
183         // from rr.outgoingLength, so 0 actually means zero, not unknown.
184         if t.ContentLength >= 0 || t.Body == nil { // redundant checks; caller did them
185                 return false
186         }
187         if requestMethodUsuallyLacksBody(t.Method) {
188                 // Only probe the Request.Body for GET/HEAD/DELETE/etc
189                 // requests, because it's only those types of requests
190                 // that confuse servers.
191                 t.probeRequestBody() // adjusts t.Body, t.ContentLength
192                 return t.Body != nil
193         }
194         // For all other request types (PUT, POST, PATCH, or anything
195         // made-up we've never heard of), assume it's normal and the server
196         // can deal with a chunked request body. Maybe we'll adjust this
197         // later.
198         return true
199 }
200
201 // probeRequestBody reads a byte from t.Body to see whether it's empty
202 // (returns io.EOF right away).
203 //
204 // But because we've had problems with this blocking users in the past
205 // (issue 17480) when the body is a pipe (perhaps waiting on the response
206 // headers before the pipe is fed data), we need to be careful and bound how
207 // long we wait for it. This delay will only affect users if all the following
208 // are true:
209 //   * the request body blocks
210 //   * the content length is not set (or set to -1)
211 //   * the method doesn't usually have a body (GET, HEAD, DELETE, ...)
212 //   * there is no transfer-encoding=chunked already set.
213 // In other words, this delay will not normally affect anybody, and there
214 // are workarounds if it does.
215 func (t *transferWriter) probeRequestBody() {
216         t.ByteReadCh = make(chan readResult, 1)
217         go func(body io.Reader) {
218                 var buf [1]byte
219                 var rres readResult
220                 rres.n, rres.err = body.Read(buf[:])
221                 if rres.n == 1 {
222                         rres.b = buf[0]
223                 }
224                 t.ByteReadCh <- rres
225         }(t.Body)
226         timer := time.NewTimer(200 * time.Millisecond)
227         select {
228         case rres := <-t.ByteReadCh:
229                 timer.Stop()
230                 if rres.n == 0 && rres.err == io.EOF {
231                         // It was empty.
232                         t.Body = nil
233                         t.ContentLength = 0
234                 } else if rres.n == 1 {
235                         if rres.err != nil {
236                                 t.Body = io.MultiReader(&byteReader{b: rres.b}, errorReader{rres.err})
237                         } else {
238                                 t.Body = io.MultiReader(&byteReader{b: rres.b}, t.Body)
239                         }
240                 } else if rres.err != nil {
241                         t.Body = errorReader{rres.err}
242                 }
243         case <-timer.C:
244                 // Too slow. Don't wait. Read it later, and keep
245                 // assuming that this is ContentLength == -1
246                 // (unknown), which means we'll send a
247                 // "Transfer-Encoding: chunked" header.
248                 t.Body = io.MultiReader(finishAsyncByteRead{t}, t.Body)
249                 // Request that Request.Write flush the headers to the
250                 // network before writing the body, since our body may not
251                 // become readable until it's seen the response headers.
252                 t.FlushHeaders = true
253         }
254 }
255
256 func noResponseBodyExpected(requestMethod string) bool {
257         return requestMethod == "HEAD"
258 }
259
260 func (t *transferWriter) shouldSendContentLength() bool {
261         if chunked(t.TransferEncoding) {
262                 return false
263         }
264         if t.ContentLength > 0 {
265                 return true
266         }
267         if t.ContentLength < 0 {
268                 return false
269         }
270         // Many servers expect a Content-Length for these methods
271         if t.Method == "POST" || t.Method == "PUT" {
272                 return true
273         }
274         if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
275                 if t.Method == "GET" || t.Method == "HEAD" {
276                         return false
277                 }
278                 return true
279         }
280
281         return false
282 }
283
284 func (t *transferWriter) writeHeader(w io.Writer, trace *httptrace.ClientTrace) error {
285         if t.Close && !hasToken(t.Header.get("Connection"), "close") {
286                 if _, err := io.WriteString(w, "Connection: close\r\n"); err != nil {
287                         return err
288                 }
289                 if trace != nil && trace.WroteHeaderField != nil {
290                         trace.WroteHeaderField("Connection", []string{"close"})
291                 }
292         }
293
294         // Write Content-Length and/or Transfer-Encoding whose values are a
295         // function of the sanitized field triple (Body, ContentLength,
296         // TransferEncoding)
297         if t.shouldSendContentLength() {
298                 if _, err := io.WriteString(w, "Content-Length: "); err != nil {
299                         return err
300                 }
301                 if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil {
302                         return err
303                 }
304                 if trace != nil && trace.WroteHeaderField != nil {
305                         trace.WroteHeaderField("Content-Length", []string{strconv.FormatInt(t.ContentLength, 10)})
306                 }
307         } else if chunked(t.TransferEncoding) {
308                 if _, err := io.WriteString(w, "Transfer-Encoding: chunked\r\n"); err != nil {
309                         return err
310                 }
311                 if trace != nil && trace.WroteHeaderField != nil {
312                         trace.WroteHeaderField("Transfer-Encoding", []string{"chunked"})
313                 }
314         }
315
316         // Write Trailer header
317         if t.Trailer != nil {
318                 keys := make([]string, 0, len(t.Trailer))
319                 for k := range t.Trailer {
320                         k = CanonicalHeaderKey(k)
321                         switch k {
322                         case "Transfer-Encoding", "Trailer", "Content-Length":
323                                 return &badStringError{"invalid Trailer key", k}
324                         }
325                         keys = append(keys, k)
326                 }
327                 if len(keys) > 0 {
328                         sort.Strings(keys)
329                         // TODO: could do better allocation-wise here, but trailers are rare,
330                         // so being lazy for now.
331                         if _, err := io.WriteString(w, "Trailer: "+strings.Join(keys, ",")+"\r\n"); err != nil {
332                                 return err
333                         }
334                         if trace != nil && trace.WroteHeaderField != nil {
335                                 trace.WroteHeaderField("Trailer", keys)
336                         }
337                 }
338         }
339
340         return nil
341 }
342
343 func (t *transferWriter) writeBody(w io.Writer) error {
344         var err error
345         var ncopy int64
346
347         // Write body
348         if t.Body != nil {
349                 var body = transferBodyReader{t}
350                 if chunked(t.TransferEncoding) {
351                         if bw, ok := w.(*bufio.Writer); ok && !t.IsResponse {
352                                 w = &internal.FlushAfterChunkWriter{Writer: bw}
353                         }
354                         cw := internal.NewChunkedWriter(w)
355                         _, err = io.Copy(cw, body)
356                         if err == nil {
357                                 err = cw.Close()
358                         }
359                 } else if t.ContentLength == -1 {
360                         ncopy, err = io.Copy(w, body)
361                 } else {
362                         ncopy, err = io.Copy(w, io.LimitReader(body, t.ContentLength))
363                         if err != nil {
364                                 return err
365                         }
366                         var nextra int64
367                         nextra, err = io.Copy(ioutil.Discard, body)
368                         ncopy += nextra
369                 }
370                 if err != nil {
371                         return err
372                 }
373         }
374         if t.BodyCloser != nil {
375                 if err := t.BodyCloser.Close(); err != nil {
376                         return err
377                 }
378         }
379
380         if !t.ResponseToHEAD && t.ContentLength != -1 && t.ContentLength != ncopy {
381                 return fmt.Errorf("http: ContentLength=%d with Body length %d",
382                         t.ContentLength, ncopy)
383         }
384
385         if chunked(t.TransferEncoding) {
386                 // Write Trailer header
387                 if t.Trailer != nil {
388                         if err := t.Trailer.Write(w); err != nil {
389                                 return err
390                         }
391                 }
392                 // Last chunk, empty trailer
393                 _, err = io.WriteString(w, "\r\n")
394         }
395         return err
396 }
397
398 type transferReader struct {
399         // Input
400         Header        Header
401         StatusCode    int
402         RequestMethod string
403         ProtoMajor    int
404         ProtoMinor    int
405         // Output
406         Body             io.ReadCloser
407         ContentLength    int64
408         TransferEncoding []string
409         Close            bool
410         Trailer          Header
411 }
412
413 func (t *transferReader) protoAtLeast(m, n int) bool {
414         return t.ProtoMajor > m || (t.ProtoMajor == m && t.ProtoMinor >= n)
415 }
416
417 // bodyAllowedForStatus reports whether a given response status code
418 // permits a body. See RFC 7230, section 3.3.
419 func bodyAllowedForStatus(status int) bool {
420         switch {
421         case status >= 100 && status <= 199:
422                 return false
423         case status == 204:
424                 return false
425         case status == 304:
426                 return false
427         }
428         return true
429 }
430
431 var (
432         suppressedHeaders304    = []string{"Content-Type", "Content-Length", "Transfer-Encoding"}
433         suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"}
434 )
435
436 func suppressedHeaders(status int) []string {
437         switch {
438         case status == 304:
439                 // RFC 7232 section 4.1
440                 return suppressedHeaders304
441         case !bodyAllowedForStatus(status):
442                 return suppressedHeadersNoBody
443         }
444         return nil
445 }
446
447 // msg is *Request or *Response.
448 func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
449         t := &transferReader{RequestMethod: "GET"}
450
451         // Unify input
452         isResponse := false
453         switch rr := msg.(type) {
454         case *Response:
455                 t.Header = rr.Header
456                 t.StatusCode = rr.StatusCode
457                 t.ProtoMajor = rr.ProtoMajor
458                 t.ProtoMinor = rr.ProtoMinor
459                 t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true)
460                 isResponse = true
461                 if rr.Request != nil {
462                         t.RequestMethod = rr.Request.Method
463                 }
464         case *Request:
465                 t.Header = rr.Header
466                 t.RequestMethod = rr.Method
467                 t.ProtoMajor = rr.ProtoMajor
468                 t.ProtoMinor = rr.ProtoMinor
469                 // Transfer semantics for Requests are exactly like those for
470                 // Responses with status code 200, responding to a GET method
471                 t.StatusCode = 200
472                 t.Close = rr.Close
473         default:
474                 panic("unexpected type")
475         }
476
477         // Default to HTTP/1.1
478         if t.ProtoMajor == 0 && t.ProtoMinor == 0 {
479                 t.ProtoMajor, t.ProtoMinor = 1, 1
480         }
481
482         // Transfer encoding, content length
483         err = t.fixTransferEncoding()
484         if err != nil {
485                 return err
486         }
487
488         realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding)
489         if err != nil {
490                 return err
491         }
492         if isResponse && t.RequestMethod == "HEAD" {
493                 if n, err := parseContentLength(t.Header.get("Content-Length")); err != nil {
494                         return err
495                 } else {
496                         t.ContentLength = n
497                 }
498         } else {
499                 t.ContentLength = realLength
500         }
501
502         // Trailer
503         t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding)
504         if err != nil {
505                 return err
506         }
507
508         // If there is no Content-Length or chunked Transfer-Encoding on a *Response
509         // and the status is not 1xx, 204 or 304, then the body is unbounded.
510         // See RFC 7230, section 3.3.
511         switch msg.(type) {
512         case *Response:
513                 if realLength == -1 &&
514                         !chunked(t.TransferEncoding) &&
515                         bodyAllowedForStatus(t.StatusCode) {
516                         // Unbounded body.
517                         t.Close = true
518                 }
519         }
520
521         // Prepare body reader. ContentLength < 0 means chunked encoding
522         // or close connection when finished, since multipart is not supported yet
523         switch {
524         case chunked(t.TransferEncoding):
525                 if noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode) {
526                         t.Body = NoBody
527                 } else {
528                         t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}
529                 }
530         case realLength == 0:
531                 t.Body = NoBody
532         case realLength > 0:
533                 t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close}
534         default:
535                 // realLength < 0, i.e. "Content-Length" not mentioned in header
536                 if t.Close {
537                         // Close semantics (i.e. HTTP/1.0)
538                         t.Body = &body{src: r, closing: t.Close}
539                 } else {
540                         // Persistent connection (i.e. HTTP/1.1)
541                         t.Body = NoBody
542                 }
543         }
544
545         // Unify output
546         switch rr := msg.(type) {
547         case *Request:
548                 rr.Body = t.Body
549                 rr.ContentLength = t.ContentLength
550                 rr.TransferEncoding = t.TransferEncoding
551                 rr.Close = t.Close
552                 rr.Trailer = t.Trailer
553         case *Response:
554                 rr.Body = t.Body
555                 rr.ContentLength = t.ContentLength
556                 rr.TransferEncoding = t.TransferEncoding
557                 rr.Close = t.Close
558                 rr.Trailer = t.Trailer
559         }
560
561         return nil
562 }
563
564 // Checks whether chunked is part of the encodings stack
565 func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
566
567 // Checks whether the encoding is explicitly "identity".
568 func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
569
570 // fixTransferEncoding sanitizes t.TransferEncoding, if needed.
571 func (t *transferReader) fixTransferEncoding() error {
572         raw, present := t.Header["Transfer-Encoding"]
573         if !present {
574                 return nil
575         }
576         delete(t.Header, "Transfer-Encoding")
577
578         // Issue 12785; ignore Transfer-Encoding on HTTP/1.0 requests.
579         if !t.protoAtLeast(1, 1) {
580                 return nil
581         }
582
583         encodings := strings.Split(raw[0], ",")
584         te := make([]string, 0, len(encodings))
585         // TODO: Even though we only support "identity" and "chunked"
586         // encodings, the loop below is designed with foresight. One
587         // invariant that must be maintained is that, if present,
588         // chunked encoding must always come first.
589         for _, encoding := range encodings {
590                 encoding = strings.ToLower(strings.TrimSpace(encoding))
591                 // "identity" encoding is not recorded
592                 if encoding == "identity" {
593                         break
594                 }
595                 if encoding != "chunked" {
596                         return &badStringError{"unsupported transfer encoding", encoding}
597                 }
598                 te = te[0 : len(te)+1]
599                 te[len(te)-1] = encoding
600         }
601         if len(te) > 1 {
602                 return &badStringError{"too many transfer encodings", strings.Join(te, ",")}
603         }
604         if len(te) > 0 {
605                 // RFC 7230 3.3.2 says "A sender MUST NOT send a
606                 // Content-Length header field in any message that
607                 // contains a Transfer-Encoding header field."
608                 //
609                 // but also:
610                 // "If a message is received with both a
611                 // Transfer-Encoding and a Content-Length header
612                 // field, the Transfer-Encoding overrides the
613                 // Content-Length. Such a message might indicate an
614                 // attempt to perform request smuggling (Section 9.5)
615                 // or response splitting (Section 9.4) and ought to be
616                 // handled as an error. A sender MUST remove the
617                 // received Content-Length field prior to forwarding
618                 // such a message downstream."
619                 //
620                 // Reportedly, these appear in the wild.
621                 delete(t.Header, "Content-Length")
622                 t.TransferEncoding = te
623                 return nil
624         }
625
626         return nil
627 }
628
629 // Determine the expected body length, using RFC 7230 Section 3.3. This
630 // function is not a method, because ultimately it should be shared by
631 // ReadResponse and ReadRequest.
632 func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) {
633         isRequest := !isResponse
634         contentLens := header["Content-Length"]
635
636         // Hardening against HTTP request smuggling
637         if len(contentLens) > 1 {
638                 // Per RFC 7230 Section 3.3.2, prevent multiple
639                 // Content-Length headers if they differ in value.
640                 // If there are dups of the value, remove the dups.
641                 // See Issue 16490.
642                 first := strings.TrimSpace(contentLens[0])
643                 for _, ct := range contentLens[1:] {
644                         if first != strings.TrimSpace(ct) {
645                                 return 0, fmt.Errorf("http: message cannot contain multiple Content-Length headers; got %q", contentLens)
646                         }
647                 }
648
649                 // deduplicate Content-Length
650                 header.Del("Content-Length")
651                 header.Add("Content-Length", first)
652
653                 contentLens = header["Content-Length"]
654         }
655
656         // Logic based on response type or status
657         if noResponseBodyExpected(requestMethod) {
658                 // For HTTP requests, as part of hardening against request
659                 // smuggling (RFC 7230), don't allow a Content-Length header for
660                 // methods which don't permit bodies. As an exception, allow
661                 // exactly one Content-Length header if its value is "0".
662                 if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == "0") {
663                         return 0, fmt.Errorf("http: method cannot contain a Content-Length; got %q", contentLens)
664                 }
665                 return 0, nil
666         }
667         if status/100 == 1 {
668                 return 0, nil
669         }
670         switch status {
671         case 204, 304:
672                 return 0, nil
673         }
674
675         // Logic based on Transfer-Encoding
676         if chunked(te) {
677                 return -1, nil
678         }
679
680         // Logic based on Content-Length
681         var cl string
682         if len(contentLens) == 1 {
683                 cl = strings.TrimSpace(contentLens[0])
684         }
685         if cl != "" {
686                 n, err := parseContentLength(cl)
687                 if err != nil {
688                         return -1, err
689                 }
690                 return n, nil
691         }
692         header.Del("Content-Length")
693
694         if isRequest {
695                 // RFC 7230 neither explicitly permits nor forbids an
696                 // entity-body on a GET request so we permit one if
697                 // declared, but we default to 0 here (not -1 below)
698                 // if there's no mention of a body.
699                 // Likewise, all other request methods are assumed to have
700                 // no body if neither Transfer-Encoding chunked nor a
701                 // Content-Length are set.
702                 return 0, nil
703         }
704
705         // Body-EOF logic based on other methods (like closing, or chunked coding)
706         return -1, nil
707 }
708
709 // Determine whether to hang up after sending a request and body, or
710 // receiving a response and body
711 // 'header' is the request headers
712 func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool {
713         if major < 1 {
714                 return true
715         }
716
717         conv := header["Connection"]
718         hasClose := httpguts.HeaderValuesContainsToken(conv, "close")
719         if major == 1 && minor == 0 {
720                 return hasClose || !httpguts.HeaderValuesContainsToken(conv, "keep-alive")
721         }
722
723         if hasClose && removeCloseHeader {
724                 header.Del("Connection")
725         }
726
727         return hasClose
728 }
729
730 // Parse the trailer header
731 func fixTrailer(header Header, te []string) (Header, error) {
732         vv, ok := header["Trailer"]
733         if !ok {
734                 return nil, nil
735         }
736         header.Del("Trailer")
737
738         trailer := make(Header)
739         var err error
740         for _, v := range vv {
741                 foreachHeaderElement(v, func(key string) {
742                         key = CanonicalHeaderKey(key)
743                         switch key {
744                         case "Transfer-Encoding", "Trailer", "Content-Length":
745                                 if err == nil {
746                                         err = &badStringError{"bad trailer key", key}
747                                         return
748                                 }
749                         }
750                         trailer[key] = nil
751                 })
752         }
753         if err != nil {
754                 return nil, err
755         }
756         if len(trailer) == 0 {
757                 return nil, nil
758         }
759         if !chunked(te) {
760                 // Trailer and no chunking
761                 return nil, ErrUnexpectedTrailer
762         }
763         return trailer, nil
764 }
765
766 // body turns a Reader into a ReadCloser.
767 // Close ensures that the body has been fully read
768 // and then reads the trailer if necessary.
769 type body struct {
770         src          io.Reader
771         hdr          interface{}   // non-nil (Response or Request) value means read trailer
772         r            *bufio.Reader // underlying wire-format reader for the trailer
773         closing      bool          // is the connection to be closed after reading body?
774         doEarlyClose bool          // whether Close should stop early
775
776         mu         sync.Mutex // guards following, and calls to Read and Close
777         sawEOF     bool
778         closed     bool
779         earlyClose bool   // Close called and we didn't read to the end of src
780         onHitEOF   func() // if non-nil, func to call when EOF is Read
781 }
782
783 // ErrBodyReadAfterClose is returned when reading a Request or Response
784 // Body after the body has been closed. This typically happens when the body is
785 // read after an HTTP Handler calls WriteHeader or Write on its
786 // ResponseWriter.
787 var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")
788
789 func (b *body) Read(p []byte) (n int, err error) {
790         b.mu.Lock()
791         defer b.mu.Unlock()
792         if b.closed {
793                 return 0, ErrBodyReadAfterClose
794         }
795         return b.readLocked(p)
796 }
797
798 // Must hold b.mu.
799 func (b *body) readLocked(p []byte) (n int, err error) {
800         if b.sawEOF {
801                 return 0, io.EOF
802         }
803         n, err = b.src.Read(p)
804
805         if err == io.EOF {
806                 b.sawEOF = true
807                 // Chunked case. Read the trailer.
808                 if b.hdr != nil {
809                         if e := b.readTrailer(); e != nil {
810                                 err = e
811                                 // Something went wrong in the trailer, we must not allow any
812                                 // further reads of any kind to succeed from body, nor any
813                                 // subsequent requests on the server connection. See
814                                 // golang.org/issue/12027
815                                 b.sawEOF = false
816                                 b.closed = true
817                         }
818                         b.hdr = nil
819                 } else {
820                         // If the server declared the Content-Length, our body is a LimitedReader
821                         // and we need to check whether this EOF arrived early.
822                         if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 {
823                                 err = io.ErrUnexpectedEOF
824                         }
825                 }
826         }
827
828         // If we can return an EOF here along with the read data, do
829         // so. This is optional per the io.Reader contract, but doing
830         // so helps the HTTP transport code recycle its connection
831         // earlier (since it will see this EOF itself), even if the
832         // client doesn't do future reads or Close.
833         if err == nil && n > 0 {
834                 if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
835                         err = io.EOF
836                         b.sawEOF = true
837                 }
838         }
839
840         if b.sawEOF && b.onHitEOF != nil {
841                 b.onHitEOF()
842         }
843
844         return n, err
845 }
846
847 var (
848         singleCRLF = []byte("\r\n")
849         doubleCRLF = []byte("\r\n\r\n")
850 )
851
852 func seeUpcomingDoubleCRLF(r *bufio.Reader) bool {
853         for peekSize := 4; ; peekSize++ {
854                 // This loop stops when Peek returns an error,
855                 // which it does when r's buffer has been filled.
856                 buf, err := r.Peek(peekSize)
857                 if bytes.HasSuffix(buf, doubleCRLF) {
858                         return true
859                 }
860                 if err != nil {
861                         break
862                 }
863         }
864         return false
865 }
866
867 var errTrailerEOF = errors.New("http: unexpected EOF reading trailer")
868
869 func (b *body) readTrailer() error {
870         // The common case, since nobody uses trailers.
871         buf, err := b.r.Peek(2)
872         if bytes.Equal(buf, singleCRLF) {
873                 b.r.Discard(2)
874                 return nil
875         }
876         if len(buf) < 2 {
877                 return errTrailerEOF
878         }
879         if err != nil {
880                 return err
881         }
882
883         // Make sure there's a header terminator coming up, to prevent
884         // a DoS with an unbounded size Trailer. It's not easy to
885         // slip in a LimitReader here, as textproto.NewReader requires
886         // a concrete *bufio.Reader. Also, we can't get all the way
887         // back up to our conn's LimitedReader that *might* be backing
888         // this bufio.Reader. Instead, a hack: we iteratively Peek up
889         // to the bufio.Reader's max size, looking for a double CRLF.
890         // This limits the trailer to the underlying buffer size, typically 4kB.
891         if !seeUpcomingDoubleCRLF(b.r) {
892                 return errors.New("http: suspiciously long trailer after chunked body")
893         }
894
895         hdr, err := textproto.NewReader(b.r).ReadMIMEHeader()
896         if err != nil {
897                 if err == io.EOF {
898                         return errTrailerEOF
899                 }
900                 return err
901         }
902         switch rr := b.hdr.(type) {
903         case *Request:
904                 mergeSetHeader(&rr.Trailer, Header(hdr))
905         case *Response:
906                 mergeSetHeader(&rr.Trailer, Header(hdr))
907         }
908         return nil
909 }
910
911 func mergeSetHeader(dst *Header, src Header) {
912         if *dst == nil {
913                 *dst = src
914                 return
915         }
916         for k, vv := range src {
917                 (*dst)[k] = vv
918         }
919 }
920
921 // unreadDataSizeLocked returns the number of bytes of unread input.
922 // It returns -1 if unknown.
923 // b.mu must be held.
924 func (b *body) unreadDataSizeLocked() int64 {
925         if lr, ok := b.src.(*io.LimitedReader); ok {
926                 return lr.N
927         }
928         return -1
929 }
930
931 func (b *body) Close() error {
932         b.mu.Lock()
933         defer b.mu.Unlock()
934         if b.closed {
935                 return nil
936         }
937         var err error
938         switch {
939         case b.sawEOF:
940                 // Already saw EOF, so no need going to look for it.
941         case b.hdr == nil && b.closing:
942                 // no trailer and closing the connection next.
943                 // no point in reading to EOF.
944         case b.doEarlyClose:
945                 // Read up to maxPostHandlerReadBytes bytes of the body, looking for
946                 // for EOF (and trailers), so we can re-use this connection.
947                 if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > maxPostHandlerReadBytes {
948                         // There was a declared Content-Length, and we have more bytes remaining
949                         // than our maxPostHandlerReadBytes tolerance. So, give up.
950                         b.earlyClose = true
951                 } else {
952                         var n int64
953                         // Consume the body, or, which will also lead to us reading
954                         // the trailer headers after the body, if present.
955                         n, err = io.CopyN(ioutil.Discard, bodyLocked{b}, maxPostHandlerReadBytes)
956                         if err == io.EOF {
957                                 err = nil
958                         }
959                         if n == maxPostHandlerReadBytes {
960                                 b.earlyClose = true
961                         }
962                 }
963         default:
964                 // Fully consume the body, which will also lead to us reading
965                 // the trailer headers after the body, if present.
966                 _, err = io.Copy(ioutil.Discard, bodyLocked{b})
967         }
968         b.closed = true
969         return err
970 }
971
972 func (b *body) didEarlyClose() bool {
973         b.mu.Lock()
974         defer b.mu.Unlock()
975         return b.earlyClose
976 }
977
978 // bodyRemains reports whether future Read calls might
979 // yield data.
980 func (b *body) bodyRemains() bool {
981         b.mu.Lock()
982         defer b.mu.Unlock()
983         return !b.sawEOF
984 }
985
986 func (b *body) registerOnHitEOF(fn func()) {
987         b.mu.Lock()
988         defer b.mu.Unlock()
989         b.onHitEOF = fn
990 }
991
992 // bodyLocked is a io.Reader reading from a *body when its mutex is
993 // already held.
994 type bodyLocked struct {
995         b *body
996 }
997
998 func (bl bodyLocked) Read(p []byte) (n int, err error) {
999         if bl.b.closed {
1000                 return 0, ErrBodyReadAfterClose
1001         }
1002         return bl.b.readLocked(p)
1003 }
1004
1005 // parseContentLength trims whitespace from s and returns -1 if no value
1006 // is set, or the value if it's >= 0.
1007 func parseContentLength(cl string) (int64, error) {
1008         cl = strings.TrimSpace(cl)
1009         if cl == "" {
1010                 return -1, nil
1011         }
1012         n, err := strconv.ParseInt(cl, 10, 64)
1013         if err != nil || n < 0 {
1014                 return 0, &badStringError{"bad Content-Length", cl}
1015         }
1016         return n, nil
1017
1018 }
1019
1020 // finishAsyncByteRead finishes reading the 1-byte sniff
1021 // from the ContentLength==0, Body!=nil case.
1022 type finishAsyncByteRead struct {
1023         tw *transferWriter
1024 }
1025
1026 func (fr finishAsyncByteRead) Read(p []byte) (n int, err error) {
1027         if len(p) == 0 {
1028                 return
1029         }
1030         rres := <-fr.tw.ByteReadCh
1031         n, err = rres.n, rres.err
1032         if n == 1 {
1033                 p[0] = rres.b
1034         }
1035         return
1036 }
1037
1038 var nopCloserType = reflect.TypeOf(ioutil.NopCloser(nil))
1039
1040 // isKnownInMemoryReader reports whether r is a type known to not
1041 // block on Read. Its caller uses this as an optional optimization to
1042 // send fewer TCP packets.
1043 func isKnownInMemoryReader(r io.Reader) bool {
1044         switch r.(type) {
1045         case *bytes.Reader, *bytes.Buffer, *strings.Reader:
1046                 return true
1047         }
1048         if reflect.TypeOf(r) == nopCloserType {
1049                 return isKnownInMemoryReader(reflect.ValueOf(r).Field(0).Interface().(io.Reader))
1050         }
1051         return false
1052 }