过程:
浏览器——》代理——–》真实应用服务器
浏览器发送请求给代理,代理发送请求给应用服务器,代理将应用服务器返回的内容返回给浏览器。
情景再现:
在有代理的情况下,request.getServerName(),并不能得到真正代理服务器的地址,如果nginx没有配置 proxy_set_header Host $Host,那么得到的地址是127:0.0.1,为什么呢?
原因分析:
通过查看Tomcat的源码得知,request首先会判断http heder中的host,如果没有,那么就获取本机的ip地址,因为代理服务器没在发送给真实服务器的header中,没有配置host,所以得到的是127.0.0.1,而如果将代理发送给应用服务器请求header中把host配置成代理服务器自身的ip地址,就可以得到代理服务器的ip地址。
源码分析的具体过程:
因为项目使用的是maven,所以查看源码比较方便
ServletRequest—–HttpServletRequestImpl——HttpServerExchange
以下是servlet3.0的源码:
/**
* Return the host that this request was sent to, in general this will be the
* value of the Host header, minus the port specifier.
* <p/>
* If this resolves to an IPv6 address it will not be enclosed by square brackets.
* Care must be taken when constructing URLs based on this method to ensure IPv6 URLs
* are handled correctly.
*
* @return The host part of the destination address
*/
public String getHostName() {
String host = requestHeaders.getFirst(Headers.HOST);
if (host == null) {
host = getDestinationAddress().getAddress().getHostAddress();
} else {
if (host.startsWith("[")) {
host = host.substring(1, host.indexOf(']'));
} else if (host.indexOf(':') != -1) {
host = host.substring(0, host.indexOf(':'));
}
}
return host;
}
解决方案
nginx中配置proxy_set_header Host $Host
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/1231.html