transfer.mx raw

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