Determine the expected body length, using RFC 7230 Section 3.3. This function is not a method, because ultimately it should be shared by ReadResponse and ReadRequest.
(isResponse bool, status int, requestMethod string, header http.Header, chunked bool)
| 594 | // function is not a method, because ultimately it should be shared by |
| 595 | // ReadResponse and ReadRequest. |
| 596 | func fixLength(isResponse bool, status int, requestMethod string, header http.Header, chunked bool) (n int64, err error) { |
| 597 | isRequest := !isResponse |
| 598 | contentLens := header["Content-Length"] |
| 599 | |
| 600 | // Hardening against HTTP request smuggling |
| 601 | if len(contentLens) > 1 { |
| 602 | // Per RFC 7230 Section 3.3.2, prevent multiple |
| 603 | // Content-Length headers if they differ in value. |
| 604 | // If there are dups of the value, remove the dups. |
| 605 | // See Issue 16490. |
| 606 | first := textproto.TrimString(contentLens[0]) |
| 607 | for _, ct := range contentLens[1:] { |
| 608 | if first != textproto.TrimString(ct) { |
| 609 | return 0, fmt.Errorf("http: message cannot contain multiple Content-Length headers; got %q", contentLens) |
| 610 | } |
| 611 | } |
| 612 | |
| 613 | // deduplicate Content-Length |
| 614 | header.Del("Content-Length") |
| 615 | header.Add("Content-Length", first) |
| 616 | |
| 617 | contentLens = header["Content-Length"] |
| 618 | } |
| 619 | |
| 620 | // Reject requests with invalid Content-Length headers. |
| 621 | if len(contentLens) > 0 { |
| 622 | n, err = parseContentLength(contentLens) |
| 623 | if err != nil { |
| 624 | return -1, err |
| 625 | } |
| 626 | } |
| 627 | |
| 628 | // Logic based on response type or status |
| 629 | if isResponse && noResponseBodyExpected(requestMethod) { |
| 630 | return 0, nil |
| 631 | } |
| 632 | if status/100 == 1 { |
| 633 | return 0, nil |
| 634 | } |
| 635 | switch status { |
| 636 | case 204, 304: |
| 637 | return 0, nil |
| 638 | } |
| 639 | |
| 640 | // According to RFC 9112, "If a message is received with both a |
| 641 | // Transfer-Encoding and a Content-Length header field, the Transfer-Encoding |
| 642 | // overrides the Content-Length. Such a message might indicate an attempt to |
| 643 | // perform request smuggling (Section 11.2) or response splitting (Section 11.1) |
| 644 | // and ought to be handled as an error. An intermediary that chooses to forward |
| 645 | // the message MUST first remove the received Content-Length field and process |
| 646 | // the Transfer-Encoding (as described below) prior to forwarding the message downstream." |
| 647 | // |
| 648 | // Chunked-encoding requests with either valid Content-Length |
| 649 | // headers or no Content-Length headers are accepted after removing |
| 650 | // the Content-Length field from header. |
| 651 | // |
| 652 | // Logic based on Transfer-Encoding |
| 653 | if chunked { |
no test coverage detected
searching dependent graphs…