Get full URL and request string in Servlet for HTTP and HTTPS requests

I am writing code whose task is to obtain the requested URL or the full path. I wrote this code:

HttpServletRequest request;//obtained from other functions String uri = request.getRequestURI(); if (request.getQueryString() != null) uri += "?" + request.getQueryString(); 

So when I browse http://google.com?q=abc , this is normal (correct). But there is a problem when I browse https://google.com . The uri value is http://google.com:443google.com:443 , so the program is used not only when using HTTPS .

And the result will be the same for request.getRequestURL().toString() .

What solution?

+52
java servlets
May 21 '13 at 16:41
source share
3 answers

By design, getRequestURL() you get the full URL, not just the query string.

In the HttpServletRequest you can get the individual parts of the URI using the following methods:

 // Example: http://myhost:8080/people?lastname=Fox&age=30 String uri = request.getScheme() + "://" + // "http" + ":// request.getServerName() + // "myhost" ":" + // ":" request.getServerPort() + // "8080" request.getRequestURI() + // "/people" "?" + // "?" request.getQueryString(); // "lastname=Fox&age=30" 
  • .getScheme() will give you "https" if it was a https://domain request.
  • .getServerName() gives domain to http(s)://domain .
  • .getServerPort() will provide you with a port.

Use the snippet below:

 String uri = request.getScheme() + "://" + request.getServerName() + ("http".equals(request.getScheme()) && request.getServerPort() == 80 || "https".equals(request.getScheme()) && request.getServerPort() == 443 ? "" : ":" + request.getServerPort() ) + request.getRequestURI() + (request.getQueryString() != null ? "?" + request.getQueryString() : ""); 

This snippet above will get the full URI, hiding the port, if used by default, and not add "?" and a query string if the latter was not provided.


Proxied Requests

Please note that if your request passes through a proxy server, you need to look at the X-Forwarded-Proto header, as the scheme can be changed:

 request.getHeader("X-Forwarded-Proto") 

Also, a generic X-Forwarded-For header that shows the source IP address of the request instead of proxys-IP.

 request.getHeader("X-Forwarded-For") 

If you yourself are responsible for the proxy configuration / load balancing, you need to make sure that these headers are configured during forwarding.

+121
May 21 '13 at 16:52
source

Just use:

 String Uri = request.getRequestURL()+"?"+request.getQueryString(); 
+5
Dec 19 '15 at 11:35
source

The fact that an HTTPS request becomes HTTP when you try to create a server-side URL indicates that you may have a proxy / load balancer ( nginx , pound , etc.), offloading SSL encryption front and back to your back in plain HTTP .

If in this case, check

  • Is your proxy server configured correctly for forward headers ( Host , X-forwarded-proto , X-forwarded-for , etc.).
  • Is your service container (such as Tomcat ) installed for front-end proxy recognition? For example, Tomcat requires adding the attributes secure="true" scheme="https" proxyPort="443" to its Connector
  • Whether your code or service container handles correctly. For example, Tomcat automatically replaces the values โ€‹โ€‹of scheme , remoteAddr , etc., when you add RemoteIpValve to your Engine . (see the Setup Guide , JavaDoc ), so you do not need to manually process these headers in your code.

An incorrect proxy header value can lead to incorrect output if request.getRequestURI() or request.getRequestURL() tries to create a source URL.

0
Oct 05 '17 at 23:39 on
source



All Articles