On HTTP.jl 2.0 a GET to an HTTPS server that only speaks HTTP/1.1 fails in the TLS handshake under :auto and :h2. :h1 works, and curl and HTTP.jl 1.x both handle the same URL without trouble.
MWE
using HTTP
url = "https://cdaweb.gsfc.nasa.gov/WS/cdasr/1/dataviews"
for proto in (:auto, :h1, :h2)
try
r = HTTP.get(url; status_exception=false, protocol=proto)
println(proto, " => status ", r.status)
catch e
println(proto, " => ", sprint(showerror, e))
end
end
Output:
auto => http tls handshake error: tls handshake failed: tls: server selected unadvertised ALPN protocol
h1 => status 200
h2 => http tls handshake error: tls handshake failed: tls: server selected unadvertised ALPN protocol
What the server does
The server doesn't support h2. openssl shows it picks http/1.1 when both are offered, and negotiates nothing when only h2 is offered:
$ echo | openssl s_client -connect cdaweb.gsfc.nasa.gov:443 -alpn h2,http/1.1 2>/dev/null | grep ALPN
ALPN protocol: http/1.1
$ echo | openssl s_client -connect cdaweb.gsfc.nasa.gov:443 -alpn h2 2>/dev/null | grep ALPN
No ALPN negotiated
curl with --http2 connects and downgrades to 1.1:
$ curl -sI --http2 -w "%{http_version}\n" -o /dev/null https://cdaweb.gsfc.nasa.gov/WS/cdasr/1/dataviews
1.1
From that it looks like :auto advertises only h2 instead of h2, http/1.1, and then rejects the server's http/1.1 selection rather than falling back. I'd expect :auto to offer both and drop down to HTTP/1.1 the way curl does.
Versions
- Julia 1.12.6, macOS (arm64)
- HTTP 2.0.0
- Reseau 1.1.4
Workaround for now is protocol=:h1.
On HTTP.jl 2.0 a GET to an HTTPS server that only speaks HTTP/1.1 fails in the TLS handshake under
:autoand:h2.:h1works, and curl and HTTP.jl 1.x both handle the same URL without trouble.MWE
Output:
What the server does
The server doesn't support h2. openssl shows it picks
http/1.1when both are offered, and negotiates nothing when onlyh2is offered:curl with
--http2connects and downgrades to 1.1:From that it looks like
:autoadvertises onlyh2instead ofh2, http/1.1, and then rejects the server'shttp/1.1selection rather than falling back. I'd expect:autoto offer both and drop down to HTTP/1.1 the way curl does.Versions
Workaround for now is
protocol=:h1.