Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: http2 negative content length #14003

Closed
rafaeljusto opened this issue Jan 18, 2016 · 3 comments

Comments

Projects
None yet
3 participants
@rafaeljusto
Copy link

commented Jan 18, 2016

Hi,

I was testing Go1.6-beta2 and found a strange behavior with HTTP2. I developed a simple server that only prints the request content-length. When tested with Go1.5 it works fine (content-length greater or equal to zero), but when I submit some content in Go1.6 using HTTP2 (TLS) the server prints -1.

Server:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
        fmt.Printf("LENGTH: %d\n", r.ContentLength)
    })

    log.Fatal(http.ListenAndServeTLS(":8080", "cert.pem", "key.pem", nil))
}

Client:

package main

import (
    "crypto/tls"
    "fmt"
    "net/http"
    "strings"
)

func main() {
    client := http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
    }

    resp, err := client.Post("https://127.0.0.1:8080/bar", "text/plain", strings.NewReader("TEST!"))
    if err != nil {
        fmt.Println(err)
        return
    }
    defer resp.Body.Close()
}

@rafaeljusto rafaeljusto changed the title http2 negative content length net/http: http2 negative content length Jan 18, 2016

@bradfitz

This comment has been minimized.

Copy link
Member

commented Jan 18, 2016

Confirmed.

func TestH12_RequestContentLength(t *testing.T) {
        h12Compare{
                Handler: func(w ResponseWriter, r *Request) {
                        w.Header().Set("Got-Length", fmt.Sprint(r.ContentLength))
                        fmt.Fprintf(w, "Req.ContentLength=%v", r.ContentLength)
                },
                ReqFunc: func(c *Client, url string) (*Response, error) {
                        return c.Post(url, "text/plain", strings.NewReader("FOUR"))
                },
                CheckResponse: func(proto string, res *Response) {
                        if got := res.Header.Get("Got-Length"); got != "4" {
                                t.Errorf("Proto %q got length %q; want %q", proto, got, "4")
                        }
                },
        }.run(t)
}
=== RUN   TestH12_RequestContentLength
--- FAIL: TestH12_RequestContentLength (0.02s)
    clientserver_test.go:175: Response headers to handler differed:
        http/1 (http://127.0.0.1:57384):
            &http.Response{Status:"200 OK", StatusCode:200, Proto:"", ProtoMajor:0, ProtoMinor:0, Header:http.Header{"Got-Length":[]string{"4"}, "Date":[]string{"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}, "Content-Length":[]string{"19"}, "Content-Type":[]string{"text/plain; charset=utf-8"}}, Body:io.ReadCloser(nil), ContentLength:19, TransferEncoding:[]string(nil), Close:false, Trailer:http.Header(nil), Request:(*http.Request)(nil), TLS:(*tls.ConnectionState)(nil)}
        http/2 (https://127.0.0.1:57385):
            &http.Response{Status:"200 OK", StatusCode:200, Proto:"", ProtoMajor:0, ProtoMinor:0, Header:http.Header{"Content-Type":[]string{"text/plain; charset=utf-8"}, "Content-Length":[]string{"20"}, "Date":[]string{"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}, "Got-Length":[]string{"-1"}}, Body:io.ReadCloser(nil), ContentLength:20, TransferEncoding:[]string(nil), Close:false, Trailer:http.Header(nil), Request:(*http.Request)(nil), TLS:(*tls.ConnectionState)(nil)}
    clientserver_test.go:178: Response bodies to handler differed.
        http1: body "Req.ContentLength=4"; err <nil>
        http2: body "Req.ContentLength=-1"; err <nil>
    clientserver_test.go:435: Proto "HTTP/2.0" got length "-1"; want "4"
FAIL
exit status 1
FAIL    net/http    0.080s

@bradfitz bradfitz self-assigned this Jan 18, 2016

@bradfitz bradfitz added this to the Go1.6Maybe milestone Jan 18, 2016

@gopherbot

This comment has been minimized.

Copy link

commented Jan 18, 2016

CL https://golang.org/cl/18730 mentions this issue.

@gopherbot

This comment has been minimized.

Copy link

commented Jan 18, 2016

CL https://golang.org/cl/18709 mentions this issue.

gopherbot pushed a commit to golang/net that referenced this issue Jan 18, 2016

http2: make Transport send a Content-Length
Same policy and logic (and comments) as the net/http.Transport.

Updates golang/go#14003

Change-Id: I5744140fed16c00b0dc9a4bc74631b7df7d8241c
Reviewed-on: https://go-review.googlesource.com/18709
Reviewed-by: Andrew Gerrand <adg@golang.org>

@gopherbot gopherbot closed this in 5b588e6 Jan 18, 2016

@golang golang locked and limited conversation to collaborators Jan 17, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.