Question

How can I add "Connection: Keep-Alive" and "Keep-Alive: timeout=x, max=y" headers to a response using Apache HttpComponents ONLY if the connection is going to be persistent?

If HttpComponents decides this connection won't be persistent, it adds a "Connection: close" header after I give the response to it. I don't want a Keep-Alive header in this case.

Why I'm doing this:

Standard behavior is for HttpComponents to change nothing in the response for a persistent connection, and add "Connection: close" for non-persistent connections. This works well in most cases.

I want to have a Keep-Alive header because clients based on the standard java.net.HttpURLConnection will time out and throw away connections after 5 seconds of inactivity unless there is a Keep-Alive header in the previous response from the server. I want to use Keep-Alive to define a longer timeout than 5 seconds.

Was it helpful?

Solution

You can add HttpResponseInterceptor, which adds "Connection: Keep-Alive" and "Keep-Alive: timeout=x, max=y" headers to a response depending on the evaluation from org.apache.http.protocol.ResponseConnControl, which set "Connection: close" header, when needed.

class ResposeKeepAliveHeaderMod implements HttpResponseInterceptor {

    @Override
    public void process(HttpResponse response, HttpContext context)
            throws HttpException, IOException {
        final Header explicit = response.getFirstHeader(HTTP.CONN_DIRECTIVE);
        if (explicit != null && HTTP.CONN_CLOSE.equalsIgnoreCase(explicit.getValue())) {
            // Connection persistence explicitly disabled
            return;
        }else{
            // "Connection: Keep-Alive" and "Keep-Alive: timeout=x, max=y" 
            response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE);
            response.setHeader(HTTP.CONN_KEEP_ALIVE, "timeout=30, max=100");
        }

    }      
   }

You need to add this to HttpProcessor, after ResponseConnControl:

HttpProcessor httpProcessor = HttpProcessorBuilder.create()
            //.addFirst(new RequestTrace())
            .add(new ResponseDate())
            //.add(new ResponseServer("MyServer-HTTP/1.1"))
            .add(new ResponseContent())
            .add(new ResponseConnControl())
            .addLast(new ResposeKeepAliveHeaderMod())
            .build();

Then build the server:

final HttpServer server = ServerBootstrap.bootstrap()
            .setListenerPort(9090)
            .setHttpProcessor(httpProcessor)
            .setSocketConfig(socketConfig)
            .setExceptionLogger(new StdErrorExceptionLogger ())
            .setHandlerMapper(handle_map)
            .create();

OTHER TIPS

I haven't tried this, but it seems you can code a custom 'ConnectionKeepAliveStrategy' for your httpCleint. Here is documentation HttpComponents Custom stratagey

Refer section 2.11

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top