Send a curl Request with a Specific HTTP Version
Pick the protocol curl speaks with --http1.0, --http1.1, --http2 or --http2-prior-knowledge. Over plain HTTP, --http2 sends an Upgrade header and falls back to 1.1.
You need to test how a server behaves with a particular HTTP version, or force curl away from the default.
for v in --http1.0 --http1.1 --http2; do
echo "== $v"
curl -sv "$v" -o /dev/null http://localhost:8000/ 2>&1 | grep -E '^> (GET|Upgrade)'
done
echo "== --http2-prior-knowledge"
curl -s --http2-prior-knowledge -o /dev/null http://localhost:8000/
echo "exit status: $?"== --http1.0
> GET / HTTP/1.0
== --http1.1
> GET / HTTP/1.1
== --http2
> GET / HTTP/1.1
> Upgrade: h2c
== --http2-prior-knowledge
exit status: 18The verbose request line shows what curl really sent. --http1.0 and --http1.1 change the version in the request line. --http2 over a cleartext URL cannot negotiate with TLS, so curl sends an HTTP/1.1 request carrying Upgrade: h2c and uses 1.1 when the server ignores it. --http2-prior-knowledge skips the upgrade and speaks HTTP/2 from the first byte, so a server that only knows HTTP/1 breaks the connection, and the run ended with exit status 18. The options are in the curl manual.
Over HTTPS, --http2 is negotiated through ALPN and works as expected, and curl uses HTTP/2 by default there when it was built with it. This run used a plain HTTP server, so it shows the cleartext behavior only. Use -w '%{http_version}' to print the version that was actually used.