Description
Previous discussion: bradfitz/http2#59
h2c (http2 without TLS) is somewhat controversial part of the http2 spec. As discussed in the linked ticket above, major browser vendors are refusing to implement it.
I still think it is important to have first class support in Go standard library though.
The primary reason is that https is an ideal transport for inter-service RPC - c.f. grpc.io which in grpc/grpc-go has to re-implement large parts of http2 client and server transport to work around this issue.
But wanting to use http2 between internal services is not limited to gRPC.
My primary motivation is that I generally want my load balancer to terminate SSL. This is not just to reduce crypto overhead on individual application servers, but can actually be more secure.
To enable perfect forward secrecy, you have to keep tight controls over session ticket keys and rotate them frequently. This is much easier to achieve if only two (or a few) load balancer machines must terminate SSL rather than possibly hundreds or thousands of application servers, not to mention fewer places for an intruder to get hold of those keys.
Of course it's possible to terminate public SSL with perfect forward secrecy at LB and then have backend connections use internally signed certificates and forgo the same stringency, but in this setup TLS is pure overhead, and additional complexity to administer.
So I think it's pretty reasonable that Go, a language whose core competency is building network services, should at least provide a means to serve and consume h2c via the standard library http2 package. I'd even argue that it should be automatic, but if opinion is strong, I'd settle for just being possible without re-implementing large chunks of the http2 transports.
If there is agreement from core (@bradfitz has most insight I'd guess) on how this could be introduced, I'd be really happy to contribute the code. How about if it was a separate package x/net/http2/h2c
and for now it's required to manually choose h2c transport in client/server?
If not, this could be built as a (standalone) third party library that anyone who needs this can use for now.
Thanks for you help with this.
Activity
bradfitz commentedon Jan 28, 2016
gRPC reimplemented http2 because they had to. We started with the same http2.Framer code and they wrote their gRPC-specific http2 client & server in parallel with me writing net/http's http2 client and server. I'm currently working on unifying them (see grpc/grpc-go#75).
I might accept h2c as a separate package under x/net/http2, but it won't be part of the Go standard library or on by default. Some of the work was already done as part of golang/net@d62542d
banks commentedon Jan 29, 2016
@bradfitz thanks.
My thought is that eventually, another framework like gRPC should not have to reimplement http2 because the standard (or at least
x/net
) package would support all valid protocol use-cases. I realise gRPC came before your implementation so it was not an option there, but long term it seems bad that anyone else (like me) who wants to use HTTP/2 for inter-service communication (according to spec) has to reinvent the wheel despite "HTTP/2" implementation existing in standard lib.To be clear, for my use-case I'm mostly interested in inter-service communication where I assume I control both client and server, so I really want HTTP/2 over TCP with "prior knowledge" (section 3.4) rather than HTTP/1.1 Upgrade.
But I think it makes sense that there is at least a somewhat official library (even if it stays in x) that supports the whole spec.
I looked at the old PR for upgrade support which seems a little hairy in the way it integrates with http server - I can see it's not a simple request to support.
Fair enough. Can I ask how the two interact? I'm using 1.6rc which uses http2 automatically when serving TLS via net/http (standard library) but the http2 implementation appears to still be this one in
x/net
. Do you consider http2 to be "standard library" due to its integration withnet/http
even though the implementation is still inx/net
and still has TODO items on public interface or did I misunderstand something (like a subset got copied over)?I will take a look through the commit you linked and get a better idea what the options are in terms of optional h2c upgrade and/or prior knowledge support with
net/http
.Thanks again for your help.
banks commentedon Jan 29, 2016
Hmm I see your linked commit is against
net/http2
notx/net/http2
implying it does exist in standard library, but if I rungodoc
on my local 1.6rc http2 is still in x in the Release Candidate despite being integrated withnet/http
.bradfitz commentedon Jan 29, 2016
We vendor a copy of x/net/http2 into net/http so http2 can be automatic for the standard library. What I mean is that I will not enable h2c automatically for the standard library, but h2c work can happen in a subpackage of x/net, like x/net/http2/h2c.
banks commentedon Jan 29, 2016
Thanks Brad, that's clear now.
gopherbot commentedon Feb 3, 2016
CL https://golang.org/cl/19176 mentions this issue.
http2: export Server.ServeConn
gopherbot commentedon Mar 31, 2016
CL https://golang.org/cl/21327 mentions this issue.
net/http: allow Handlers to handle http2 upgrade PRI requests
ayanamist commentedon May 14, 2016
Sorry to bother, but i found it's quite easy to make a h2c client with a little modification to
golang.org/x/net/http2
then remove the restriction from
golang.org/x/net/http2/transport.go
infunc (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error)
I agree that nearly all browsers will not support h2c, but there are some h2c server serving traffic as another RPC service (not gRPC), so can https restriction be loosen a little to support h2c client?
bradfitz commentedon May 16, 2016
I'd be fine with an
http2.Transport.AllowHTTPScheme bool
knob.ayanamist commentedon May 16, 2016
@bradfitz I'd be fine wth the knob too. So, will it be shipped?
bradfitz commentedon May 16, 2016
If somebody sends me a change.
37 remaining items