Hi,

We can add the header to the custom valves, but then in addition we have to
change a few log file configurations, create a servlet filter and maybe
something else I cant think of now. Basically doing the same thing a few
times and keeping track of all the places that depend on the header. Ideally
this would all be corrected once in the beginning of the request processing
pipeline, so log file configuration, other valves and the war files will
remain unchanged.

 

Attached a Valve that does that. This is the minimum code necessary, so it
should not have any significant performance impact. 

Feel free to use as is, not guaranteed to work, no expressed on implied
warranties, not FDIC insured and may loose value.

 

To configure Tomcat add to server.xml:

 

<Service name="Catalina">

      <Connector port="8080" .../> 

      <Engine defaultHost="localhost" name="Catalina">

            <!-- This should precede all other configuration in the engine
-->

            <Valve className="org.apache.catalina.connector.RemoteIPValve"/>

 

Java class/jar should be placed in /server/lib or /server/classes

 

E

 

 

 

package org.apache.catalina.connector;

 

import java.io.IOException;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

import javax.servlet.ServletException;

 

import org.apache.catalina.connector.Request;

import org.apache.catalina.connector.Response;

import org.apache.catalina.valves.ValveBase;

 

/**

 * A valve that extracts the remote IP of the client from an HTTP header
field

 * passed by the proxy, and set it in the request as the original client IP.

 * This valve should be the first valve in the engine, so log valves (and

 * others) will see the real client IP without requiring the same code
again.

 * 

 * @author Elli Albek, www.sustainlane.com

 */

public class RemoteIPValve extends ValveBase {

 

      private static final Pattern ipExpr =
Pattern.compile("^[\\da-fA-F]+(\\.[\\da-fA-F]+)+");

 

      private String forwardedForHeader = "X-Forwarded-For";

 

      public void invoke(Request request, Response response) throws
IOException, ServletException {

 

            String header = request.getHeader(forwardedForHeader);

            String forwardedIP = getFirstIP(header);

            if (forwardedIP != null)

                  request.remoteAddr = forwardedIP;

 

            next.invoke(request, response);

      }

 

      /**

       * Return the first IP address in a string that may contain an IP list

       */

      static final String getFirstIP(String header) {

            if (header == null)

                  return null;

            Matcher m = ipExpr.matcher(header);

            if (m.find()) {

                  return m.group();

            }

            return null;

      }

 

      public void setForwardedForHeader(String forwardedForHeader) {

            this.forwardedForHeader = forwardedForHeader;

      }

 

      public String getInfo() {

            return "RemoteIPValve";

      }

}

Reply via email to