内置Jetty HTTPS启动使用request.getScheme()总是返回http问题解决方案

6 篇文章 0 订阅
5 篇文章 0 订阅

现象:

        不论是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啊。

这个原理还没搞懂,以后有时间再研究。谁知道的告诉我下,万分感谢!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值