Transferred from: http://feitianbenyue.iteye.com/blog/2056357
Recently in a project, the structure of the use of Nginx +tomcat cluster, and nginx configuration of Ssl,tomcat no SSL, the project uses the HTTPS protocol
However, obviously is the HTTPS URL request, found log inside,
XML code
- 0428 15:55:55 INFO (paymentinterceptor.java:44) prehandle ()-Requeststringforlog: {
- "Request.getrequesturl ():": "Http://trade.feilong.com/payment/paymentChannel?" id=212&s=a84485e0985afe97fffd7fd7741c93851d83a4f6 ",
- "Request.getmethod:": "GET",
- "_parametermap": {
- "id": ["212"],
- "S": ["A84485e0985afe97fffd7fd7741c93851d83a4f6"]
- }
- }
The Request.getrequesturl () output is always
/ httpTrade.feilong.com/payment/paymentchannel?id=212&s=a84485e0985afe97fffd7fd7741c93851d83a4f6 but the URL in the browser is
https://Trade.feilong.com/payment/paymentchannel?id=212&s=a84485e0985afe97fffd7fd7741c93851d83a4f6
An instant to subvert my view of Java, the API is clearly written:
Getrequesturl ():
Java code
- Reconstructs the URL the client used to make the request.
- The returned URL contains a protocol, server name, port number, and server path,
- But it does not include query string parameters.
That is, Getrequesturl () outputs a path with no query string (with information such as protocol, port, server path, and so on).
and also found that
XML code
- Request.getscheme ()//always HTTP, not actual HTTP or HTTPS
- Request.issecure ()//Always False (because always HTTP)
- REQUEST.GETREMOTEADDR ()//Always nginx request IP, not user's IP
- Request.getrequesturl ()//is always the URL of the Nginx request instead of the URL actually requested by the user
- Response.sendredirect (relative URL)//always redirects to HTTP (because it is considered to be an HTTP request)
Read some information and found a solution:
The solution is simple, just need to configure Nginx and Tomcat separately, instead of changing the program.
Configure the Nginx forwarding options:
XML code
- Proxy_set_header Host $host;
- Proxy_set_header X-real-ip $remote _addr;
- Proxy_set_header x-forwarded-for $proxy _add_x_forwarded_for;
- Proxy_set_header X-forwarded-proto $scheme;
Proxy_set_header X-forwarded-proto $scheme;
Configure a Valve under the Engine module of the Tomcat Server.xml:
XML code
- <Valve classname="Org.apache.catalina.valves.RemoteIpValve"
- remoteipheader="X-forwarded-for"
- protocolheader="X-forwarded-proto"
- protocolheaderhttpsvalue="https"/>
The X-forwarded-proto is configured to correctly identify whether the actual user is sending an HTTP or HTTPS protocol.
All 5 of these tests are turned into the correct results, just as the user accesses Tomcat directly.
About Remoteipvalve, interested students can read the next doc
Http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html
XML code
- Tomcat Port of MOD_REMOTEIP, this valve replaces the apparent client remote IP address and hostname for the request with T He IP address List presented by a proxy or a load balancer via a request headers (e.g. "x-forwarded-for").
- Another feature of this valve are to replace the apparent scheme (HTTP/HTTPS) and server ports with the scheme presented by A proxy or a load balancer via a request header (e.g. "X-forwarded-proto").
Look at their source code, relatively simple, in various frameworks, various algorithms before, this class has a small impact on performance
- If you do not configure the Protocolheader property, do nothing.
- If Protocolheader is configured, but the value Request.getheader (Protocolheader) is null, nothing is done
- If Protocolheader is configured, but the value (ignoring case) of Request.getheader (Protocolheader) is configured protocolheaderhttpsvalue (default HTTPS), Scheme is set to HTTPS with Port set to Httpsserverport
- Other settings are HTTP
Java code
- if (protocolheader! = null) {
- String Protocolheadervalue = Request.getheader (Protocolheader);
- if (protocolheadervalue = = null) {
- //don ' t modify the Secure,scheme and ServerPort attributes
- //The request
- } Else if (protocolheaderhttpsvalue.equalsignorecase (Protocolheadervalue)) {
- Request.setsecure (true);
- //Use Request.coyoteRequest.scheme instead of Request.setscheme () because Request.setscheme () are no-op in Tomcat 6.0
- Request.getcoyoterequest (). Scheme (). setString ("https");
- Request.setserverport (Httpsserverport);
- } Else {
- Request.setsecure (false);
- //Use Request.coyoteRequest.scheme instead of Request.setscheme () because Request.setscheme () are no-op in Tomcat 6.0
- Request.getcoyoterequest (). Scheme (). setString ("http");
- Request.setserverport (Httpserverport);
- }
- }
Reference:
SSL certificate and HTTPS application deployment summary
http://han.guokai.blog.163.com/blog/static/136718271201211631456811/
Nginx ssl+tomcat cluster, request.getscheme () take HTTPS to the correct protocol