• Brad Fitzpatrick's avatar
    net/http: restore Transport's Request.Body byte sniff in limited cases · 6e36811c
    Brad Fitzpatrick authored
    In Go 1.8, we'd removed the Transport's Request.Body
    one-byte-Read-sniffing to disambiguate between non-nil Request.Body
    with a ContentLength of 0 or -1. Previously, we tried to see whether a
    ContentLength of 0 meant actually zero, or just an unset by reading a
    single byte of the Request.Body and then stitching any read byte back
    together with the original Request.Body.
    
    That historically has caused many problems due to either data races,
    blocking forever (#17480), or losing bytes (#17071). Thus, we removed
    it in both HTTP/1 and HTTP/2 in Go 1.8. Unfortunately, during the Go
    1.8 beta, we've found that a few people have gotten bitten by the
    behavior change on requests with methods typically not containing
    request bodies (e.g. GET, HEAD, DELETE). The most popular example is
    the aws-go SDK, which always set http.Request.Body to a non-nil value,
    even on such request methods. That was causing Go 1.8 to send such
    requests with Transfer-Encoding chunked bodies, with zero bytes,
    confusing popular servers (including but limited to AWS).
    
    This CL partially reverts the no-byte-sniffing behavior and restores
    it only for GET/HEAD/DELETE/etc requests, and only when there's no
    Transfer-Encoding set, and the Content-Length is 0 or -1.
    
    Updates #18257 (aws-go) bug
    And also private bug reports about non-AWS issues.
    
    Updates #18407 also, but haven't yet audited things enough to declare
    it fixed.
    
    Change-Id: Ie5284d3e067c181839b31faf637eee56e5738a6a
    Reviewed-on: https://go-review.googlesource.com/34668
    Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
    6e36811c
requestwrite_test.go 21.2 KB