NullPointerException in AsyncNHttpClientHandler  when server sends reply before 
request is fully written.
---------------------------------------------------------------------------------------------------------

                 Key: HTTPCORE-242
                 URL: https://issues.apache.org/jira/browse/HTTPCORE-242
             Project: HttpComponents HttpCore
          Issue Type: Bug
          Components: HttpCore NIO
    Affects Versions: 4.1
         Environment: Server:  IIS/7.5 with NTLM authentication.
            Reporter: Michael Poindexter


I'm seeing a problem with AsyncNHttpClientHandler in v4.1 of HttpCore.  When I 
submit a number of requests simultaneously or a single POST with a large body 
to a server using NTLM authentication, I get this exception:

Caused by: java.lang.NullPointerException
at 
org.apache.http.nio.protocol.AsyncNHttpClientHandler.outputReady(AsyncNHttpClientHandler.java:268)
at 
org.apache.http.nio.protocol.BufferingHttpClientHandler.outputReady(BufferingHttpClientHandler.java:118)
at 
org.apache.http.impl.nio.DefaultNHttpClientConnection.produceOutput(DefaultNHttpClientConnection.java:207)
at 
org.apache.http.impl.nio.ssl.SSLClientIOEventDispatch.outputReady(SSLClientIOEventDispatch.java:245)
at 
com.qumu.cxf.rt.transport.ahttp.MultiProtocolIOEventDispatch.outputReady(MultiProtocolIOEventDispatch.java:49)
at 
org.apache.http.impl.nio.reactor.BaseIOReactor.writable(BaseIOReactor.java:185)
at 
org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:338)
at 
org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at 
org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
at 
org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at 
org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
at java.lang.Thread.run(Thread.java:680)

The server I am connecting to is IIS/7.5. I am using NTLM authentication (with 
JCIFS), so I need to keep the connection alive through several round trips as 
the NTLM message exchange occurs.

I dug into the HttpCore code, and here is my analysis of what is occurring:
1.) AsyncNHttpClientHandler.connect calls requestReady to send the initial 
request.  This sets the request on the connection, and the connection starts 
writing the request line in response to write events.
2.) The server receives the request line and responds immediately with a 401 
Unauthorized.  At this point the POST body has not been fully sent to the 
server.
3.) AsyncNHttpClientHandler.inputReady is called with the response from the 
server.  At this point processResponse is called, and my code executes.  I 
detect that the request needs authentication and I need to retransmit my 
request with an auth header, so my ConnectionReuseStrategy says to keep the 
connection alive.
4.) When control returns from my code, the code in processResponse calls 
connState.resetOutput, clearing the entity and request in connState.  There is 
still output from the POST body pending.
5.)  processResponse calls conn.requestOutput to reenable write events since 
the connection is not to be closed.
6.)  A write event happens, and DefaultNHttpClientConnection.produceOutput is 
called.  Since the output from the initial request never finished, 
contentEncoder is not null and so AsyncNHttpClientHandler.outputReady is called 
instead of requestReady.  Since connState was reset, the entity is null and 
this NPE happens.

I copied the code of AsyncNHttpClientHandler and added a conn.suspendInput() 
call in requestReady:
           if (entityReq != null && entityReq.expectContinue()) {
               .....
           } else {
           conn.suspendInput();
           }
and a conn.requestInput call in outputReady:
           entity.produceContent(encoder, conn);
           if(encoder.isCompleted()) {
           conn.requestInput();
           }
and this seemed to resolve the issue by not allowing the request and response 
to overlap, but I'm not sure this is the best way to fix it.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to