2

I have a Spring boot app running on Tomcat. I have to resolve each ip to its Geolocation : city , province and Country . However,sometimes I receive ip address as a comma separated String instead of a single ip address. For example , 1.39.27.224, 8.37.225.221 . The code to extract ip from a Http request that I am using :

public static String getIp(final HttpServletRequest request) {
    PreConditions.checkNull(request, "request cannot be null");
    String ip = request.getHeader("X-FORWARDED-FOR");
    if (!StringUtils.hasText(ip)) {
        ip = request.getRemoteAddr();
    }
    return ip;
}
Ankush92
  • 401
  • 1
  • 9
  • 20

2 Answers2

4

The X-Forwarded-For can be used to identify the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.

The general format of this field is

X-Forwarded-For: client, proxy1, proxy2

In above example you can see that the request is passed through proxy1 and proxy2.

In your case you should parse this comma separated string and read the first value which is client's IP address.

Warning - It is easy to forge an X-Forwarded-For field so you might get wrong information.

Please take a look at https://en.wikipedia.org/wiki/X-Forwarded-For to read more about this.

Rashid
  • 78
  • 7
0

Here is what I use in my servlet (running on Jetty behind HAProxy) -

I just try to get the first IP address in the X-Forwarded-For header:

Pattern FIRST_IP_ADDRESS = Pattern.compile("^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})");

public static String parseXff(HttpServletRequest httpReq) {
    String xff = httpReq.getHeader("X-Forwarded-For");
    if (xff != null) {
        Matcher matcher = FIRST_IP_ADDRESS.matcher(xff);
        if (matcher.find()) {
            return matcher.group(1);
        }
    }

    // return localhost when servlet is accessed directly, without HAProxy
    return "127.0.0.1";
}
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416