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: unable to post body to an HTTP/2 server. #17066

Closed
definitelycarter opened this issue Sep 11, 2016 · 7 comments
Closed

net/http: unable to post body to an HTTP/2 server. #17066

definitelycarter opened this issue Sep 11, 2016 · 7 comments
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@definitelycarter
Copy link

definitelycarter commented Sep 11, 2016

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.7.1 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOBIN="/Users/adamcarter/Projects/Go/bin"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/adamcarter/Projects/Go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/s2/ytl9qynd5vddgn2zq5fdhrwh0000gn/T/go-build763705077=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"

What did you do?

Run the following code locally.

What did you expect to see?

A response without an error

What did you see instead?

I get the following error

Post https://api.pipedrive.com/v1/authorizations: stream error: stream ID 1; REFUSED_STREAM

Oddly when I pass a nil body into the request, I get a response from the server stating that my email and password is required:

        HTTP/2.0 400 Bad Request
        Access-Control-Allow-Origin: *
        Content-Type: application/json
        Date: Sun, 11 Sep 2016 19:47:52 GMT
        Server: nginx
        Set-Cookie: pipe-session=%2FZgblzwot3xVcYbzSDhII%2BTrQZzIzyxMMJdlXjk%2Bx1zbSf%2FZdL2V7NyDA%2BIJ9bsAYAmDEEOx1Qv%2BRU1tECHImcc4JRT%2FktP%2BIj9fvhsAX8iIDQfVaiS75ScCRqClARrD0wNw%2Fg%3D%3D; path=/; domain=.pipedrive.com; secure; httponly
        Vary: Accept-Encoding
        X-Frame-Options: SAMEORIGIN
        X-Ratelimit-Limit: 100
        X-Ratelimit-Remaining: 99
        X-Ratelimit-Reset: 10
        X-Xss-Protection: 1; mode=block

        {"success":false,"error":"Email or password not given.","error_info":"Please check developers.pipedrive.com for more information about Pipedrive API.","data":null,"additional_data":null}

Their server is nginx 1.9.15 and there are some places that indicate there's an issue with this particular version of nginx; However, I'd like to confirm with the folks here.

/cc @pipedrive

@bradfitz
Copy link
Contributor

Run your program with GODEBUG=http2debug=2 using a fake password and post the results here?

@bradfitz bradfitz changed the title Unable to post body to an HTTP/2 server. net/http: unable to post body to an HTTP/2 server. Sep 11, 2016
@bradfitz bradfitz added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Sep 11, 2016
@bradfitz bradfitz self-assigned this Sep 11, 2016
@definitelycarter
Copy link
Author

Here's the result:

2016/09/11 16:03:26 http2: Transport failed to get client conn for api.pipedrive.com:443: http2: no cached connection was available
2016/09/11 16:03:26 http2: Transport creating client conn 0xc4200f1380 to 198.61.241.200:443
2016/09/11 16:03:26 http2: Framer 0xc42042e300: wrote SETTINGS len=18, settings: ENABLE_PUSH=0, INITIAL_WINDOW_SIZE=4194304, MAX_HEADER_LIST_SIZE=10485760
2016/09/11 16:03:26 http2: Framer 0xc42042e300: wrote WINDOW_UPDATE len=4 (conn) incr=1073741824
2016/09/11 16:03:26 http2: Transport encoding header ":authority" = "api.pipedrive.com"
2016/09/11 16:03:26 http2: Transport encoding header ":method" = "POST"
2016/09/11 16:03:26 http2: Transport encoding header ":path" = "/v1/authorizations"
2016/09/11 16:03:26 http2: Transport encoding header ":scheme" = "https"
2016/09/11 16:03:26 http2: Transport encoding header "content-type" = "application/json"
2016/09/11 16:03:26 http2: Transport encoding header "content-length" = "32"
2016/09/11 16:03:26 http2: Transport encoding header "accept-encoding" = "gzip"
2016/09/11 16:03:26 http2: Transport encoding header "user-agent" = "Go-http-client/2.0"
2016/09/11 16:03:26 http2: Framer 0xc42042e300: read SETTINGS len=18, settings: MAX_CONCURRENT_STREAMS=128, INITIAL_WINDOW_SIZE=0, MAX_FRAME_SIZE=16777215
2016/09/11 16:03:26 http2: Framer 0xc42042e300: wrote HEADERS flags=END_HEADERS stream=1 len=68
2016/09/11 16:03:26 http2: Transport received SETTINGS len=18, settings: MAX_CONCURRENT_STREAMS=128, INITIAL_WINDOW_SIZE=0, MAX_FRAME_SIZE=16777215
2016/09/11 16:03:26 http2: Framer 0xc42042e300: wrote SETTINGS flags=ACK len=0
2016/09/11 16:03:26 http2: Framer 0xc42042e300: read WINDOW_UPDATE len=4 (conn) incr=2147418112
2016/09/11 16:03:26 http2: Transport received WINDOW_UPDATE len=4 (conn) incr=2147418112
2016/09/11 16:03:26 http2: Framer 0xc42042e300: read SETTINGS flags=ACK len=0
2016/09/11 16:03:26 http2: Transport received SETTINGS flags=ACK len=0
2016/09/11 16:03:26 http2: Framer 0xc42042e300: read RST_STREAM stream=1 len=4 ErrCode=REFUSED_STREAM
2016/09/11 16:03:26 http2: Transport received RST_STREAM stream=1 len=4 ErrCode=REFUSED_STREAM
2016/09/11 16:03:26 RoundTrip failure: stream error: stream ID 1; REFUSED_STREAM

@bradfitz
Copy link
Contributor

Yeah, this was nginx being overly aggressive in its interpretation of the spec.

The link you found has the history: curl/curl#804
and in particular, https://trac.nginx.org/nginx/ticket/959 (where it says it's fixed in nginx 1.11.0)

I think we'll do nothing here, like curl. I'd reluctant to block waiting for their settings. Maybe we could block up to 100ms or something? I don't know.

I guess it depends how long this nginx bug will be in the wild.

If we wanted to go all the way, we could retry on REFUSED_STREAM if we hadn't written DATA yet, or buffer, but that seems like a lot of work if it's a temporary fix only.

@definitelycarter
Copy link
Author

Thank you for the info. I also sent a message out to @pipedrive to (hopefully) upgrade nginx.

@odeke-em
Copy link
Member

Ah @bradfitz you beat me to the punch, I was just reproducing this firstly to ensure that our plain net/http 2 servers can receive the request then was gonna reproduce with nginx. Code at https://github.com/odeke-em/bugs/tree/master/golang/17066

@definitelycarter
Copy link
Author

Just to confirm, it looks like it is't possible to make requests using http 1 wil ssl. It looks like http.Transport dictates this. Is there another way to force http 1?

@bradfitz
Copy link
Contributor

See the package docs: https://golang.org/pkg/net/http/#pkg-overview

I'm going to close this for now. We can reopen if it looks like that nginx is going to be in the wild for some time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

4 participants