hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Becke <be...@u.washington.edu>
Subject Re: SocketException with invalid server
Date Fri, 20 Jun 2003 01:41:17 GMT
Adrian,

I'm looking into to this and I agree it is quite strange.  The part I  
don't understand is why the second attempt to write to the socket  
fails. The socket is not being closed on the HttpClient side until  
after the failure occurs.  Any thoughts on how the connection is being  
closed?

Mike

On Thursday, June 19, 2003, at 08:50 PM, Adrian Sutton wrote:

> Howdy all,
> I'm having some trouble pinpointing the exact cause of an exception  
> I'm getting from HttpClient, it seems to be related to connection  
> management with MultiThreadedConnectionManager so I thought I'd draw  
> on the expertise here. :)
>
> Essentially, we have an invalid HTTP server (Stellent CMS actually and  
> we will file a bug with them), which is returning headers like:
>
> HTTP/1.1 401 Unauthorized
> WWW-Authenticate: Basic "Secure Realm"
> Connection: keep-alive
>
> Which is clearly missing the Content-Length header.  Now, previously  
> HttpClient handled this perfectly by reading until the end of the  
> connection (ie: treating it like it was a Connection: close), however  
> for some reason a socket exception is being thrown and the invalid  
> connection is added back into the connection pool and then every  
> connection to the server after that thows an exception.
>
> I haven't been able to work out a good way to create a test case for  
> this yet, but I can provide a simple set of steps to reproduce:
>
> 1. Get something like netcat which will let you "pretend" to be a HTTP  
> server (ie: it will listen on a port and send back whatever you type)
>
> 2. Start it listening on port 8080 (for netcat use: nc -l -p 8080)
>
> 3.  Compile the program below and run it.
>
> 4. Enter the following into you netcat window (followed by a blank  
> line to indicate the end of the headers):
>
> HTTP/1.1 401 Unauthorized
> WWW-Authenticate: Basic "realm"
> Connection: keep-alive
>
> You'll see HttpClient throws an exception (listed below the code).   
> Note that netcat did not close the connection, HttpClient did.  Also,  
> note that it doesn't make any difference if you set netcat up to  
> immediately start listening for another connection after the  
> connection is closed (ie: netcat -l -p 8080 && netcat -l -p 8080).
>
> It looks like HttpClient is closing the connection but not telling  
> itself that the connection is closed so it then tries to reuse the  
> connection and fails.  The same thing happens if you perform two GET  
> requests and the server returns 200 OK with connection: keep-alive but  
> no content length to the first request.
>
> Any help tracking down this would be greatly appreciated, even if it's  
> just a hint as to where to start making changes. :)
>
> CODE: -------------------------
> import org.apache.commons.httpclient.*;
> import org.apache.commons.httpclient.methods.*;
> import org.apache.commons.httpclient.contrib.ssl.*;
> import org.apache.commons.httpclient.protocol.*;
>
>
> public class Test {
>
>     public static void main(String[] args) throws Exception {
>         //String url =  
> "https://basil/stellent/groups/secure/documents/adsales/> testimage.jpg";
>         String url = "http://localhost:8080/test.gif";
>         HttpClient client = new HttpClient(new  
> MultiThreadedHttpConnectionManager());
>         client.getState().setCredentials(null, null, new  
> UsernamePasswordCredentials("sysadmin", "idc"));
>         GetMethod get = new GetMethod(url);
>         int result = client.executeMethod(get);
>         System.err.println("Result: " + result);
>         System.err.println(get.getResponseBody());
>     }
> }
> ----------------------------------
> Resulting exception:
> Exception in thread "main" java.net.SocketException: Socket closed
>         at  
> java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:99)
>         at  
> java.net.SocketOutputStream.write(SocketOutputStream.java:136)
>         at  
> org.apache.commons.httpclient.HttpConnection$WrappedOutputStream.write( 
> HttpConnection.java:1347)
>         at  
> java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:69)
>         at  
> java.io.BufferedOutputStream.flush(BufferedOutputStream.java:127)
>         at  
> org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(H 
> ttpConnection.java:782)
>         at  
> org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpCo 
> nnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionMan 
> ager.java:1046)
>         at  
> org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBas 
> e.java:2174)
>         at  
> org.apache.commons.httpclient.HttpMethodBase.processRequest(HttpMethodB 
> ase.java:2529)
>         at  
> org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.jav 
> a:1066)
>         at  
> org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java: 
> 638)
>         at  
> org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java: 
> 500)
>         at Test.main(Test.java:15)
>
>
> The wire trace is:
>
> [DEBUG] HttpClient - -Java version: 1.4.1_01
> [DEBUG] HttpClient - -Java vendor: Apple Computer, Inc.
> [DEBUG] HttpClient - -Java class path:  
> commons-httpclient-2.0-beta1.jar:commons-logging-1.0.2.jar:.
> [DEBUG] HttpClient - -Operating system name: Mac OS X
> [DEBUG] HttpClient - -Operating system architecture: ppc
> [DEBUG] HttpClient - -Operating system version: 10.2.6
> [DEBUG] HttpClient - -SUN 1.2: SUN (DSA key/parameter generation; DSA  
> signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS  
> keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP,  
> Collection CertStores)
> [DEBUG] HttpClient - -SunJSSE 1.41: Sun JSSE provider(implements RSA  
> Signatures, PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)
> [DEBUG] HttpClient - -SunRsaSign 1.0: SUN's provider for RSA signatures
> [DEBUG] HttpClient - -SunJCE 1.4: SunJCE Provider (implements DES,  
> Triple DES, Blowfish, PBE, Diffie-Hellman, HMAC-MD5, HMAC-SHA1)
> [DEBUG] HttpClient - -SunJGSS 1.0: Sun (Kerberos v5)
> [DEBUG] MultiThreadedHttpConnectionManager -  
> -HttpConnectionManager.getConnection:  config =  
> org.apache.commons.httpclient.HostConfiguration@b8332793, timeout = 0
> [DEBUG] HttpConnection - -Creating connection for localhost using  
> protocol http:80
> [DEBUG] HttpConnection - -Creating connection for localhost using  
> protocol http:80
> [DEBUG] HttpConnection - -HttpConnection.setSoTimeout(0)
> [DEBUG] HttpMethod - -Execute loop try 1
> [DEBUG] wire - ->> "GET /test.gif HTTP/1.1[\r][\n]"
> [DEBUG] HttpMethod - -Adding Host request header
> [DEBUG] wire - ->> "User-Agent: Jakarta  
> Commons-HttpClient/2.0beta1[\r][\n]"
> [DEBUG] wire - ->> "Host: localhost:8080[\r][\n]"
> [DEBUG] wire - ->> "[\r][\n]"
> [DEBUG] wire - -<< "HTTP/1.1 401 Unauthorized[\r][\n]"
> [DEBUG] wire - -<< "WWW-Authenticate: Basic "realm"[\r][\n]"
> [DEBUG] wire - -<< "Connection: keep-alive[\r][\n]"
> [DEBUG] HttpMethod - -Authorization required
> [DEBUG] HttpAuthenticator - -Using 'localhost:8080' authentication  
> realm
> [DEBUG] HttpMethod - -HttpMethodBase.execute(): Server demanded  
> authentication credentials, will try again.
> [DEBUG] HttpMethod - -Should NOT close connection in response to  
> Connection: keep-alive
>
> [DEBUG] HttpMethod - -Execute loop try 2
> [DEBUG] wire - ->> "GET /test.gif HTTP/1.1[\r][\n]"
> [DEBUG] HttpMethod - -Request to add Host header ignored: header  
> already added
> [DEBUG] wire - ->> "User-Agent: Jakarta  
> Commons-HttpClient/2.0beta1[\r][\n]"
> [DEBUG] wire - ->> "Host: localhost:8080[\r][\n]"
> [DEBUG] wire - ->> "Authorization: Basic c3lzYWRtaW46aWRj[\r][\n]"
> [DEBUG] MultiThreadedHttpConnectionManager - -Freeing connection:  
> org.apache.commons.httpclient.HttpConnection@5718f2
> [DEBUG] MultiThreadedHttpConnectionManager - -Notifying no-one, there  
> are no waiting threads
> Exception in thread "main" java.net.SocketException: Socket closed
>         at  
> java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:99)
>         at  
> java.net.SocketOutputStream.write(SocketOutputStream.java:136)
>         at  
> org.apache.commons.httpclient.HttpConnection$WrappedOutputStream.write( 
> HttpConnection.java:1347)
>         at  
> java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:69)
>         at  
> java.io.BufferedOutputStream.flush(BufferedOutputStream.java:127)
>         at  
> org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(H 
> ttpConnection.java:782)
>         at  
> org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpCo 
> nnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionMan 
> ager.java:1046)
>         at  
> org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBas 
> e.java:2174)
>         at  
> org.apache.commons.httpclient.HttpMethodBase.processRequest(HttpMethodB 
> ase.java:2529)
>         at  
> org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.jav 
> a:1066)
>         at  
> org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java: 
> 638)
>         at  
> org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java: 
> 500)
>         at Test.main(Test.java:15)
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:  
> commons-httpclient-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail:  
> commons-httpclient-dev-help@jakarta.apache.org
>


Mime
View raw message