You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Michael Poindexter <mp...@qumu.com> on 2010/11/20 04:48:17 UTC

Possible Bug With HttpCore-NIO 4.1

I'm seeing a problem with AsyncNHttpClientHandler in v4.1 of HttpCore.  When I submit a number of requests simultaneously (anything > 12 seems to trigger it for me), 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)

Some details about my code/environment:  Each request is submitted on it's own connection.  The requests are all POSTs.  I am using SSL, and I cannot seem to reproduce this over plain HTTP.  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.

Is my analysis correct?  If so, is there a better way to fix this?

Mike Poindexter


Re: Possible Bug With HttpCore-NIO 4.1

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Fri, 2010-11-19 at 19:48 -0800, Michael Poindexter wrote:
> I'm seeing a problem with AsyncNHttpClientHandler in v4.1 of HttpCore.  When I submit a number of requests simultaneously (anything > 12 seems to trigger it for me), 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)
> 
> Some details about my code/environment:  Each request is submitted on it's own connection.  The requests are all POSTs.  I am using SSL, and I cannot seem to reproduce this over plain HTTP.  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.
> 
> Is my analysis correct?  If so, is there a better way to fix this?
> 
> Mike Poindexter
> 

Hi Mike

Thank you very much for such a thorough and detailed analysis. Please
raise a JIRA for this defect

https://issues.apache.org/jira/browse/HTTPCORE

Would it also be a big deal for you to put together a small test app
that can be used to reproduce the problem?

Cheers

Oleg


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