2015-07-26 20 views
5

Tôi đang triển khai servlet trong một Jetty được nhúng (9.3.0.v20150612) và tôi muốn sử dụng HTTP/2.Embedded Jetty HTTP/2 không hoạt động với Firefox/Chrome nhưng có vẻ ổn với Safari

Tôi đang bật ALPN cho đàm phán giao thức để chọn HTTP1.1 hoặc HTTP2. Khi tôi gửi yêu cầu HTTP đến servlet của tôi từ Safari 8 (chỉ hỗ trợ HTTP1.1) hoặc Safari 9 (hỗ trợ cả HTTP1.1 & HTTP2), tôi nhận được câu trả lời từ servlet của mình. Khi tôi thực hiện cùng một yêu cầu từ Firefox 39, nó không hoạt động và tôi chỉ nhận được NS_ERROR_ABORT. Tôi gặp vấn đề tương tự với Chrome.

Tôi có hai câu hỏi:

  1. Tại sao tôi không nhận được câu trả lời từ Chrome & Firefox
  2. Làm thế nào tôi có thể biết nếu với Safari 9, HTTP/2 đã được sử dụng thay vì HTTP1.1? (IOS9 App của tôi cũng đang kết nối mà không vấn đề)

Dưới đây là đoạn code để thực hiện việc khởi tạo Jetty

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; 
} 

Khi tôi bắt đầu máy chủ, tôi cũng cung cấp tùy chọn Java -Xbootclasspath/p: $ installDirectory/lib/alpn-boot-8.1.3.v20150130.jar

Có gì sai hoặc thiếu? Nhờ sự giúp đỡ của bạn,

Kính trọng,

+0

Bạn có thể trợ giúp với: webProperties? mà nhập/jar? –

Trả lời

6

Mã của bạn là chính xác, nó chỉ thiếu hơn hai dòng quan trọng để có được HTTP/2 để làm việc một cách chính xác.

Khi bạn cấu hình SslContextFactory, thêm dòng:

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

gì hai dòng sau làm là để sắp xếp các thuật toán mã hóa TLS để thích HTTP/2 người trước khi những người khác, và yêu cầu phải tôn trọng trật tự đó .

Không phân loại, máy chủ đã quay trở lại phiên bản cũ hơn của HTTP/2 (h2-14) không thực thi cường độ mã hóa, nhưng điều này không may bị Chrome và Firefox từ chối.

Tôi không biết chính xác lý do tại sao nó hoạt động với Safari: lỗi Safari hoặc giải thích chi tiết hơn về đặc điểm kỹ thuật HTTP/2 liên quan đến cường độ mã hóa đối với các trình duyệt khác.

+0

Cảm ơn rất nhiều, nó hoạt động thực sự tốt đẹp với Firefox và Chrome với sự thay đổi này! Một câu hỏi khác, làm cách nào tôi có thể kiểm tra ở phía máy chủ (với một số nhật ký trong Cầu cảng) nếu yêu cầu đã được xử lý bằng cách sử dụng http 1.1 hoặc http/2? – sebastien

+0

Nói chung, 'HttpServletRequest.getProtocol()' sẽ trả về chuỗi phiên bản giao thức HTTP. Để ghi nhật ký phía máy chủ tích hợp của Jetty, hãy xem https://www.eclipse.org/jetty/documentation/current/embedded-examples.html – sbordet

+0

Cảm ơn bạn lần nữa! Với HttpServletRequest.getProtocol() tôi đã xác minh ứng dụng IOS 9 của tôi thực sự đang sử dụng HTTP/2 – sebastien

Các vấn đề liên quan