On Fri, 2013-08-09 at 15:16 -0700, Erik Pilz wrote:
> We're migrating an old application from Java's HttpsUrlConnection to
> HttpClient. After running a performance test we found a high cost around
> connection acquisition. A bit of debugging later led me to find that we're
> not getting the full benefit of pooled connections. What I eventually found
> is that I have to create a HttpClientContext and populate the userToken
> with some object and use HttpClient#execute(method, context). This wasn't
> obvious to me; is this intentional or did I just find a workaround to a bug?

...

> Calling HttpClient#execute(method) will create a context whose userToken is
> null. To work around the behavior it's instead necessary to create an
> HttpClientContext and populate it with a userToken of your own (it can be
> any object); this will then be used as the state in the available
> connections instead of the principal from the SSLSession; you then use
> HttpClient#execute(method, context) in place of HttpClient#execute(method).
> 
> Thanks,
> Erik

Hi Erik

This is by design and not a defect.

Mutually authenticated SSL connections are considered state-full and
special measures are taken to make sure they cannot be leased to a
consumer with a different security context. Their state is represented
by a user token, which is by default the security principal of the
client certificate.

There are two ways you could resolve the issue

(1) Disable connection state management if your application does not
need to maintain a different security context per worker thread 

---
CloseableHttpClient client = HttpClients.custom()
    .disableConnectionState()
    .build();
---

(2) Simply make related requests share the same context (recommended).
In this case SSL security principal of the initial request will be added
to the execution context as a user token and propagated to all
subsequent requests. When leasing a persistent connection from the
connection pool HttpClient will use the user token to request a
connection with a specific state / security context.

---
CloseableHttpClient client = HttpClients.custom()
        .build();
HttpClientContext context = HttpClientContext.create();
HttpGet get1 = new HttpGet("https://myhost/this";);
CloseableHttpResponse response1 = client.execute(get1, context);
try {

} finally {
    response1.close();
}
HttpGet get2 = new HttpGet("https://myhost/that";);
CloseableHttpResponse response2 = client.execute(get2, context);
try {

} finally {
    response1.close();
}
---

Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to