Embedded Jetty HTTP / 2 does not work with Firefox / Chrome, but seems to be with Safari

I am implementing a servlet in embedded Jetty (9.3.0.v20150612) and I would like to use HTTP / 2.

I allow ALPN to select HTTP1.1 or HTTP2 for protocol negotiation. When I send an HTTP request to my servlet from Safari 8 (only HTTP1.1 is supported) or Safari 9 (support HTTP1.1 and HTTP2), I get a response from my servlet. When I execute the same request from Firefox 39, it does not work, and I just get NS_ERROR_ABORT. I have the same issue with Chrome.

I have two questions:

  • Why am I not getting a response from Chrome and Firefox.
  • How can I find out if using Safari 9, HTTP / 2 was used instead of HTTP1.1? (My iOS9 app also connects seamlessly)

Below is the code to perform Jetty initialization

private void startHTTP2Server() { WebServerProperties webProperties = WebServerProperties.getInstance(); HttpConfiguration config = getHttpConfiguration(); HttpConnectionFactory http1 = new HttpConnectionFactory(config); HTTP2ServerConnectionFactory http2 = new HTTP2ServerConnectionFactory(config); NegotiatingServerConnectionFactory.checkProtocolNegotiationAvailable(); ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); alpn.setDefaultProtocol(http1.getProtocol()); // sets default protocol to HTTP 1.1 // SSL Connection Factory SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setKeyStorePath(webProperties.getKeystore()); sslContextFactory.setKeyStorePassword(webProperties.getKeystorePassword()); //sslContextFactory.setKeyManagerPassword(KEYSTORE_PW); //sslContextFactory.addExcludeCipherSuites(".*RC4.*"); //sslContextFactory.addExcludeCipherSuites("TLS_DHE_RSA.*"); sslContextFactory.setProtocol(webProperties.getTLSVersion()); // SEB SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol()); Server server = new Server(); //ServerConnector connector = new ServerConnector(server, ssl, alpn, http2, http1); ServerConnector connector = new ServerConnector(server, ssl, alpn, http2, http1); connector.setPort(webProperties.getPort()); server.addConnector(connector); // --- SEB ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath(webProperties.getServletContext()); context.setResourceBase(System.getProperty(webProperties.getServletTmpDir())); server.setHandler(context); // Add dump servlet context.addServlet(IMonServer.class, webProperties.getServletPath()); try { server.start(); server.join(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static HttpConfiguration getHttpConfiguration() { WebServerProperties webProperties = WebServerProperties.getInstance(); HttpConfiguration config = new HttpConfiguration(); config.setSecureScheme("https"); config.setSecurePort(webProperties.getPort()); config.setSendXPoweredBy(true); config.setSendServerVersion(true); config.addCustomizer(new SecureRequestCustomizer()); return config; } 

When I start the server, I also give the Java parameter -Xbootclasspath / p: $ installDirectory / lib / alpn-boot-8.1.3.v20150130.jar

Is there something wrong or not? Thank you for your help.

Hi,

+5
source share
1 answer

Your code is correct, it just lacks two more lines that are important for the correct operation of HTTP / 2.

When configuring SslContextFactory add the lines:

  sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); sslContextFactory.setUseCipherSuitesOrder(true); 

What these two lines do is sort the TLS ciphers to prefer HTTP / 2 over others and ask that this order be respected.

Without sorting, the server returned to an older version of HTTP / 2 (h2-14), which did not use encryption strength, but this, unfortunately, is rejected by Chrome and Firefox.

I don’t know exactly why it works with Safari: either a Safari error, or a more relaxed interpretation of the HTTP / 2 specification regarding the strength of encryption in relation to other browsers.

+6
source

All Articles