hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Andrey K (JIRA)" <j...@apache.org>
Subject [jira] [Comment Edited] (HTTPCLIENT-1762) Proxy reuses a fully established routed authenticated connection in attempt to CONNECT to target again causing 400 and NPE
Date Sun, 14 Aug 2016 18:40:20 GMT

    [ https://issues.apache.org/jira/browse/HTTPCLIENT-1762?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15420435#comment-15420435

Andrey K edited comment on HTTPCLIENT-1762 at 8/14/16 6:39 PM:

somewhat obfuscated log of a session with multiple requests with some of them failing - sending
CONNECT over existing connections due to ambiguity in the pool - see attachment

was (Author: andreyka):
somewhat obfuscated log of a session with multiple requests with some of them failing - sending
CONNECT over existing connections due to ambiguity in the pool

> Proxy reuses a fully established routed authenticated connection in attempt to CONNECT
to target again causing 400 and NPE
> --------------------------------------------------------------------------------------------------------------------------
>                 Key: HTTPCLIENT-1762
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1762
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpClient
>            Reporter: Andrey K
>         Attachments: buglog.txt
> First I noticed I was getting sporadic errors when attempting to make an HTTPS call via
HTTP Proxy that requires authentication:
> java.lang.IllegalArgumentException: Auth scheme may not be null
> 	at org.apache.http.util.Args.notNull(Args.java:54)
> 	at org.apache.http.impl.client.AuthenticationStrategyImpl.authSucceeded(AuthenticationStrategyImpl.java:215)
> 	at org.apache.http.impl.client.ProxyAuthenticationStrategy.authSucceeded(ProxyAuthenticationStrategy.java:43)
> 	at org.apache.http.impl.auth.HttpAuthenticator.isAuthenticationRequested(HttpAuthenticator.java:88)
> 	at org.apache.http.impl.nio.client.MainClientExec.needAuthentication(MainClientExec.java:629)
> 	at org.apache.http.impl.nio.client.MainClientExec.handleResponse(MainClientExec.java:569)
> 	at org.apache.http.impl.nio.client.MainClientExec.responseReceived(MainClientExec.java:309)
> 	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseReceived(DefaultClientExchangeHandlerImpl.java:147)
> 	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.responseReceived(HttpAsyncRequestExecutor.java:303)
> 	at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:255)
> 	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81)
> 	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39)
> 	at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:121)
> 	at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
> 	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
> 	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
> 	at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
> 	at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
> 	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588)
> Upon closer look with trace debug, I saw that it was breaking on an unexpected 400 status
code coming back against a CONNECT+AUTH request. When I traced the connection that was used
for this connect, I saw that it was a fully connected routed connection. What happened was
the HttpClient got a 407 after attempting to do a CONNECT and that 407 contained instruction
to close connection. HttpClient discarded the connection and obtained a new one from the pool
but the one that was leased was already fully authenticated and tunneled. Thus the CONNECT
request was sent to the actual tunneled target and returned with a 400.
> As a workaround I have enhanced a custom ProxyAuthenticationStrategy to rename the USER_TOKEN
context value to a temporary unique value to prevent reusing a fully established connection
and then revert it back after authentication is sucessful:
>   static AtomicLong counter = new AtomicLong(0);
>   @Override
>   public Map<String, Header> getChallenges(HttpHost authhost, HttpResponse response,
HttpContext context) throws MalformedChallengeException {
>     String originalUserToken = (String)context.getAttribute(ORIGINAL_USER_TOKEN);
>     if (originalUserToken == null) {
>       originalUserToken = (String)context.getAttribute(HttpClientContext.USER_TOKEN);
>       context.setAttribute(ORIGINAL_USER_TOKEN, originalUserToken);
>       String temporaryName = "NON-REUSABLE-" + counter.incrementAndGet();
>       context.setAttribute(HttpClientContext.USER_TOKEN, temporaryName);
>       log.trace("OnAuth: Renaming connection from {} to {}", originalUserToken, temporaryName);
>     }
>     return super.getChallenges(authhost, response, context);
>   }
>   @Override
>   public void authSucceeded(HttpHost authhost, AuthScheme authScheme, HttpContext context)
>     String originalUserToken = (String)context.getAttribute(ORIGINAL_USER_TOKEN);
>     if (originalUserToken != null) {
>       String tempUserToken = (String)context.getAttribute(HttpClientContext.USER_TOKEN);
>       context.setAttribute(HttpClientContext.USER_TOKEN, originalUserToken);
>       context.removeAttribute(ORIGINAL_USER_TOKEN);
>       log.trace("OnAuthSucc: Renaming connection from {} to {}", tempUserToken, originalUserToken);
>     }
>     super.authSucceeded(authhost, authScheme, context);
>   }

This message was sent by Atlassian JIRA

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

View raw message