user3892260
user3892260

Reputation: 1035

Adding a filter to find out remote IP address of requester using JdkHttpServerFactory

Is there any way to get the remote IP address while sticking to the JdkHttpServerFactory framework?

I have a very light RESTful server which uses JdkHttpServerFactory to create a server, essentially with one line of code:

JdkHttpServerFactory.createHttpServer(baseUri, config);

My dependencies are:

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.23.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-jdk-http</artifactId>
            <version>2.23.2</version>
        </dependency>

It appears it is not trivial to add a filter to this framework. I have tried it by bringing in HttpServletRequest but this means I need to bring in the servlet framework, and this actually didn't work for me with JdkHttpServerFactory, I end up getting null as my request.

I found another suggestion, but that suggestion also meant switching over to using Grizly2, which agains means I have to abandon the simple/light JdkHttpServerFactory method.

Upvotes: 1

Views: 357

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 209052

The only way I can see to access the IP is through the HttpExchange. Unfortunately, this is not something that is exposed to us. You can either make a feature request to expose the IP or you can just modify it yourself and build your own artifact. In either case, the change I would suggest making is to just add a property in to the ContainerRequest, that you could pull out in your filter.

If you look here in the source code, you will see the ContainerRequest. I would just do something like

final ContainerRequest requestContext = new ContainerRequest(baseUri, requestUri,
                exchange.getRequestMethod(), getSecurityContext(exchange.getPrincipal(), isSecure),
                new MapPropertiesDelegate());
requestContext.setProperty(JdkServerProperties.REMOTE_IP_ADDR, exchange.getRemoteAddr());

Then in your ContainerRequestFilter, you can just do

@Override
public void filter(ContainerRequestContext requestContext) {
    // ContainerRequest implements ContainerRequestContext
    InetSockAddress remoteAddr = (InetSocketAddress) requestContext.getProperty(JdkServerProperties.REMOTE_IP_ADDR);
}

Yeah, so if I were to make a feature/pull request or just build my own artifact, this is probably the change I would make. Or if you don't want to expose the InetSocketAddress, you can just build the IP string and add that as the property value.

Upvotes: 1

Related Questions