Httpx: Support HTTP/2 without TLS

Created on 4 Nov 2019  路  11Comments  路  Source: encode/httpx

Would it be possible to force the httpx client to use HTTP/2 to communicate with the server without TLS?

I'm using it as

client = AsyncClient(http_versions=["HTTP/2"])

but it still (reasonably tho) uses HTTP/1.1.

Most of the clients are trying to negotiate the update to HTTP/2 over HTTP/1.1 before as well, which is desired behaviour, but it might be handy for easier development and/or debugging.

There's hyper.HTTP20Connection that enforces h2, but it gets a bit out of sync from h2 itself.

htt2 tls+pki

Most helpful comment

Hi @indomirreg, I don't we have plans in the near future to support this, certainly not pre 1.0. But I think we're all in agreement this is something we could look into so I'm reopening this issue.

All 11 comments

To allow for this I think we'd need to add support for the HTTP header Upgrade: h2c right?
(Rather than the current HTTPS-only connections which are ALPN-negotiated.)

I'd be okay with us supporting that - it just needs the extra work is all.

@gvbgduh What is your use-case for HTTP/2 without TLS? All browsers that implement HTTP/2 only support via ALPN.

The other issue with that configuration example above is that in order to support HTTP/2 without TLS we have to use HTTP/1.1 to get an upgrade.

Thanks, @sethmlarson, yes that makes sense.
To be honest, I was looking for some shortcuts with setting up the client for testing for the HTTP/2 implementation against the server-side.

After some research it is true that HTTP/2 does not require encryption, but "currently no browser supports HTTP/2 unencrypted", and there seems to be various reasons why that is.

I'd agree with Tom that this could be supported, but it'd just need someone to work on it.

If your use case is local HTTP/2 testing, I guess the main obstacle is setting up a local self-signed TLS certificate. So in the meantime, would adding a section or some links to our docs about this help alleviate the issue?

Thanks a lot @florimondmanca, yes, it would definitely be an option. As it's not very obvious how to use self-signed certificates.

On the other hand, I gave it a bit of though, and I think there can be a valid example.
Indeed, browsers don't support unencrypted traffic, but your own APIs might not. And if we have a number of services that communicate with each other within the private network behind some firewall we can save a bit on encryption overhead. Sometimes it can be such a practice to terminate ssl at the load balancer.
Tho, not all of HTTP/2 features would make sense for APIs as for browsers, but at least multiplexing can be helpful.

Another thing, that upgrade flow can actually be handy, but it seems to worth another ticket.

I may try to help with it, but I want to finish the support for uvicorn first.

Ah, so the goal is to test the Uvicorn HTTP/2 implementation? 馃槃 Sounds exciting.

I think there's not a pressing need otherwise to add support for unencrypted HTTP/2, and as you wrote it's probably worth a different ticket spun up from this one.

If you all are OK with it I'll close this, and open one about documenting usage of self-signed certificates. Thanks @gvbgduh!

Yeah, I'm happy with it. Thanks @florimondmanca!
I guess those 2 cases (unencrypted traffic within secure net and the upgrade flow) may arise at some point eventually, but not sure it's worth attention now.

@florimondmanca any plan to support h2c yet?

Currently, 5G Core works on HTTP2 and as services are behind firewall and load balancer, they communicate using h2c to avoid encryption overload. The goal was to test these services and few implementations are available on h2c.

I am using reverse proxy for http2/TLS -> h2c but this workaround seems unstable. Implementation suggested in #873 would be really helpful
"Second is known as "with prior knowledge". The client does not send a first HTTP/1.1 request but directly sends the request in HTTP/2 format (with frames...) assuming "with prior knowledge" that the server understands the HTTP/2 protocol. All of this without TLS."

Thanks

Hi @indomirreg, I don't we have plans in the near future to support this, certainly not pre 1.0. But I think we're all in agreement this is something we could look into so I'm reopening this issue.

A note that this somewhat ties into #304 (connection upgrades), since "unencyprted HTTP/2" via h2c is an HTTP/1.1 + an h2c upgrade. So it could be that we'd eventually make WebSocket and HTTP/2+h2c use the same "upgrade API" (?).

Furthermore, the h2 docs have a handy guide about h2c upgrades: Negotiating HTTP/2: HTTP URLs (Upgrade).

I also have a usecase where I test microservices from https://github.com/GoogleCloudPlatform/microservices-demo one-by-one. Those microservices don't use TLS due to in-cluster safety.
I should say that curl also fails to autodetect HTTP/2 here, but it offers a flag of --http2-prior-knowledge. With the approach of "force http/2", we don't need any complex solutions.

What would you say to following proposal: have a third value for http2 flag of Client and AsyncClient, something like this:

client = httpx.AsyncClient(http2="force")
# or 
client = httpx.AsyncClient(http2=httpx._types.HTTP2Flags.FORCED)

And have it propagated to SyncHTTPConnection._create_connection() and its async brother.
Does it make sense to you? Any thoughts?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

daisixuan picture daisixuan  路  4Comments

florimondmanca picture florimondmanca  路  4Comments

florimondmanca picture florimondmanca  路  4Comments

tomchristie picture tomchristie  路  4Comments

florimondmanca picture florimondmanca  路  3Comments