Index: src/java/org/apache/commons/httpclient/HttpMethodBase.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v retrieving revision 1.152 diff -u -u -r1.152 HttpMethodBase.java --- src/java/org/apache/commons/httpclient/HttpMethodBase.java 13 Jun 2003 21:32:17 -0000 1.152 +++ src/java/org/apache/commons/httpclient/HttpMethodBase.java 20 Jun 2003 08:57:03 -0000 @@ -229,6 +229,9 @@ /** true if we are finished with the connection */ private boolean doneWithConnection = false; + + /** true if the connection is using chunked encoding. */ + private boolean usingChunkedEncoding = false; /** Number of milliseconds to wait for 100-contunue response */ private static final int RESPONSE_WAIT_TIME_MS = 3000; @@ -900,6 +903,10 @@ } return true; } else if (connectionHeader.getValue().equalsIgnoreCase("keep-alive")) { + if (!usingChunkedEncoding && getResponseContentLength() < 0) { + LOG.debug("Should close connection as content-length is missing."); + return true; + } if (LOG.isDebugEnabled()) { LOG.debug("Should NOT close connection in response to " + connectionHeader.toExternalForm()); @@ -1981,6 +1988,7 @@ // RFC2616, 4.4 item number 3 if (transferEncodingHeader != null) { if ("chunked".equalsIgnoreCase(transferEncodingHeader.getValue())) { + usingChunkedEncoding = true; // Some HTTP servers do not bother sending a closing chunk // if response body is empty if (conn.isResponseAvailable(conn.getSoTimeout())) { Index: src/test/org/apache/commons/httpclient/TestResponseHeaders.java =================================================================== RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestResponseHeaders.java,v retrieving revision 1.7 diff -u -u -r1.7 TestResponseHeaders.java --- src/test/org/apache/commons/httpclient/TestResponseHeaders.java 10 Jun 2003 22:42:52 -0000 1.7 +++ src/test/org/apache/commons/httpclient/TestResponseHeaders.java 20 Jun 2003 08:57:18 -0000 @@ -127,6 +127,21 @@ assertEquals("Wed, 28 Mar 2001 05:05:04 GMT", method.getResponseHeader("Date").getValue()); assertEquals("UserLand Frontier/7.0-WinNT", method.getResponseHeader("Server").getValue()); } + + public void testChunkedEncoding() throws Exception { + String body = "0\r\n"; + SimpleHttpConnection conn = new SimpleHttpConnection(); + String headers = + "HTTP/1.1 200 OK\r\n" + + "Connection: keep-alive\r\n" + + "Transfer-Encoding: chunked\r\n"; + conn.addResponse(headers, body); + GetMethod method = new GetMethod("/"); + method.execute(new HttpState(), conn); + method.getResponseBodyAsString(); + + assertTrue(conn.isOpen()); + } /** * Tests that having a duplicate content length causes no problems. @@ -153,6 +168,7 @@ "HTTP/1.1 200 OK\r\n" + "proxy-connection: close\r\n" + "proxy-connection: close\r\n" + + "Content-Length: 0\r\n" + "\r\n"; conn.addResponse(headers, ""); @@ -169,6 +185,7 @@ "HTTP/1.0 200 OK\r\n" + "proxy-connection: keep-alive\r\n" + "proxy-connection: keep-alive\r\n" + + "Content-Length: 0\r\n" + "\r\n"; conn.addResponse(headers, ""); @@ -202,6 +219,7 @@ "HTTP/1.0 200 OK\r\n" +"Connection: keep-alive\r\n" +"Connection: keep-alive\r\n" + +"Content-Length: 0\r\n" +"\r\n"; conn.addResponse(headers, ""); @@ -210,6 +228,39 @@ method.getResponseBodyAsString(); assertTrue(conn.isOpen()); + } + + public void testNoContentLength() throws Exception { + SimpleHttpConnection conn = new SimpleHttpConnection(); + String headers = + "HTTP/1.1 200 OK\r\n" + + "Connection: keep-alive\r\n" + + "\r\n"; + + conn.addResponse(headers, "12345"); + GetMethod method = new GetMethod("/"); + method.execute(new HttpState(), conn); + method.getResponseBodyAsString(); + + assertFalse(conn.isOpen()); + } + + public void testProxyNoContentLength() throws Exception { + SimpleHttpConnection conn = new SimpleHttpConnection(); + String headers = + "HTTP/1.1 200 OK\r\n" + + "proxy-connection: keep-alive\r\n" + + "\r\n"; + + conn.addResponse(headers, "12345"); + conn.setProxyHost("proxy"); + conn.setProxyPort(1); + GetMethod method = new GetMethod("/"); + method.execute(new HttpState(), conn); + method.getResponseBodyAsString(); + + boolean isOpen = conn.isOpen(); + assertFalse(isOpen); } public void testNullHeaders() throws Exception {