问题描述
从 Jetty 9.4 开始。?可以在同一端口上运行 HTTP 和 HTTPs。 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);
由于我只想提供 HTTPS,因此我想将每个 http://host:port/stuff
重定向到 https://host:port/stuff
。我知道如何使用 RedirectRule
的子类或仅使用名为 early 的处理程序进行重定向。
我遇到的问题是:我如何从请求中确定连接是 HTTP 而不是 HTTPS?
当我在调试器中查看 Request
时,没有发现任何提示,一切看起来都好像是 http 即使连接是 https,Request.isSecure()
都是假的,方案是 http
等等。我能想到的最好的事情是:
if (Request.getHttpChannel().getEndPoint() instanceof SslConnection.DecryptedEndPoint())
这是一个带注释和剪辑的堆栈跟踪,显示了我的处理程序如何相互包装:
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"
在我的 HttpToHttpsRedirectRule
中,我想弄清楚它是哪个连接。有没有比上面提到的 instanceof
更明智的解决方案?
解决方法
为了确保保留原始方案(可能还有更多)信息,有必要在 http 配置中添加一个 SecureRequestCustomizer
,如下所示:
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);
找到关键提示in the jetty mailing list。