You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Fae Hutter (JIRA)" <ji...@apache.org> on 2016/03/03 10:55:18 UTC

[jira] [Created] (HTTPASYNC-103) Connections reuse does not work when using TLS client certs

Fae Hutter created HTTPASYNC-103:
------------------------------------

             Summary: Connections reuse does not work when using TLS client certs
                 Key: HTTPASYNC-103
                 URL: https://issues.apache.org/jira/browse/HTTPASYNC-103
             Project: HttpComponents HttpAsyncClient
          Issue Type: Bug
    Affects Versions: 4.1.1
            Reporter: Fae Hutter


When using TLS client certs, {{PoolingNHttpClientConnectionManager.requestConnection()}} is called with {{state=null}} but {{PoolingNHttpClientConnectionManager.releaseConnection()}} is called with {{state=X500Principal}}.

What I think it happening... {{org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection()}} has:

{code:java}
final Object userToken = this.localContext.getUserToken();
this.connmgr.requestConnection( ... userToken, ...
{code}

At this point the user token has not been set.

Then {{org.apache.http.impl.nio.client.MainClientExec.responseCompleted()}} has this which sets the user token:

{code:java}
Object userToken = localContext.getUserToken();
if (userToken == null) {
  userToken = this.userTokenHandler.getUserToken(localContext);
  localContext.setAttribute(HttpClientContext.USER_TOKEN, userToken);
}
{code}

And {{org.apache.http.impl.nio.client.AbstractClientExchangeHandler.releaseConnection()}} then with:

{code:java}
final Object userToken = this.localContext.getUserToken();
this.connmgr.releaseConnection(localConn, userToken, validDuration, TimeUnit.MILLISECONDS);
{code}

And because the state does not match, the call to {{releaseConnection()}} has no effect.

There is an assertion for this at {{org.apache.http.nio.pool.RouteSpecificPool.free()}}, but the assertion is never called because {{org.apache.http.nio.pool.AbstractNIOConnPool.release()}} first checks the response of:

{code:java}
if (this.leased.remove(entry)) { ...
{code}

And there is no else statement.

In case this is useful for anyone else, for now I have worked around the issue using this:

{code:java}
/**
 * This is a hackaround for connections not being release (and thus not reused) when using TLS client certs.
 * The problem is that the connection is requested with state==null but released with state==javax.security.auth.x500.X500Principal.
 * Since our use case does not require the state value to be none null, enforce that assumption and override it when releasing connections.
 */
private static class MyPoolingNHttpClientConnectionManager extends PoolingNHttpClientConnectionManager {

    public MyPoolingNHttpClientConnectionManager(final ConnectingIOReactor ioreactor, final NHttpConnectionFactory<ManagedNHttpClientConnection> connFactory,
            final Registry<SchemeIOSessionStrategy> iosessionFactoryRegistry, final DnsResolver dnsResolver) {
        super(ioreactor, connFactory, iosessionFactoryRegistry, dnsResolver);
    }

    @Override
    public Future<NHttpClientConnection> requestConnection(final HttpRoute route, final Object state, final long connectTimeout, final long leaseTimeout, final TimeUnit tunit,
            final FutureCallback<NHttpClientConnection> callback) {
        if (state != null) throw new UnsupportedOperationException("Requesting connections with state!=null is not supported by this work around.");
        new Exception().printStackTrace();
        return super.requestConnection(route, state, connectTimeout, leaseTimeout, tunit, callback);
    }

    @Override
    public void releaseConnection(final NHttpClientConnection managedConn, final Object state, final long keepalive, final TimeUnit tunit) {
        new Exception().printStackTrace();
        super.releaseConnection(managedConn, null, keepalive, tunit); // XXX Deliberately replace state with null.
    }

}
{code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org