[prev in list] [next in list] [prev in thread] [next in thread] 

List:       httpclient-commons-dev
Subject:    [jira] [Updated] (HTTPASYNC-143) Connection closed randomly during NTLM authorization
From:       "Isa Muqattash (JIRA)" <jira () apache ! org>
Date:       2018-08-17 15:40:00
Message-ID: JIRA.13179610.1534520240000.104473.1534520400081 () Atlassian ! JIRA
[Download RAW message or body]


     [ https://issues.apache.org/jira/browse/HTTPASYNC-143?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel \
]

Isa Muqattash updated HTTPASYNC-143:
------------------------------------
    Description: 
Recently switched from the (synchronous) HttpClient to HttpAsyncClient, and I'm  \
dealing with a  HTTP 401 error returned from an HTTP POST that involves NTLM \
authentication.

The issue sporadically occurs, more frequently with HttpAsyncClient 4.1.3, and still \
occurs in 4.1.4 but less frequently.

  The HTTP POST request incorrectly includes a "Content-Type: Application/JSON" \
header and the body is a ZIP file binary, and removing that header seems to make the \
issue go away, or at least I cannot reproduce the random behavior when the head is \
not specified. However, all this worked fine with the synchronous HttpClient and it \
will be difficult to go to many many applications and remove that additional header, \
which I'm not sure why it would cause this issue described here.

I enabled context and wire logs, and what I'm seeing is that the three-step NTLM \
handshake takes place. When the issue does not reproduce, all three steps occur on \
the same connection. But when the issue reproduces, the context and wire logs show \
that the connection is closed between each of the three steps.

Furthermore, I looked into this for several days and the issue reproduces more \
frequently with some zip binaries rather than other. The same zip file sometimes \
succeeds but other times fails.

Perhaps there is some JSON parsing taking place that randomly causes issues and \
causes the connection to be closed? (I'm just rambling now but just trying to give as \
much info as possible...)

Sample success and failure handshake logs attached.

Source code I'm using is as follows (stripped down):

  
{code:java}
val httpclientB = HttpAsyncClients.custom().setRedirectStrategy(new \
LaxRedirectStrategy() {  override def createLocationURI(location: String): URI = {
      super.createLocationURI(location)
}

override def isRedirected(req: HttpRequest, resp: HttpResponse, ctxt: HttpContext): \
Boolean = {  super.isRedirected(req, resp, ctxt)
} 

override def getRedirect(req: HttpRequest, resp: HttpResponse, ctxt: HttpContext): \
HttpUriRequest = {  val x = super.getRedirect(req, resp, ctxt)
   if (x.containsHeader("Content-Length")) {
      x.removeHeaders("Content-Length")
   }
   x
}
})

val credsProvider = new BasicCredentialsProvider()
credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("foo", "bar", "baz", \
"domain")) httpclientB.setDefaultCredentialsProvider(credsProvider)

val httpClient = httpclientB.useSystemProperties().build()
httpClient.start()
val future = httpClient.execute(httpRequest, null)
future.get(Long.MaxValue, TimeUnit.MILLISECONDS))
{code}
  

  

  was:
Recently switched from the (synchronous) HttpClient to HttpAsyncClient, and I'm  \
dealing with a  HTTP 401 error returned from an HTTP POST that involves NTLM \
authentication.

The issue sporadically occurs, more frequently with HttpAsyncClient 4.1.3, and still \
occurs in 4.1.4 but less frequently.

  

The HTTP POST request incorrectly includes a "Content-Type: Application/JSON" header \
and the body is a ZIP file binary, and removing that header seems to make the issue \
go away, or at least I cannot reproduce the random behavior when the head is not \
specified. However, all this worked fine with the synchronous HttpClient and it will \
be difficult to go to many many applications and remove that additional header, which \
I'm not sure why it would cause this issue described here.

  

  

I enabled context and wire logs, and what I'm seeing is that the three-step NTLM \
handshake takes place. When the issue does not reproduce, all three steps occur on \
the same connection. But when the issue reproduces, the context and wire logs show \
that the connection is closed between each of the three steps.

  

Furthermore, I looked into this for several days and the issue reproduces more \
frequently with some zip binaries rather than other. The same zip file sometimes \
succeeds but other times fails.

  

