摘要:而后发现原先部署在这两个应用之前的反向代理的协议从原来的改成了,但是这两个应用的并没有跟着升级成而依旧是。经过进一步跟踪请求发现并不是所有请求都出现异常,而只有的地方出现问题,而的时候并没有使用协议,而依然是。
问题描述
今天遇到一个奇怪的现象,原先部署在外网访问的应用某些功能出现了异常错误,用chrome开发者工具调试后发现一个奇怪的错误:
意思基本上就是当前页面是https协议加载的,但是这个页面发起了一个http的ajax请求,这种做法是非法的。
现象进一步分析后发现以下三个现象:
在排查代码之后并没有发现代码里有任何写死使用http协议的地方,而后又发现另一个应用也出现了这个情况,两个应用使用的框架分别是struts2和spring,这个问题似乎和框架无关。
而后发现原先部署在这两个应用之前的反向代理的协议从原来的http改成了https,但是这两个应用的tomcat并没有跟着升级成https而依旧是http。
经过进一步跟踪请求发现并不是所有请求都出现异常,而只有redirect的地方出现问题,而redirect的时候并没有使用https协议,而依然是http。
推论结合上面三个现象推论:
这个问题和框架无关
是tomcat和反向代理协议不一致造成的
问题出在redirect上
分析看javax.servlet.http.HttpServletResponse#sendRedirect的javadoc是这么说的:
Sends a temporary redirect response to the client using the specified redirect location URL. This method can accept relative URLs; the servlet container must convert the relative URL to an absolute URL before sending the response to the client. If the location is relative without a leading "/" the container interprets it as relative to the current request URI. If the location is relative with a leading "/" the container interprets it as relative to the servlet container root.
If the response has already been committed, this method throws an IllegalStateException. After using this method, the response should be considered to be committed and should not be written to.
也就是说servlet容器在sendRedirect的时候是需要将传入的url参数转换成绝对地址的,而这个绝对地址是包含协议的。
而后翻阅tomcat源码,发现org.apache.catalina.connector.Response#toAbsolute和绝对地址转换有关:
protected String toAbsolute(String location) { if (location == null) { return (location); } boolean leadingSlash = location.startsWith("/"); if (location.startsWith("//")) { // Scheme relative redirectURLCC.recycle(); // Add the scheme String scheme = request.getScheme(); try { redirectURLCC.append(scheme, 0, scheme.length()); redirectURLCC.append(":"); redirectURLCC.append(location, 0, location.length()); return redirectURLCC.toString(); } catch (IOException e) { IllegalArgumentException iae = new IllegalArgumentException(location); iae.initCause(e); throw iae; }
注意到request.getScheme()这个调用,那么问题来了,这个值是什么时候设置的?
在一番google之后发现了类似的问题,回答推荐使用org.apache.catalina.valves.RemoteIpValve来解决这个问题,查找tomcat发现了Remote IP Valve的protocolHeader属性的似乎可以解决此问题,进一步在翻看源代码之后发现这么一段跟确认了我的猜测:
public void invoke(Request request, Response response) throws IOException, ServletException { //... if (protocolHeader != null) { String protocolHeaderValue = request.getHeader(protocolHeader); if (protocolHeaderValue == null) { // don"t modify the secure,scheme and serverPort attributes // of the request } else if (protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue)) { request.setSecure(true); // use request.coyoteRequest.scheme instead of request.setScheme() because request.setScheme() is no-op in Tomcat 6.0 request.getCoyoteRequest().scheme().setString("https"); setPorts(request, httpsServerPort); } else { request.setSecure(false); // use request.coyoteRequest.scheme instead of request.setScheme() because request.setScheme() is no-op in Tomcat 6.0 request.getCoyoteRequest().scheme().setString("http"); setPorts(request, httpServerPort); } } //.... }解决办法
在反向代理那里设置一个头X-Forwarded-Proto,值设置成https。
在tomcat的server.xml里添加这段配置:
如此一来sendRedirect的时候就能够正确的使用协议了。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/65017.html
摘要:近日发现一个问题应用程序在返回的时候丢失了原先访问的端口。于是怀疑问题出在这几个上。在中,在描述的时候提到,其返回的必须是。修改的端口为靠谱这个方法比较靠谱,只要将的端口改成就没有问题了。使用靠谱使用提供的,将的值做文本替换。 github 近日发现一个问题:应用程序在返回Http Redirect的时候丢失了原先访问的端口。比如,我们这样访问http://IP-A:Port-A/ap...
摘要:近日发现一个问题应用程序在返回的时候丢失了原先访问的端口。于是怀疑问题出在这几个上。在中,在描述的时候提到,其返回的必须是。修改的端口为靠谱这个方法比较靠谱,只要将的端口改成就没有问题了。使用靠谱使用提供的,将的值做文本替换。 github 近日发现一个问题:应用程序在返回Http Redirect的时候丢失了原先访问的端口。比如,我们这样访问http://IP-A:Port-A/ap...
摘要:传给微信的参数进行转义其中参数是可以被微信原样返回,这样就可以按你自己的需求完成反向代理了。可以去掉搭建测试环境另一条运维的原则是不要在生产环境上直接改,在测试环境修改并经过测试,测试通过后,再上传到生产环境。 前言 在与第三方系统进行接口开发时,需要不断的改进和测试,以常见的微信登录支付和 Alipay 支付和登录为例. 相对来讲 Alipay 做起来容易一些, 一是接口 SDK 封...
摘要:由于上面我们已经新建了一个配置文件,这里就直接将反向代理的配置写在里面通过配置,我们反向代理到了端口的服务。六最后本文中,我们学习了如何通过快速搭建环境,并对其配置证书和反向代理,让网站能够以协议来访问。 欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习、面试资源哟!!个人网站: https://www.except...
阅读 2695·2023-04-25 21:26
阅读 1513·2021-11-25 09:43
阅读 1948·2019-08-30 15:52
阅读 930·2019-08-30 14:05
阅读 2614·2019-08-29 16:10
阅读 414·2019-08-29 13:48
阅读 1859·2019-08-29 12:47
阅读 1299·2019-08-23 18:04