7

The following code is returning incorrectly, from what I understand:

HttpServletRequest httpRequest = (HttpServletRequest) request;
String userIPAddress = httpRequest.getRemoteAddr();

// Actual
// "0:0:0:0:0:0:0:1%0"

// Expected
// "0:0:0:0:0:0:0:1"

Any idea why the %0 is there? When I loop through

InetAddress.getAllByName("localhost")

I get the following:

// ["192.168.100.1", "127.0.0.1", "0:0:0:0:0:0:1"]

How would I test for localhost if getRemoteAddr() is returning invalid format, or am I doing something wrong?

Thanks!

andrewpthorp
  • 4,998
  • 8
  • 35
  • 56

2 Answers2

6

The problem is these two functions

1) java.net.InetAddress.getAllByName(String)

and

2) javax.servlet.ServletRequest.getRemoteAddr()

Are very different. The first function is part of the standard Java runtime and the second is implemented by your Java EE container. You are using Tomcat7 so the optional zone parameter %0 is being added.

Bottom line, you should not be doing string comparison on ip addresses like you are.

What you should really be doing is using the org.apache.catalina.filters.RemoteIpFilter. This does what you are trying to do in a well defined way.

Example:

<filter>
   <filter-name>RemoteIpFilter</filter-name>
   <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
   <init-param>
     <param-name>allowedInternalProxies</param-name>
     <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value>
   </init-param>
   <init-param>
     <param-name>remoteIpHeader</param-name>
     <param-value>x-forwarded-for</param-value>
   </init-param>
   <init-param>
     <param-name>remoteIpProxiesHeader</param-name>
     <param-value>x-forwarded-by</param-value>
   </init-param>
   <init-param>
     <param-name>protocolHeader</param-name>
     <param-value>x-forwarded-proto</param-value>
   </init-param>
 </filter>

See http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#Remote_IP_Filter for more info.

Nicholas DiPiazza
  • 10,029
  • 11
  • 83
  • 152
3

0:0:0:0:0:0:0:1%0 is a valid long form for the IPv6 localhost. The %0 specifies the optional zone index.

Here is more information about IPv6 Zone Indices.

I do not know why a call to httpRequest.getRemoteAddr(); is returning the optional zone index of %0, and

InetAddress.getAllByName("localhost") 

does not. However, my recommendation is that if you are looking to match on localhost, you match on both patterns, or do a startsWith match.

Bhushan
  • 18,329
  • 31
  • 104
  • 137
Philip Tenn
  • 6,003
  • 8
  • 48
  • 85
  • That's good to know, and it is odd that they are returning different results. I don't, however, want to check for inclusion or startsWith. Too many weird situations : 192.168.100.1 > 192.168.100.12, etc – andrewpthorp Aug 22 '12 at 20:30
  • 1
    Documentation for InetAddress says "may include scope index", so no joy that way... http://download.java.net/jdk7/archive/b123/docs/api/java/net/InetAddress.html#getAllByName%28java.lang.String%29 – Alfabravo Aug 22 '12 at 20:56
  • I guess I was a bit vague when I mentioned "match on both patterns or do a startsWith match". Please allow me to clarify. Your question specifically mentioned not being able to match because of the trailing `%0`. For matching the IPv6 address, you should ignore the optional zone index and just match on `0:0:0:0:0:0:0:1`. This optional zone index is going to be OS-dependent. For example, on Linux your IPv6 loopback could be `0:0:0:0:0:0:0:1%eth0` and on Windows it could be `0:0:0:0:0:0:0:1%0` – Philip Tenn Aug 22 '12 at 20:58