net
net copied to clipboard
http2/h2c: handle request bodies during h2c connection upgrading
If a request that triggered an upgrade from HTTP/1.1 -> HTTP/2 contained a body, it would not be replayed by the server as a HTTP/2 data frame. This would result in hangs as the client would get no data back, as the request body was never actually handled.
This code corrects this, and sends HTTP/2 DATA frames with the request body.
As an example:
Client:
$ curl -v --http2 -d 'POST BODY' http://localhost:5555
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5555 (#0)
> POST / HTTP/1.1
> Host: localhost:5555
> User-Agent: curl/7.64.1
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
> Content-Length: 9
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 9 out of 9 bytes
< HTTP/1.1 101 Switching Protocols
< Connection: Upgrade
< Upgrade: h2c
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 200
< content-length: 0
< date: Sat, 29 Jan 2022 06:51:05 GMT
<
* Connection #0 to host localhost left intact
* Closing connection 0
Echo server:
$ ./bin/h2test
Listening [0.0.0.0:5555]...
Request: {Method:POST URL:/ Proto:HTTP/2.0 ProtoMajor:2 ProtoMinor:0 Header:map[Accept:[*/*]
Content-Length:[9] Content-Type:[application/x-www-form-urlencoded] User-Agent:[curl/7.64.1]]
Body:0xc000098120 GetBody:<nil> ContentLength:9 TransferEncoding:[] Close:false Host:localhost:5555
Form:map[] PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr:127.0.0.1:54540 RequestURI:/
TLS:<nil> Cancel:<nil> Response:<nil> ctx:0xc0000a0000}
Received body: POST BODY
Fixes #38064
This PR (HEAD: 189b99aa2b1cd8ee48efdeba6592902c5e28604e) has been imported to Gerrit for code review.
Please visit https://go-review.googlesource.com/c/net/+/383114 to see it.
Tip: You can toggle comments from me using the comments
slash command (e.g. /comments off
)
See the Wiki page for more info
Message from Ingo Oeser:
Patch Set 1:
(2 comments)
Please don’t reply on this GitHub thread. Visit golang.org/cl/383114. After addressing review feedback, remember to publish your drafts!
This PR (HEAD: ba79222830de46c3accddb442b867c4ca37a7635) has been imported to Gerrit for code review.
Please visit https://go-review.googlesource.com/c/net/+/383114 to see it.
Tip: You can toggle comments from me using the comments
slash command (e.g. /comments off
)
See the Wiki page for more info
Message from Damien Neil:
Patch Set 2: Code-Review-1
(1 comment)
Please don’t reply on this GitHub thread. Visit golang.org/cl/383114. After addressing review feedback, remember to publish your drafts!
Message from James Lamanna:
Patch Set 2:
(2 comments)
Please don’t reply on this GitHub thread. Visit golang.org/cl/383114. After addressing review feedback, remember to publish your drafts!
Message from Damien Neil:
Patch Set 2:
(1 comment)
Please don’t reply on this GitHub thread. Visit golang.org/cl/383114. After addressing review feedback, remember to publish your drafts!
Message from James Lamanna:
Patch Set 2:
(1 comment)
Please don’t reply on this GitHub thread. Visit golang.org/cl/383114. After addressing review feedback, remember to publish your drafts!
Message from Damien Neil:
Patch Set 2:
(1 comment)
Please don’t reply on this GitHub thread. Visit golang.org/cl/383114. After addressing review feedback, remember to publish your drafts!