Hi, are there any plans to support http/2 ? Jetty 9.4 would support it.
Have you tried creating a jetty-http2-server and passing it to Javalin via app.embeddedServer()?
i did not, i am not familiar yet with http2. i need bidirectional communication so my guess is that http2 could be a good choice. at the moment i just created a little test with websockets. but i would prefer to also test http2.
https://www.eclipse.org/jetty/documentation/9.4.x/http2.html
I did not find a sample on their page with streams (probably what i need).
Is there any kind of sample for http2 with javalin? Or can i use the regular rest api which switches to http2? if so, how are streams handled?
@blahmutz You can check some examples of creating embedded http2 jetty server here. The repo also has all the dependencies required in the pom file.
There are some tutorials on the Javalin website for setting up a custom server instance.
Regarding http2 push, this SO answer has some basic example of using PushBuilder. You can try to connect that to the Javalin rest api, it should work, though I haven't tried myself 馃檪
the existing examples out there are too old. they have "checkProtocolNegotiationAvailable", which was removed sometime ago
this is what I have so far.
public static void main(String[] args) {
Javalin app = Javalin.create()
.embeddedServer(new EmbeddedJettyFactory(() -> {
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
// HTTP Configuration
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSecureScheme("https");
httpConfig.setSecurePort(8443);
// SSL Context Factory for HTTPS and HTTP/2
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("keystore.p12");
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
// HTTPS Configuration
HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
httpsConfig.addCustomizer(new SecureRequestCustomizer());
// HTTP/2 Connection Factory
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig);
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
alpn.setDefaultProtocol("h2");
// SSL Connection Factory
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
// HTTP/2 Connector
ServerConnector http2Connector = new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(httpsConfig));
http2Connector.setPort(8443);
server.addConnector(http2Connector);
ALPN.debug = false;
return server;
})).start();
app.get("/", ctx -> ctx.result("Hello World"));
}
I got it to start. the regular connector on port 8080 is working fine.
I also have
Started ServerConnector@ {SSL,[ssl, alpn, h2, http/1.1]}{0.0.0.0:8443}
so at least jetty isn't hating it
but...
trying to make any request with curl, I keep getting SSL error
in terms of dep, on top of javalin, I had to add
compile "org.eclipse.jetty.http2:http2-server:9.4.8.v20171121"
compile "org.eclipse.jetty:jetty-alpn-conscrypt-server:9.4.8.v20171121"
compile "org.eclipse.jetty.alpn:alpn-api:1.1.3.v20160715"
runtime "org.mortbay.jetty.alpn:alpn-boot:8.1.12.v20180117"
the api version you need to use is specific to the java 8 version as per
https://www.eclipse.org/jetty/documentation/9.4.x/alpn-chapter.html#alpn-versions
also, just to keep it all in one place and you can cut and paste.
I use
keytool -genkey -alias jetty -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
to generate the keystore file for above
@wmacgyver What curl command do you execute and what error do you receive?
@wmacgyver have you tried running this outside of Javalin?
server.setHandler(new HelloHandler());
server.start();
server.join();
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
public class HelloHandler extends AbstractHandler {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().println("<h1>Hello Jetty</h1>");
baseRequest.setHandled(true);
}
}
@ShikaSD
trying curl -k --http2-prior-knowledge https://localhost:8443, I get error
even using regular https
curl -k https://localhost:8443
I get the same error OpenSSL SSL_connect: SSL_ERROR_SYSCALL
however, @tipsy is on to something
I ran the code outside of javalin, and it bombs the same way. so it's not javalin. going to make it work with just jetty first
will keep you guys posted
@wmacgyver maybe looking at what Dropwizard does would be helpful: https://github.com/dropwizard/dropwizard/tree/1bb7142cb241d3218a80c58e2018d5ad7790c90c/dropwizard-http2/src/main/java/io/dropwizard/http2
It was last updated 13 days ago, so hopefully it's not outdated.
@tipsy
doh, I figured it out right away as soon as you pointed out to try run it as pure jetty
I was missing sslContextFactory.setProvider("Conscrypt");
ie it needs to look like
// SSL Context Factory for HTTPS and HTTP/2
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("keystore.p12");
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
sslContextFactory.setProvider("Conscrypt");
it works both in pure jetty and javalin now.
I'm going to create a full working example in a github repo for using javalin with http2
and write up some docs. be back to you guys. but it works now
@wmacgyver cool. When you feel confident in your implementation it would be great if you could create a PR for https://github.com/tipsy/javalin/issues/69. It would be nice to include some "default" Jetty-servers with Javalin.
@tipsy got it, I guess this means you are moving forward on tie javalin to jetty then :)
Most likely, yes, but #69 doesn't really impact that, I just want a standalone-object like this:
JettyDefaults {
fun http2Server(...): Server = ...
fun sslServer(...): Server = ...
}
understood.
full example https://github.com/wmacgyver/javalin-http2-example as promised
@wmacgyver thanks! I forked the repo and expanded it a bit: https://github.com/tipsy/javalin-http2-example
I added gradle-wrapper, a kotlin version, bumped all dependencies and added a static-file example. I couldn't add this to your repo, as this is now part of the official documentation: https://javalin.io/documentation#sslhttp2
@tipsy no worries, I'm glad you found it useful enough to include it in the official doc. I'm happy to help out. http2 option is so few and far in between on JVM. I'm glad it's possible with javalin.