Return-Path: X-Original-To: apmail-hc-commits-archive@www.apache.org Delivered-To: apmail-hc-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B3E44655D for ; Wed, 18 May 2011 12:24:50 +0000 (UTC) Received: (qmail 65770 invoked by uid 500); 18 May 2011 12:24:50 -0000 Delivered-To: apmail-hc-commits-archive@hc.apache.org Received: (qmail 65740 invoked by uid 500); 18 May 2011 12:24:50 -0000 Mailing-List: contact commits-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 commits@hc.apache.org Received: (qmail 65733 invoked by uid 99); 18 May 2011 12:24:50 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 May 2011 12:24:50 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_FRT_STOCK2 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 May 2011 12:24:45 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 23E9523889F7; Wed, 18 May 2011 12:24:23 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1124215 - in /httpcomponents/httpcore/trunk: ./ httpcore/src/main/java/org/apache/http/impl/ httpcore/src/main/java/org/apache/http/impl/entity/ httpcore/src/test/java/org/apache/http/impl/ httpcore/src/test/java/org/apache/http/impl/entity/ Date: Wed, 18 May 2011 12:24:23 -0000 To: commits@hc.apache.org From: olegk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110518122423.23E9523889F7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: olegk Date: Wed May 18 12:24:22 2011 New Revision: 1124215 URL: http://svn.apache.org/viewvc?rev=1124215&view=rev Log: HTTPCORE-257: Fixed incorrect results produced by DefaultConnectionReuseStrategy when handling response esponse messages whose content entity has been decoded or modified by a protocol interceptor Modified: httpcomponents/httpcore/trunk/RELEASE_NOTES.txt httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java Modified: httpcomponents/httpcore/trunk/RELEASE_NOTES.txt URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?rev=1124215&r1=1124214&r2=1124215&view=diff ============================================================================== --- httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original) +++ httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Wed May 18 12:24:22 2011 @@ -1,6 +1,24 @@ -Changes since 4.1 +Changes since 4.1.1 ------------------- +* [HTTPCORE-257] Fixed incorrect results produced by DefaultConnectionReuseStrategy when handling + response messages whose content entity has been decoded or modified by a protocol interceptor. + Contributed by Oleg Kalnichevski + +Release 4.1.1 +------------------- + +This is a patch release that fixes a number of non-critical issues found since release 4.1. + +This release marks the end of support for Java 1.3. As of release 4.2 HttpCore will require +Java 1.5 for all its components. + +Please note that several classes and methods deprecated between versions 4.0-beta1 and 4.0 GA +(more than two years ago) will also be removed in the 4.2 branch. + +Users of 4.0.x versions are advised to upgrade and replace deprecated API calls following +recommendations in javadocs. + * In case of an unexpected end of stream condition (the peer closed connection prematurely) truncated Content-Length delimited message bodies will cause an I/O exception. Application can still choose to catch and ignore ConnectionClosedException in order to accept partial Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java?rev=1124215&r1=1124214&r2=1124215&view=diff ============================================================================== --- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java (original) +++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java Wed May 18 12:24:22 2011 @@ -28,16 +28,14 @@ package org.apache.http.impl; import org.apache.http.ConnectionReuseStrategy; -import org.apache.http.HttpConnection; +import org.apache.http.Header; import org.apache.http.HeaderIterator; -import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.ParseException; import org.apache.http.ProtocolVersion; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; -import org.apache.http.protocol.ExecutionContext; import org.apache.http.TokenIterator; import org.apache.http.message.BasicTokenIterator; @@ -77,25 +75,28 @@ public class DefaultConnectionReuseStrat ("HTTP context may not be null."); } - HttpConnection conn = (HttpConnection) - context.getAttribute(ExecutionContext.HTTP_CONNECTION); - - if (conn != null && !conn.isOpen()) - return false; - // do NOT check for stale connection, that is an expensive operation - // Check for a self-terminating entity. If the end of the entity will // be indicated by closing the connection, there is no keep-alive. - HttpEntity entity = response.getEntity(); ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); - if (entity != null) { - if (entity.getContentLength() < 0) { - if (!entity.isChunked() || - ver.lessEquals(HttpVersion.HTTP_1_0)) { - // if the content length is not known and is not chunk - // encoded, the connection cannot be reused + Header teh = response.getFirstHeader(HTTP.TRANSFER_ENCODING); + if (teh != null) { + if (!HTTP.CHUNK_CODING.equalsIgnoreCase(teh.getValue())) { + return false; + } + } else { + Header[] clhs = response.getHeaders(HTTP.CONTENT_LEN); + // Do not reuse if not properly content-length delimited + if (clhs == null || clhs.length != 1) { + return false; + } + Header clh = clhs[0]; + try { + int contentLen = Integer.parseInt(clh.getValue()); + if (contentLen < 0) { return false; } + } catch (NumberFormatException ex) { + return false; } } Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java?rev=1124215&r1=1124214&r2=1124215&view=diff ============================================================================== --- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java (original) +++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/entity/StrictContentLengthStrategy.java Wed May 18 12:24:22 2011 @@ -79,6 +79,9 @@ public class StrictContentLengthStrategy String s = contentLengthHeader.getValue(); try { long len = Long.parseLong(s); + if (len < 0) { + throw new ProtocolException("Negative content length: " + s); + } return len; } catch (NumberFormatException e) { throw new ProtocolException("Invalid content length: " + s); Modified: httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java?rev=1124215&r1=1124214&r2=1124215&view=diff ============================================================================== --- httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java (original) +++ httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java Wed May 18 12:24:22 2011 @@ -28,27 +28,17 @@ package org.apache.http.impl; import org.apache.http.ConnectionReuseStrategy; -import org.apache.http.HttpConnection; -import org.apache.http.HttpConnectionMetrics; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; -import org.apache.http.StatusLine; -import org.apache.http.entity.BasicHttpEntity; import org.apache.http.message.BasicHttpResponse; -import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; -import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestDefaultConnectionReuseStrategy { - /** A mock connection that is open and not stale. */ - private HttpConnection mockConnection; - /** HTTP context. */ private HttpContext context; @@ -57,121 +47,61 @@ public class TestDefaultConnectionReuseS @Before public void setUp() { - // open and not stale is required for most of the tests here - mockConnection = new MockConnection(true, false); reuseStrategy = new DefaultConnectionReuseStrategy(); context = new BasicHttpContext(null); - context.setAttribute(ExecutionContext.HTTP_CONNECTION, mockConnection); - } - - @After - public void tearDown() { - mockConnection = null; } - // ------------------------------------------------------- TestCase Methods - - @Test + @Test(expected=IllegalArgumentException.class) public void testIllegalResponseArg() throws Exception { - - HttpContext context = new BasicHttpContext(null); - - try { - reuseStrategy.keepAlive(null, context); - Assert.fail("IllegalArgumentException should have been thrown"); - } catch (IllegalArgumentException ex) { - // expected - } + reuseStrategy.keepAlive(null, this.context); } - @Test + @Test(expected=IllegalArgumentException.class) public void testIllegalContextArg() throws Exception { - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", false, -1); - try { - reuseStrategy.keepAlive(response, null); - Assert.fail("IllegalArgumentException should have been thrown"); - } catch (IllegalArgumentException ex) { - // expected - } + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + reuseStrategy.keepAlive(response, null); } @Test public void testNoContentLengthResponseHttp1_0() throws Exception { - HttpResponse response = - createResponse(HttpVersion.HTTP_1_0, 200, "OK", false, -1); - + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK"); Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testNoContentLengthResponseHttp1_1() throws Exception { - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", false, -1); - + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testChunkedContent() throws Exception { - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); - + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); Assert.assertTrue(reuseStrategy.keepAlive(response, context)); } @Test - public void testClosedConnection() throws Exception { - - // based on testChunkedContent which is known to return true - // the difference is in the mock connection passed here - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); - - HttpConnection mockonn = new MockConnection(false, false); - context.setAttribute(ExecutionContext.HTTP_CONNECTION, mockonn); - Assert.assertFalse("closed connection should not be kept alive", - reuseStrategy.keepAlive(response, context)); - } - - @Test - public void testStaleConnection() throws Exception { - - // based on testChunkedContent which is known to return true - // the difference is in the mock connection passed here - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); - - HttpConnection mockonn = new MockConnection(true, true); - context.setAttribute(ExecutionContext.HTTP_CONNECTION, mockonn); - Assert.assertTrue("stale connection should not be detected", - reuseStrategy.keepAlive(response, context)); - } - - @Test public void testIgnoreInvalidKeepAlive() throws Exception { - HttpResponse response = - createResponse(HttpVersion.HTTP_1_0, 200, "OK", false, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK"); response.addHeader("Connection", "keep-alive"); - Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testExplicitClose() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", "close"); - Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testExplicitKeepAlive() throws Exception { // Use HTTP 1.0 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_0, 200, "OK", false, 10); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK"); + response.addHeader("Content-Length", "10"); response.addHeader("Connection", "keep-alive"); Assert.assertTrue(reuseStrategy.keepAlive(response, context)); @@ -179,85 +109,77 @@ public class TestDefaultConnectionReuseS @Test public void testHTTP10Default() throws Exception { - HttpResponse response = - createResponse(HttpVersion.HTTP_1_0, 200, "OK"); - + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK"); + response.addHeader("Content-Length", "10"); Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testHTTP11Default() throws Exception { - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK"); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Content-Length", "10"); Assert.assertTrue(reuseStrategy.keepAlive(response, context)); } @Test public void testFutureHTTP() throws Exception { - HttpResponse response = - createResponse(new HttpVersion(3, 45), 200, "OK"); - + HttpResponse response = new BasicHttpResponse(new HttpVersion(3, 45), 200, "OK"); + response.addHeader("Content-Length", "10"); Assert.assertTrue(reuseStrategy.keepAlive(response, context)); } @Test public void testBrokenConnectionDirective1() throws Exception { // Use HTTP 1.0 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_0, 200, "OK"); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK"); + response.addHeader("Content-Length", "10"); response.addHeader("Connection", "keep--alive"); - Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testBrokenConnectionDirective2() throws Exception { // Use HTTP 1.0 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_0, 200, "OK"); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_0, 200, "OK"); + response.addHeader("Content-Length", "10"); response.addHeader("Connection", null); - Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testConnectionTokens1() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", "yadda, cLOSe, dumdy"); - Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testConnectionTokens2() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", "yadda, kEEP-alive, dumdy"); - Assert.assertTrue(reuseStrategy.keepAlive(response, context)); } @Test public void testConnectionTokens3() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", "yadda, keep-alive, close, dumdy"); - Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @Test public void testConnectionTokens4() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", "yadda, close, dumdy"); response.addHeader("Proxy-Connection", "keep-alive"); - // Connection takes precedence over Proxy-Connection Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } @@ -265,11 +187,10 @@ public class TestDefaultConnectionReuseS @Test public void testConnectionTokens5() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", "yadda, dumdy"); response.addHeader("Proxy-Connection", "close"); - // Connection takes precedence over Proxy-Connection, // even if it doesn't contain a recognized token. // Default for HTTP/1.1 is to keep alive. @@ -279,11 +200,10 @@ public class TestDefaultConnectionReuseS @Test public void testConnectionTokens6() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", ""); response.addHeader("Proxy-Connection", "close"); - // Connection takes precedence over Proxy-Connection, // even if it is empty. Default for HTTP/1.1 is to keep alive. Assert.assertTrue(reuseStrategy.keepAlive(response, context)); @@ -292,110 +212,36 @@ public class TestDefaultConnectionReuseS @Test public void testConnectionTokensInvalid() throws Exception { // Use HTTP 1.1 - HttpResponse response = - createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1); + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); response.addHeader("Connection", "keep-alive=true"); - Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } + @Test + public void testMultipleContentLength() throws Exception { + // Use HTTP 1.1 + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Content-Length", "10"); + response.addHeader("Content-Length", "11"); + Assert.assertFalse(reuseStrategy.keepAlive(response, context)); + } - /** - * Creates a response without an entity. - * - * @param version the HTTP version - * @param status the status code - * @param message the status message - * - * @return a response with the argument attributes, but no headers - */ - private final static HttpResponse createResponse(HttpVersion version, - int status, - String message) { - - StatusLine statusline = new BasicStatusLine(version, status, message); - HttpResponse response = new BasicHttpResponse(statusline); - - return response; - - } // createResponse/empty - - - /** - * Creates a response with an entity. - * - * @param version the HTTP version - * @param status the status code - * @param message the status message - * @param chunked whether the entity should indicate chunked encoding - * @param length the content length to be indicated by the entity - * - * @return a response with the argument attributes, but no headers - */ - private final static HttpResponse createResponse(HttpVersion version, - int status, - String message, - boolean chunked, - int length) { - - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setChunked(chunked); - entity.setContentLength(length); - HttpResponse response = createResponse(version, status, message); - response.setEntity(entity); - - return response; - - } // createResponse/entity - - - /** - * A mock connection. - * This is neither client nor server connection, since the default - * strategy is agnostic. It does not allow modification of it's state, - * since the strategy is supposed to decide about keep-alive, but not - * to modify the connection's state. - */ - private final static class MockConnection implements HttpConnection { - - private boolean iAmOpen; - private boolean iAmStale; - - public MockConnection(boolean open, boolean stale) { - iAmOpen = open; - iAmStale = stale; - } - - public final boolean isOpen() { - return iAmOpen; - } - - public void setSocketTimeout(int timeout) { - } - - public int getSocketTimeout() { - return -1; - } - - public final boolean isStale() { - return iAmStale; - } - - public final void close() { - throw new UnsupportedOperationException - ("connection state must not be modified"); - } - - public final void shutdown() { - throw new UnsupportedOperationException - ("connection state must not be modified"); - } - - public HttpConnectionMetrics getMetrics() { - return null; - } + @Test + public void testInvalidContentLength() throws Exception { + // Use HTTP 1.1 + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Content-Length", "crap"); + Assert.assertFalse(reuseStrategy.keepAlive(response, context)); + } - } // class MockConnection + @Test + public void testInvalidNegativeContentLength() throws Exception { + // Use HTTP 1.1 + HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Content-Length", "-10"); + Assert.assertFalse(reuseStrategy.keepAlive(response, context)); + } -} // class TestDefaultConnectionReuseStrategy +} Modified: httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java?rev=1124215&r1=1124214&r2=1124215&view=diff ============================================================================== --- httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java (original) +++ httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/entity/TestStrictContentLengthStrategy.java Wed May 18 12:24:22 2011 @@ -55,34 +55,22 @@ public class TestStrictContentLengthStra Assert.assertEquals(ContentLengthStrategy.IDENTITY, lenStrategy.determineLength(message)); } - @Test + @Test(expected=ProtocolException.class) public void testEntityWithInvalidTransferEncoding() throws Exception { ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy(); HttpMessage message = new DummyHttpMessage(); message.addHeader("Transfer-Encoding", "whatever"); - - try { - lenStrategy.determineLength(message); - Assert.fail("ProtocolException should have been thrown"); - } catch (ProtocolException ex) { - // expected - } + lenStrategy.determineLength(message); } - @Test + @Test(expected=ProtocolException.class) public void testEntityWithInvalidChunkEncodingAndHTTP10() throws Exception { ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy(); HttpMessage message = new DummyHttpMessage(); message.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0); message.addHeader("Transfer-Encoding", "chunked"); - - try { - lenStrategy.determineLength(message); - Assert.fail("ProtocolException should have been thrown"); - } catch (ProtocolException ex) { - // expected - } + lenStrategy.determineLength(message); } @Test @@ -93,18 +81,20 @@ public class TestStrictContentLengthStra Assert.assertEquals(100, lenStrategy.determineLength(message)); } - @Test + @Test(expected=ProtocolException.class) public void testEntityWithInvalidContentLength() throws Exception { ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy(); HttpMessage message = new DummyHttpMessage(); message.addHeader("Content-Length", "whatever"); + lenStrategy.determineLength(message); + } - try { - lenStrategy.determineLength(message); - Assert.fail("ProtocolException should have been thrown"); - } catch (ProtocolException ex) { - // expected - } + @Test(expected=ProtocolException.class) + public void testEntityWithNegativeContentLength() throws Exception { + ContentLengthStrategy lenStrategy = new StrictContentLengthStrategy(); + HttpMessage message = new DummyHttpMessage(); + message.addHeader("Content-Length", "-10"); + lenStrategy.determineLength(message); } @Test