All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xiongyingqi.common.utils.ip.RemoteIpUtils Maven / Gradle / Ivy

The newest version!
package com.xiongyingqi.common.utils.ip;

import com.xiongyingqi.common.utils.string.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

/**
 * @author xiongyingqi
 * @since 17-5-11 下午9:23
 */
public abstract class RemoteIpUtils {
  private static final Logger logger = LoggerFactory.getLogger(RemoteIpUtils.class);

  public static final String LOW_CASE_X_FORWARD = "x-forwarded-for";
  private static String lastHeaderNameOfXForwardFor = null;
  public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
  public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");

  public static String longToIpV4(long longIp) {
    int octet3 = (int) ((longIp >> 24) % 256);
    int octet2 = (int) ((longIp >> 16) % 256);
    int octet1 = (int) ((longIp >> 8) % 256);
    int octet0 = (int) ((longIp) % 256);
    return octet3 + "." + octet2 + "." + octet1 + "." + octet0;
  }

  public static long ipV4ToLong(String ip) {
    String[] octets = ip.split("\\.");
    return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) +
        (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);
  }

  public static boolean isIPv4Private(String ip) {
    long longIp = ipV4ToLong(ip);
    return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255")) ||
        (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255")) ||
        longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255");
  }

  public static boolean isIPv4Valid(String ip) {
    return pattern.matcher(ip).matches();
  }

  public static String getIpFromRequest(HttpServletRequest request) {
    if (request == null) {
      return null;
    }
    String ip;
    boolean found = false;
    if (logger.isDebugEnabled()) {
      logHeader(request);
    }
    String headerNameOfXForwardFor = getHeaderNameOfXForwardFor(request);
    if ((ip = request.getHeader(headerNameOfXForwardFor)) != null) {
      logger.debug("Found x-forwarded-for ip: {}", ip);
      StringTokenizer tokenizer = new StringTokenizer(ip, ",");
      while (tokenizer.hasMoreElements()) {
        ip = tokenizer.nextToken().trim();
        if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
          found = true;
          break;
        }
      }
    }
    if (!found) {
      ip = request.getRemoteAddr();
    }
    logger.info("Found remote ip: {}; Is from x-forwarded-for? {}", ip, found);
    return ip;
  }

  protected static String getHeaderNameOfXForwardFor(HttpServletRequest request) {
    if (lastHeaderNameOfXForwardFor != null && StringUtils.hasText(request.getHeader(lastHeaderNameOfXForwardFor))) {
      return lastHeaderNameOfXForwardFor;
    }
    for (Enumeration headerNames = request.getHeaderNames(); headerNames
        .hasMoreElements(); ) {
      String headerName = (String) headerNames.nextElement();
      if (LOW_CASE_X_FORWARD.equalsIgnoreCase(headerName)) {
        lastHeaderNameOfXForwardFor = headerName;
        return headerName;
      }
    }
    return LOW_CASE_X_FORWARD;
  }

  private static void logHeader(HttpServletRequest httpServletRequest) {
    for (Enumeration headerNames = httpServletRequest.getHeaderNames(); headerNames
        .hasMoreElements(); ) {
      String headerName = (String) headerNames.nextElement();
      Enumeration headers = httpServletRequest.getHeaders(headerName);
      logger.debug("Header: {}={}", headerName, Collections.list(headers));
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy