Return-Path: Delivered-To: apmail-hc-dev-archive@www.apache.org Received: (qmail 28515 invoked from network); 22 Nov 2010 17:14:10 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 22 Nov 2010 17:14:10 -0000 Received: (qmail 74105 invoked by uid 500); 22 Nov 2010 17:14:41 -0000 Delivered-To: apmail-hc-dev-archive@hc.apache.org Received: (qmail 74057 invoked by uid 500); 22 Nov 2010 17:14:41 -0000 Mailing-List: contact dev-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list dev@hc.apache.org Received: (qmail 74049 invoked by uid 99); 22 Nov 2010 17:14:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 Nov 2010 17:14:40 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.22] (HELO thor.apache.org) (140.211.11.22) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 Nov 2010 17:14:38 +0000 Received: from thor (localhost [127.0.0.1]) by thor.apache.org (8.13.8+Sun/8.13.8) with ESMTP id oAMHEGg8016519 for ; Mon, 22 Nov 2010 17:14:16 GMT Message-ID: <30011613.236151290446056440.JavaMail.jira@thor> Date: Mon, 22 Nov 2010 12:14:16 -0500 (EST) From: "Michael Poindexter (JIRA)" To: dev@hc.apache.org Subject: [jira] Commented: (HTTPCORE-242) NullPointerException in AsyncNHttpClientHandler when server sends reply before request is fully written. In-Reply-To: <30384907.217361290293533632.JavaMail.jira@thor> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 X-Virus-Checked: Checked by ClamAV on apache.org [ https://issues.apache.org/jira/browse/HTTPCORE-242?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12934514#action_12934514 ] Michael Poindexter commented on HTTPCORE-242: --------------------------------------------- I agree, the behavior is pretty broken, but I think the idea is for the client to terminate the connection if the server responds early and then retry authentication on a new connection. I think given this option (1) is quite reasonable. I have actually already changed my code to both close the connection after it gets a 401 no matter what the Connection header says and clear out the entity on any HttpEntityEnclosingRequest's that transmitted are part of the NTLM handshake (so the Content-Length = 0 and this error does not happen). As long as the AsyncNHttpClient closes the connection instead of throwing a NPE and causing the IOReactor to fall over from my point of view the client is working correctly. Ideally detecting this would not result in an IOException, but rather just a silent close of the connection so that in my code I can test if the connection is closed before deciding to reuse it. > 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 > Attachments: httcore-quickresponse.pcap, HTTPCORE-242.patch, httpcore-connection-reuse-bug-fixed2.zip, httpcore.log > > > 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: dev-unsubscribe@hc.apache.org For additional commands, e-mail: dev-help@hc.apache.org