Perhaps there is some JSON parsing taking place that randomly causes issues and \
causes the connection to be closed? (I'm just rambling now but just trying to give as \
much info as possible...)

  

Sample success and failure handshake logs attached.

  

Source code I'm using is as follows (stripped down):

  
{code:java}
val httpclientB = HttpAsyncClients.custom().setRedirectStrategy(new \
LaxRedirectStrategy() {  override def createLocationURI(location: String): URI = {
      super.createLocationURI(location)
}

override def isRedirected(req: HttpRequest, resp: HttpResponse, ctxt: HttpContext): \
Boolean = {  super.isRedirected(req, resp, ctxt)
} 

override def getRedirect(req: HttpRequest, resp: HttpResponse, ctxt: HttpContext): \
HttpUriRequest = {  val x = super.getRedirect(req, resp, ctxt)
   if (x.containsHeader("Content-Length")) {
      x.removeHeaders("Content-Length")
   }
   x
}
})

val credsProvider = new BasicCredentialsProvider()
credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("foo", "bar", "baz", \
"domain")) httpclientB.setDefaultCredentialsProvider(credsProvider)

val httpClient = httpclientB.useSystemProperties().build()
httpClient.start()
val future = httpClient.execute(httpRequest, null)
future.get(Long.MaxValue, TimeUnit.MILLISECONDS))
{code}
  

  


> Connection closed randomly during NTLM authorization
> ----------------------------------------------------
> 
> Key: HTTPASYNC-143
> URL: https://issues.apache.org/jira/browse/HTTPASYNC-143
> Project: HttpComponents HttpAsyncClient
> Issue Type: Bug
> Affects Versions: 4.1.4
> Reporter: Isa Muqattash
> Priority: Major
> Attachments: asyncHttpClient_failed.log, asyncHttpClient_success.log
> 
> 
> Recently switched from the (synchronous) HttpClient to HttpAsyncClient, and I'm  \
> dealing with a  HTTP 401 error returned from an HTTP POST that involves NTLM \
> authentication. The issue sporadically occurs, more frequently with HttpAsyncClient \
> 4.1.3, and still occurs in 4.1.4 but less frequently. The HTTP POST request \
> incorrectly includes a "Content-Type: Application/JSON" header and the body is a \
> ZIP file binary, and removing that header seems to make the issue go away, or at \
> least I cannot reproduce the random behavior when the head is not specified. \
> However, all this worked fine with the synchronous HttpClient and it will be \
> difficult to go to many many applications and remove that additional header, which \
> I'm not sure why it would cause this issue described here. I enabled context and \
> wire logs, and what I'm seeing is that the three-step NTLM handshake takes place. \
> When the issue does not reproduce, all three steps occur on the same connection. \
> But when the issue reproduces, the context and wire logs show that the connection \
> is closed between each of the three steps. Furthermore, I looked into this for \
> several days and the issue reproduces more frequently with some zip binaries rather \
> than other. The same zip file sometimes succeeds but other times fails. Perhaps \
> there is some JSON parsing taking place that randomly causes issues and causes the \
> connection to be closed? (I'm just rambling now but just trying to give as much \
> info as possible...) Sample success and failure handshake logs attached.
> Source code I'm using is as follows (stripped down):
> 
> {code:java}
> val httpclientB = HttpAsyncClients.custom().setRedirectStrategy(new \
> LaxRedirectStrategy() { override def createLocationURI(location: String): URI = {
> super.createLocationURI(location)
> }
> override def isRedirected(req: HttpRequest, resp: HttpResponse, ctxt: HttpContext): \
> Boolean = { super.isRedirected(req, resp, ctxt)
> } 
> override def getRedirect(req: HttpRequest, resp: HttpResponse, ctxt: HttpContext): \
> HttpUriRequest = { val x = super.getRedirect(req, resp, ctxt)
> if (x.containsHeader("Content-Length")) {
> x.removeHeaders("Content-Length")
> }
> x
> }
> })
> val credsProvider = new BasicCredentialsProvider()
> credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("foo", "bar", "baz", \
> "domain")) httpclientB.setDefaultCredentialsProvider(credsProvider)
> val httpClient = httpclientB.useSystemProperties().build()
> httpClient.start()
> val future = httpClient.execute(httpRequest, null)
> future.get(Long.MaxValue, TimeUnit.MILLISECONDS))
> {code}
> 
> 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic