hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Oleg Kalnichevski (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (HTTPASYNC-110) Proxy reuses a fully established routed authenticated connection in attempt to CONNECT to target again causing 400 and NPE
Date Mon, 15 Aug 2016 18:50:20 GMT

    [ https://issues.apache.org/jira/browse/HTTPASYNC-110?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15421471#comment-15421471
] 

Oleg Kalnichevski commented on HTTPASYNC-110:
---------------------------------------------

Andrey
Could you please try this patch and let me know if that solves the problem for you?
https://github.com/ok2c/httpasyncclient/commit/d3147df1add179389881b9f117b3d995f27a0752

Oleg

> Proxy reuses a fully established routed authenticated connection in attempt to CONNECT
to target again causing 400 and NPE
> --------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HTTPASYNC-110
>                 URL: https://issues.apache.org/jira/browse/HTTPASYNC-110
>             Project: HttpComponents HttpAsyncClient
>          Issue Type: Bug
>            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);
>   static final String ORIGINAL_USER_TOKEN = "ORIGINAL_USER_TOKEN";
>   @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
(v6.3.4#6332)

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


Mime
View raw message