When processing an HTTP/1 Upgrade: h2c request, detect errors reading
the request body and fail the request rather than passing off the
partially-read request to the HTTP/2 server.
Correctly handles the case where a MaxBytesHandler has limited the
size of the initial HTTP/1 request body.
Fixesgolang/go#56352
Change-Id: I08d60953cea26961cffbab3094cc1b44236f4e37
Reviewed-on: https://go-review.googlesource.com/c/net/+/447396
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: John Howard <howardjohn@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
The initial request on an h2c-upgraded connection is written as an
HTTP/1 request, with the response sent as an HTTP/2 stream.
The h2c package handled this request by constructing a sequence of
bytes representing an HTTP/2 stream containing the initial request,
prepending those bytes to the remainder of the connection, and
presenting that to the HTTP/2 server as if no upgrade had happened.
This translation did not handle request bodies. Handling request
bodies under this model would be difficult, since it would require
also translating the HTTP/2 flow control.
Rewrite the h2c upgrade to explicitly hand off the request to the
HTTP/2 server instead.
Fixesgolang/go#52882.
Change-Id: I26e0f12e2b1c8b48fd36ba47baea076424983553
Reviewed-on: https://go-review.googlesource.com/c/net/+/407454
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
When using h2c.NewHandler, the *http.Request object for h2c requests has a
.Context() that doesn't inherit from the *http.Server's BaseContext. This
is surprising for users of vanilla net/http, and is surprising to users of
http2.ConfigureServer; HTTP/1 requests inherit from that BaseContext, and
TLS h2 requests inherit from that BaseContext, but cleartext h2c requests
don't.
So, modify h2c.NewHander to respect that base Context, by way of the
hijacked Request's .Context().
Change-Id: Ibc24ae6e2fb153d9561827ad791329487dae8e5a
GitHub-Last-Rev: 821b2070f7
GitHub-Pull-Request: golang/net#88
Reviewed-on: https://go-review.googlesource.com/c/net/+/278972
Reviewed-by: Liam Haworth <liam@haworth.id.au>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Implements h2c by leveraging the existing http2.Server by implementing the 2
ways to start an h2c connection as described in RFC 7540, which are: (1)
create a connection starting with HTTP/1 and then upgrading to h2c [Section 3.2]
and (2) starting a connection directly speaking h2c (aka starting with prior
knowledge) [Section 3.4].
For both of the above connection methods the implementation strategy is to
hijack a HTTP/1 connection, perform the h2c connection on the hijacked
net.Conn, and create a suitably configured net.Conn to pass into
http2.Server.ServeConn.
For h2c with prior knowledge this is relatively simple. For that we just have
to verify the HTTP/2 client preface has been written to the net.Conn, and
then reforward the client preface to the hijacked connection.
For h2c upgraded from HTTP/1, this is a bit more involved. First we validate
the HTTP/1 Upgrade request, and respond to the client with 101 Switching
Protocols. Then we write a HTTP/2 client preface on behalf of the client,
and a settings frame and a headers frame which correspond to what was in
the upgrade request. Then since http2.Server is going respond with a
settings ACK, we swallow it so that it is not forwarded to the client since
for h2c upgrade from HTTP/1 the 101 Switching Protocols response replaces
the settins ACK.
Fixesgolang/go#14141
Change-Id: I435f40216c883809c0dcb75426c9c59e2ea31182
Reviewed-on: https://go-review.googlesource.com/112999
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>