Reputation: 5093
Starting with Jetty 9.4.? it is possible to run HTTP and HTTPs on the same port. The gist of it is:
HttpConnectionFactory http = new HttpConnectionFactory();
SslConnectionFactory https = new SslConnectionFactory(sslCtxFactory, http.getProtocol());
DetectorConnectionFactory conFactory = new DetectorConnectionFactory(https);
ServerConnector connector = new ServerConnector(server, conFactory, http);
Since I only want to serve HTTPS, I would like to redirect each and every http://host:port/stuff
to https://host:port/stuff
. I know how to redirect with either subclass of RedirectRule
or just with a handler called early.
The thing I am struggling with is: how do I figure out from the request that the connection is HTTP and not HTTPS?
When I look at the Request
in the debugger, I found no hints, everything looks as if it is http even if the connection is https, Request.isSecure()
is false, scheme is http
and so on. The best thing I could come up with was:
if (Request.getHttpChannel().getEndPoint() instanceof SslConnection.DecryptedEndPoint())
Here is an annotated and clipped stack trace showing how my handlers are wrapped into each other:
at server.HttpToHttpsRedirectRule.matchAndApply(HttpToHttpsRedirectRule.java:34)
"^^ Here I do the matchAndApply myself and then use a jetty RedirectRule.apply"
"The redirect works OK, but figuring whether it is HTTPS does not work"
at org.eclipse.jetty.rewrite.handler.RuleContainer.apply(RuleContainer.java:166)
at org.eclipse.jetty.rewrite.handler.RuleContainer.matchAndApply(RuleContainer.java:145)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:317)
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:766)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at server.LogHandler.handle(LogHandler.java:33)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
"^^^ the outermost handler"
[clip]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
"^^^ we decoded the ssl and feed the lower levels plain HTTP"
[clip]
at org.eclipse.jetty.io.ssl.SslConnection$1.run(SslConnection.java:146)
"^^^ we are in SSL"
It is in my HttpToHttpsRedirectRule
where I would like to figure out which connection it is. Is there a saner solution than the instanceof
mentioned above?
Upvotes: 1
Views: 710
Reputation: 5093
To make sure the original scheme (and possibly more) information is kept, it is necessary to add a SecureRequestCustomizer
to the http configuration like this:
HttpConfiguration httpConf = new HttpConfiguration();
httpConf.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConf);
SslConnectionFactory https = new SslConnectionFactory(sslCtxFactory, http.getProtocol());
DetectorConnectionFactory conFactory = new DetectorConnectionFactory(https);
ServerConnector connector = new ServerConnector(server, conFactory, http);
The crucial hint was found in the jetty mailing list.
Upvotes: 1