eclipse-ee4j / eclipse-ee4j/jersey

Jersey OAuth 2 leaking connections with ApacheHTTPClient / PoolingHttpClientConnectionManager

Open
#4,763 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
730
Forks
382
PR merge metrics
No merged PRs in 30d

Description

Using:
- org.glassfish.jersey.jersey-server and org.glassfish.jersey.jersey-client 2.30.1
- org.glassfish.jersey.security.jersey.security.oauth2-client 2.30.1
- org.glassfish.jersey.connectors.jersey-apache-connector 2.30.1
- org.apache.httpcomponents.httpcomponents-client 4.5.9

I am setting up the ClientBuilder for the OAuth2-client as follows, and note that I have to stretch the value of setDefaultMaxPerRoute so our application does not lock up regularly:

ClientConfig loConfig = new ClientConfig();
moHttpClientConnectionMgr = new PoolingHttpClientConnectionManager();
moHttpClientConnectionMgr.setMaxTotal( 500 );
moHttpClientConnectionMgr.setDefaultMaxPerRoute( 500 );
moHttpClientConnectionMgr.setValidateAfterInactivity( 1000 );

loConfig.property( ApacheClientProperties.CONNECTION_MANAGER, moHttpClientConnectionMgr );
loConfig.connectorProvider( new ApacheConnectorProvider() );
// For some reason, the Microsoft Azure OAuth server does not support CHUNKED requests, which
// is the default for ApacheHttpClient (apparently).
loConfig.property(
ClientProperties.REQUEST_ENTITY_PROCESSING,
RequestEntityProcessing.BUFFERED );
if( msOutboundProxyUri != null && msOutboundProxyUri.trim().length() > 0 )
{
// set up outbound proxy, if configured
loConfig.property( ClientProperties.PROXY_URI, msOutboundProxyUri );
}

ClientBuilder loBuilder = ClientBuilder.newBuilder().withConfig( loConfig );

I suspect the following code in org/glassfish/jersey/client/oauth2/AuthCodeGrantImpl.java in the finish() method causes a connection to leak and not have the connection returned to the pool whenever the OAuth-provider returns any HTTP status other than 200, because the response is never actually consumed:

final Response response = client.target(accessTokenUri)
.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));

if (response.getStatus() != 200) {
throw new ProcessingException(LocalizationMessages.ERROR_FLOW_REQUEST_ACCESS_TOKEN(response.getStatus()));
}
this.tokenResult = response.readEntity(TokenResult.class);
return tokenResult;

The same code is present in refreshAccessToken().

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.