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