摘要:而后發現原先部署在這兩個應用之前的反向代理的協議從原來的改成了,但是這兩個應用的并沒有跟著升級成而依舊是。經過進一步跟蹤請求發現并不是所有請求都出現異常,而只有的地方出現問題,而的時候并沒有使用協議,而依然是。
問題描述
今天遇到一個奇怪的現象,原先部署在外網訪問的應用某些功能出現了異常錯誤,用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("http://")) { // 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的時候就能夠正確的使用協議了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/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...
閱讀 2696·2023-04-25 21:26
閱讀 1514·2021-11-25 09:43
閱讀 1949·2019-08-30 15:52
閱讀 932·2019-08-30 14:05
閱讀 2614·2019-08-29 16:10
閱讀 414·2019-08-29 13:48
閱讀 1860·2019-08-29 12:47
閱讀 1299·2019-08-23 18:04