Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--http2-prior-knowledge still offers http/1.1 #9963

Closed
kit-ty-kate opened this issue Nov 22, 2022 · 12 comments
Closed

--http2-prior-knowledge still offers http/1.1 #9963

kit-ty-kate opened this issue Nov 22, 2022 · 12 comments
Labels

Comments

@kit-ty-kate
Copy link

kit-ty-kate commented Nov 22, 2022

I did this

curl -sv https://exn.st --http2-prior-knowledge -o /dev/null

I expected the following

[…]
* Connected to exn.st (XXX...) port 443 (#0)
* ALPN: offers h2
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
[…]
> GET / HTTP/2
[…]

but got

[…]
* Connected to exn.st (XXX...) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
[…]
> GET / HTTP/1.1
[…]

I expected to not see ALPN: offers http/1.1 given what the documentation says on the website (https://curl.se/docs/http2.html):

curl offers the --http2-prior-knowledge command line option to enable use of HTTP/2 without HTTP/1.1 Upgrade.

curl/libcurl version

curl 7.86.0 (aarch64-unknown-linux-gnu) libcurl/7.86.0 OpenSSL/3.0.7 zlib/1.2.13 brotli/1.0.9 zstd/1.5.2 libidn2/2.3.4 libpsl/0.21.1 (+libidn2/2.3.4) libssh2/1.10.0 nghttp2/1.51.0
Release-Date: 2022-10-26
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

operating system

Linux alarm 5.19.0-asahi-5-1-ARCH #1 SMP PREEMPT_DYNAMIC Sat, 20 Aug 2022 09:23:11 +0000 aarch64 GNU/Linux
@jay
Copy link
Member

jay commented Nov 23, 2022

--http2-prior-knowledge :

Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1 Upgrade. It requires prior knowledge that the server supports HTTP/2 straight away. HTTPS requests will still do HTTP/2 the standard way with negotiated protocol version in the TLS handshake.

Do you see different results when http/1.1 is not sent in the ALPN?

@bagder
Copy link
Member

bagder commented Nov 24, 2022

prior knowledge is pointless over HTTPS as then the negotiation is done before HTTP starts and with no "penalty". Without HTTPS you can avoid a round-trip if you know can speak h2 immediately.

@bagder
Copy link
Member

bagder commented Nov 24, 2022

I suppose we could use it there to mean "I really only want h2 and nothing else"

@kit-ty-kate
Copy link
Author

Do you see different results when http/1.1 is not sent in the ALPN?

With #9964 yes. I had to change the code of exn.st but basically the previous code would choose http/1.1 over h2 if the ALPN request said http/1.1 is available.

I suppose we could use it there to mean "I really only want h2 and nothing else"

That's what I thought the argument would do after reading the documentation. But it looks like the manpage disagrees then. If you think the behaviour could be changed I think it would be a good thing. If you don't want to change the behaviour maybe a new argument could be added?

@drok
Copy link
Contributor

drok commented Dec 22, 2022

prior knowledge is pointless over HTTPS as then the negotiation is done before HTTP starts and with no "penalty". Without HTTPS you can avoid a round-trip if you know can speak h2 immediately.

The TLS handshake can be avoided by using a saved ssl session.

Applications which use libcurl and seek to extract maximum performance, take advantage of saved SSL sessions. It may or may not be supported in the current "curl" command line application.

Regards

@bagder
Copy link
Member

bagder commented Dec 22, 2022

The TLS handshake can be avoided by using a saved ssl session.

Correct, but that is entirely separate from this proposed change. libcurl already features a session cache for that.

@drok
Copy link
Contributor

drok commented Dec 23, 2022

The TLS handshake can be avoided by using a saved ssl session.

Correct, but that is entirely separate from this proposed change. libcurl already features a session cache for that.

My point is that prior knowledge is not pointless over HTTPS for the stated reason that the TLS handshake is slow, because that reason is not valid. TLS handshake is not guaranteed to be slow. The TLS handshake can be as fast as a 3-way TCP handshake in some cases, such as the example I gave, where session caches are in use.

@bagder
Copy link
Member

bagder commented Feb 9, 2023

This is not a bug, but could be made into a future feature if someone wants to work on it.

@bagder bagder closed this as completed Feb 9, 2023
@Sharathji1990
Copy link

Sharathji1990 commented Jul 23, 2024

Hi Team,

I understand its kind of old thread, but is this issue fixed in any release. I understand the fix provided by Kit-ty-Kate had merge conflicts.

But, --http2-prior-knowledge doesn't work as defined and it really doesn't solve the problem of wanting to send only H2 in ALPN header.

Please let me know if there is any work-around or any released package which has this kind of working. ( I couldn't find it in any release package and none of the change logs mention it)

Thanks

@bagder
Copy link
Member

bagder commented Jul 23, 2024

But, --http2-prior-knowledge doesn't work as defined and it really doesn't solve the problem of wanting to send only H2 in ALPN header.

That's not what this option is for, so I don't think saying "doesn't work as defined" is correct.

But as said before: we/someone could make it work like this.

jay added a commit to jay/curl that referenced this issue Jul 23, 2024
- For HTTPS if http2-prior-knowledge is set then only offer h2 (HTTP/2)
  alpn to the server for protocol negotiation.

Prior to this change both HTTP/2 ("h2") and HTTP/1.1 ("http/1.1") were
offered for ALPN when http2-prior-knowledge was set.

CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE (tool: --http2-prior-knowledge) is
meant to send non-TLS HTTP requests HTTP/2 when it is known the server
supports them. However when HTTPS is used then it attempts to first
negotiate the connection with ALPN. In that case the user likely does
not want to offer http/1.1 to the server as an acceptable protocol.

Reported-by: kit-ty-kate@users.noreply.github.com

Fixes curl#9963
Closes #xxxxx
@jay
Copy link
Member

jay commented Jul 23, 2024

#14266

@Sharathji1990
Copy link

I stand corrected for my mentioning of --http2-prior-knowledge working, and thanks a lot for changing the behaviour and committing it.

jay added a commit that referenced this issue Aug 4, 2024
- For HTTPS if http2-prior-knowledge is set then only offer h2 (HTTP/2)
  alpn to the server for protocol negotiation.

Prior to this change both HTTP/2 ("h2") and HTTP/1.1 ("http/1.1") were
offered for ALPN when http2-prior-knowledge was set.

CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE (tool: --http2-prior-knowledge) is
meant to send non-TLS HTTP requests HTTP/2 when it is known the server
supports them. However when HTTPS is used then it attempts to first
negotiate the connection with ALPN. In that case the user likely does
not want to offer http/1.1 to the server as an acceptable protocol.

Reported-by: kit-ty-kate@users.noreply.github.com

Fixes #9963
Closes #14266
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5 participants