现象:
不论是http还是https访问时,通过request.getScheme()获取的值都是http。
环境:
内置Jetty启动项目
同时启动http与https访问。内置Jetty HTTPS启动
jetty版本:9.4.9.v20180320
由于最近升级了https服务。导致系统原来的重定向功能出现了问题。
之前如果用户未登录,会重新定向到登录页面,登录成功后返回原页面。用户登录后重定向到原来访问页面
inv.getController().redirect("/xpl/admin/login"+"?toUrl=" + toUrl);
但是使用https后,发现了一个新问题,上面默认重定向时总是使用http协议,导致重定向失败,提示:
Mixed Content: The page at 'https://localhost:9443/xpl/admin/main' was loaded over HTTPS, but requested an insecure resource 'http://localhost:9443/xpl/admin/login?toUrl=%2Fxpl%2Fadmin%2Fuser'. This request has been blocked; the content must be served over HTTPS.
而使用request.getScheme()又无法获取到正确的协议名称。
这个问题纠结了很久,昨天网上搜了很久的资料也没找到相关资料。
今天研究了一整天的jetty源码。终于找到获取到正确协议方法了。
具体过程就不详细描述了。直接给出解决方案吧:
第一步,定义下面函数获取Scheme。
/***
* 获取请求协议
* @return http 或者 https 或者 null
*/
public static String getScheme(){
if(HttpConnection.getCurrentConnection() == null){
return null;
}
return HttpConnection.getCurrentConnection().getHttpConfiguration().getSecureScheme();
}
用户请求时,jetty会把创建的HttpConnection绑定到本地线程。
通过HttpConnection获取对应的HttpConfiguration,然后获取到SecureScheme。
第二步,启动jetty时,配置正确的HttpConfiguration。
由于HttpConfiguration的构造函数默认创建的SecureScheme值是https。
server = new Server( port );
替换为:
server = new Server();
HttpConfiguration.setSecureScheme(HttpScheme.HTTP.asString());
ServerConnector connector=new ServerConnector(server,null,null,null,-1,-1,new HttpConnectionFactory(HttpConfiguration));
connector.setPort( port );
server.setConnectors(new Connector[]{connector});
第三步,重定向时路径加上协议名称。
/***
* 获取协议,域名,端口号
* @param request
* @return 例如:http://f0rb.iteye.com:8080/
*/
public static String getDomain(HttpServletRequest request){
StringBuffer url = request.getRequestURL();
String domain = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
if("https".equals(getScheme())){
domain = domain.replace("http", "https");
}
return domain;
}
inv.getController().redirect(domain + "xpl/admin/login?toUrl=" + toUrl);
打完收工。
PS:改完后发现http和https是共用session的。https登录后,使用http就可以不用登录,继续访问了。
这个我一直认为http和https是属于跨域的,应该不是同一个session啊。
这个原理还没搞懂,以后有时间再研究。谁知道的告诉我下,万分感谢!