elixir-mint / mint

Functional HTTP client for Elixir with support for HTTP/1 and HTTP/2 🌱
Apache License 2.0
1.36k stars 112 forks source link

Add options to bypass ALPN protocol negotiation #294

Closed zillou closed 3 years ago

zillou commented 3 years ago

I tried to connect a server with Mint.HTTP2, but I got {:error, : protocol_not_negotiated}. Because this server does support h2 but not support ALPN negotiation (can tell from the curl output).

I tried to comment out his line, and everything works fine:

https://github.com/elixir-mint/mint/blob/master/lib/mint/http2.ex#L1061

So, the question is it possible to add a transport option to bypass the ALPN protocol negotiation step if we knew the server supports h2 already?

Here's the output from curl. You can see there * ALPN, server did not agree to a protocol.

*   Trying ******* ...
* TCP_NODELAY set
* Connected to ******* port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
.... ....
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol <<---
* Server certificate:
....
....
* 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
* Using Stream ID: 1 (easy handle 0x7fba6d00d600)
> GET /api/***** HTTP/2
> Host: ***
> Accept: application/json
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200
.....
ericmj commented 3 years ago

I am hesitant to support this since according to the RFC it's a MUST to use ALPN when connecting over TLS https://tools.ietf.org/html/rfc7540#section-3.4:

[...] implementations that support HTTP/2 over TLS MUST use protocol negotiation in TLS [TLS-ALPN].

The reasoning for this seems to be to prevent cross-protocol attacks https://tools.ietf.org/html/rfc7540#section-10.2.

Is it possible for you to change the server so it's compliant with the HTTP/2 RFC or to change to a server that is compliant?

zillou commented 3 years ago

Thanks for looking into this. I agree that it's better to follow the RFC strictly. I'll try to push the service provider to make their server be compliant with the RFC instead.