Jetty version
9.4.26.v20200117
Java version
JDK1.8.0_u121
OS type/version
Windows
Description
Here is my code
package jetty.http.server;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.FlowControlStrategy;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
public class JettyEmbeddedServer {
public static void main(String[] args) throws Exception {
int plainPort = 18000;
int securePort = 18001;
int http2Port = 18002;
// Create a basic jetty server object without declaring the port. Since
// we are configuring connectors directly we'll be setting ports on
// those connectors.
Server server = new Server();
// HTTP Configuration
// HttpConfiguration is a collection of configuration information
// appropriate for http and https. The default scheme for http is
// <code>http</code> of course, as the default for secured http is
// <code>https</code> but we show setting the scheme to show it can be
// done. The port for secured communication is also set here.
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSecureScheme("https");
httpConfig.setSecurePort(securePort);
httpConfig.setOutputBufferSize(32768);
// HTTP connector
// The first server connector we create is the one for http, passing in
// the http configuration we configured above so it can get things like
// the output buffer size, etc. We also set the port (8080) and
// configure an idle timeout.
ServerConnector http = new ServerConnector(server,
new HttpConnectionFactory(httpConfig));
http.setPort(plainPort);
http.setIdleTimeout(30000);
// Since this example shows off SSL configuration, we need a keystore
// with the appropriate key.
String keystorePath = Resource.newClassPathResource("keystore").getURI().getPath();
// SSL Context Factory for HTTPS
// SSL requires a certificate so we configure a factory for ssl contents
// with information pointing to what keystore the ssl connection needs
// to know about. Much more configuration is available the ssl context,
// including things like choosing the particular certificate out of a
// keystore to be used.
SslContextFactory sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(keystorePath);
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
// OPTIONAL: Un-comment the following to use Conscrypt for SSL instead of
// the native JSSE implementation.
//Security.addProvider(new OpenSSLProvider());
//sslContextFactory.setProvider("Conscrypt");
// HTTPS Configuration
// A new HttpConfiguration object is needed for the next connector and
// you can pass the old one as an argument to effectively clone the
// contents. On this HttpConfiguration object we add a
// SecureRequestCustomizer which is how a new connector is able to
// resolve the https connection before handing control over to the Jetty
// Server.
HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
SecureRequestCustomizer src = new SecureRequestCustomizer();
src.setStsMaxAge(2000);
src.setStsIncludeSubDomains(true);
httpsConfig.addCustomizer(src);
// HTTPS connector
// We create a second ServerConnector, passing in the http configuration
// we just made along with the previously created ssl context factory.
// Next we set the port and a longer idle timeout.
ServerConnector https = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(httpsConfig));
https.setPort(securePort);
https.setIdleTimeout(500000);
// HTTP2
HttpConfiguration http2Config = new HttpConfiguration(httpConfig);
SecureRequestCustomizer http2src = new SecureRequestCustomizer();
http2src.setStsMaxAge(2000);
http2src.setStsIncludeSubDomains(true);
http2Config.addCustomizer(http2src);
HTTP2ServerConnectionFactory http2ConnectionFactory = new HTTP2ServerConnectionFactory(new HttpConfiguration(http2Config));
http2ConnectionFactory.setInitialSessionRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
http2ConnectionFactory.setInitialStreamRecvWindow(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
ServerConnector http2 = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_2.asString()),
http2ConnectionFactory);
http2.setPort(http2Port);
http2.setIdleTimeout(500000);
// Here you see the server having multiple connectors registered with
// it, now requests can flow into the server from both http and https
// urls to their respective ports and be processed accordingly by jetty.
// A simple handler is also registered with the server so the example
// has something to pass requests off to.
// Set the connectors
server.setConnectors(new Connector[]{http, https, http2});
// Set a handler
ServletContextHandler context = new ServletContextHandler(server, "/", true, false);
context.addServlet(new ServletHolder(new JettyEmbeddedServerHandler()), "/*");
// Start the server
server.start();
server.dumpStdErr();
server.join();
}
}
On jdk8 i have already config -Xbootclasspath/p:F:\maven-repository\org\mortbay\jetty\alpn\alpn-boot\8.1.11.v20170118\alpn-boot-8.1.11.v20170118.jar
and got the following erorr on startup
Exception in thread "main" java.lang.IllegalStateException: No protocol factory for SSL next protocol: 'HTTP/2.0' in ServerConnector@1817d444{SSL,[ssl, h2]}{0.0.0.0:18002}
at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:316)
at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:81)
at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:231)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:72)
at org.eclipse.jetty.server.Server.doStart(Server.java:385)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:72)
at jetty.http.server.JettyEmbeddedServer.main(JettyEmbeddedServer.java:126)
The problem is this line:
ServerConnector http2 = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_2.asString()),
http2ConnectionFactory);
The correct name for the HTTP/2 protocol is h2 not HttpVersion.HTTP_2.asString().
Use this instead:
ServerConnector http2 = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, http2ConnectionFactory.getProtocol()),
http2ConnectionFactory);
Note also that you are creating a connector that will only be able to speak HTTP/2 over TLS. This is called "HTTP/2 with prior knowledge" and clients may or may not be able to support this mode.
For example, curl supports it via curl --http2-prior-knowledge, but browsers won't be able to connect because they use ALPN.
If you want to setup ALPN, see this example.
Closing as I think this is solved. Please comment if you still have troubles.
Got it working.
Thanks for your help.
Most helpful comment
Got it working.
Thanks for your help.