Details
-
Bug
-
Status: Resolved
-
Minor
-
Resolution: Fixed
-
4.0.3
-
CXF latest and CXF 4.0.3 on Java 11 and 17 both show this issue.
-
Unknown
Description
Summary
I have been trying to update one of our apps using the Jetty backend to use http2. While doing this I've noticed that the protocol negotiation is in the wrong order which results in http/1.1 always being preferred where the client includes this in the ALPN handshake. This means that both browsers and cURL will never successfully negotiate h2/http2.
—
The problem
The issue can be shown using curl.
curl -ikv https://localhost:9000
I've attached the full output of this command when running curl against the CXF sample jax_rs_basic_http2_jetty.
The important lines are:
* ALPN: offers h2,http/1.1 * ALPN: server accepted http/1.1
Compare this with the attached curl output from the CXF sample jax_rs_basic_http2_netty.
The important lines here are:
* ALPN: offers h2,http/1.1 * ALPN: server accepted h2
—
The solution
The ALPN takes place within ALPNServerConnection, which is part of the jetty-alpn-server module.
// RFC 7301 states that the server picks the protocol // that it prefers that is also supported by the client. for (String serverProtocol : serverProtocols) { if (clientProtocols.contains(serverProtocol)) { ConnectionFactory factory = getConnector().getConnectionFactory(serverProtocol); if (factory instanceof CipherDiscriminator && !((CipherDiscriminator)factory).isAcceptable(serverProtocol, tlsProtocol, tlsCipher)) { if (LOG.isDebugEnabled()) LOG.debug("Protocol {} not acceptable to {} for {}/{} on {}", serverProtocol, factory, tlsProtocol, tlsCipher, getEndPoint()); continue; } negotiated = serverProtocol; break; } }
As the code states, the server is responsible for picking the protocol and Jetty picks the first match in the server's list. From the log output of the same app the first in the list is http/1.1
INFO: Started ServerConnector@11eadcba\{ssl, (http/1.1, ssl, alpn, h2)}{0.0.0.0:9000}}
Therefore the solution is to ensure that when h2 is enabled inside JettyHTTPServerEngine -> createConnectorJetty, the HTTP2ServerConnectionFactory should always be added at the start of the list.
With this change, curl then successfully negotiates with h2.
Attachments
Attachments
Issue Links
- links to