How to report remote IP from NHttpRequestHandler using Apache httpcomponents?

I am using the Apache http component of the Apache http component with comets (deferred response). My code is very similar to the example "Basic non-blocking HTTP server" at http://hc.apache.org/httpcomponents-core-ga/examples.html

I use DefaultServerIOEventDispatch and DefaultListeningIOReactor to send requests, as in the code example. Inside my NHttpRequestHandler, I would like to record the IP address of each request.

Inside the HttpRequestHandler you have access to HttpRequest, HttpResponse and HttpContext. With the NHttpRequestHandler, you also have the NHttpResponseTrigger. How to get the remote IP address from which the request came? I do not see how to do this with accessible objects.

Refresh , here is the Scala code in which I ended up:

def getIp(context: HttpContext): Option[String] = {
  val conn = context.getAttribute(ExecutionContext.HTTP_CONNECTION)

  conn match {
    case inet: HttpInetConnection =>
      inet.getRemoteAddress match {
        case sock: java.net.InetSocketAddress => // HttpComponents 4.1
          Some(sock.getAddress.getHostAddress)
        case adr: java.net.InetAddress => // HttpComponents 4.2
          Some(adr.getHostAddress)
        case unknown =>
          Some(unknown.toString)
      }
    case _ => None
  }
}

As you can see, there is an extra step in HttpComponents 4.1.

+3
source share
2 answers

You can use the type NHttpConnectionfor the instance HttpInetConnectionand call the method HttpInetConnection#getRemoteAddressto get the IP address of the opposite endpoint. The connection object can be obtained from the instance HttpContextpassed as a parameter, c HttpRequestHandler. Alternatively, you may need to implement an interface EventListenerif you want to separate the connection life cycle event log from the protocol processing logic.

Contrib HttpCore, HttpCore - :

http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/httpcore-contrib/src/main/java/org/apache/http/contrib/logging/

+1

, , , - .

httpcore-nio 4.1, . , (, , ). 4.2.1 . . 403 Forbidden, localhost.

HttpCore NIO 4.2

@Override
public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) {
    HttpInetConnection connection = (HttpInetConnection) context.getAttribute(ExecutionContext.HTTP_CONNECTION);
    InetAddress ia = connection.getRemoteAddress();
    if("localhost".equals(ia.getHostName()) {
        response.setStatusCode(HttpStatus.SC_FORBIDDEN);
        return;
    }
    ...
}

HttpCore NIO 4.1

: . 4.1, 4.2.x. , .

httpcore-nio 4.1, , , , (iosession) (HttpContext).

@Override
public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) {
    try {
        Field f = context.getClass().getDeclaredField("iosession");
        boolean accessible = f.isAccessible();
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        int modifiers = f.getModifiers();
        modifiersField.setAccessible(true);
        modifiersField.set(f, f.getModifiers() & ~Modifier.FINAL & ~Modifier.PRIVATE);
        f.setAccessible(true);
        IOSession io = (IOSession) f.get(context);
        f.setAccessible(accessible);
        modifiersField.set(f, modifiers);
        SocketAddress sa = io.getRemoteAddress();
        if("localhost".equals(((InetSocketAddress) sa).getHostName())) {
            response.setStatusCode(HttpStatus.SC_FORBIDDEN);
            return;
        }
    } catch (Exception e) {
        logger.error("No way! I can't believe this fantastic piece of code threw an exception!", e);
    } 
    ...
}
+4

All Articles