You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2005/04/05 20:37:48 UTC
svn commit: r160206 - in jakarta/httpclient/trunk/http-common/src:
java/org/apache/http/impl/ java/org/apache/http/io/
test/org/apache/http/impl/
Author: olegk
Date: Tue Apr 5 11:37:44 2005
New Revision: 160206
URL: http://svn.apache.org/viewcvs?view=rev&rev=160206
Log:
Extra test coverage, javadocs
Added:
jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java (with props)
jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java (with props)
Modified:
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultEntityGenerator.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedInputStream.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedOutputStream.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ContentLengthInputStream.java
jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestAllImpl.java
jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultEntityGenerator.java
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultEntityGenerator.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultEntityGenerator.java?view=diff&r1=160205&r2=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultEntityGenerator.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultEntityGenerator.java Tue Apr 5 11:37:44 2005
@@ -49,7 +49,135 @@
/**
* <p>
+ * This entity generator comforms to the entity transfer rules outlined in the
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec4.4">Section 4.4</a>,
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6">Section 3.6</a>,
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.41">Section 14.41</a>
+ * and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec14.13">Section 14.13</a>
+ * of <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">RFC 2616</a>
* </p>
+ * <h>4.4 Message Length</h>
+ * <p>
+ * The transfer-length of a message is the length of the message-body as it appears in the
+ * message; that is, after any transfer-codings have been applied. When a message-body is
+ * included with a message, the transfer-length of that body is determined by one of the
+ * following (in order of precedence):
+ * </p>
+ * <p>
+ * 1.Any response message which "MUST NOT" include a message-body (such as the 1xx, 204,
+ * and 304 responses and any response to a HEAD request) is always terminated by the first
+ * empty line after the header fields, regardless of the entity-header fields present in the
+ * message.
+ * </p>
+ * <p>
+ * 2.If a Transfer-Encoding header field (section 14.41) is present and has any value other
+ * than "identity", then the transfer-length is defined by use of the "chunked" transfer-
+ * coding (section 3.6), unless the message is terminated by closing the connection.
+ * </p>
+ * <p>
+ * 3.If a Content-Length header field (section 14.13) is present, its decimal value in
+ * OCTETs represents both the entity-length and the transfer-length. The Content-Length
+ * header field MUST NOT be sent if these two lengths are different (i.e., if a
+ * Transfer-Encoding
+ * </p>
+ * <pre>
+ * header field is present). If a message is received with both a
+ * Transfer-Encoding header field and a Content-Length header field,
+ * the latter MUST be ignored.
+ * </pre>
+ * <p>
+ * 4.If the message uses the media type "multipart/byteranges", and the ransfer-length is not
+ * otherwise specified, then this self- elimiting media type defines the transfer-length.
+ * This media type UST NOT be used unless the sender knows that the recipient can arse it; the
+ * presence in a request of a Range header with ultiple byte- range specifiers from a 1.1
+ * client implies that the lient can parse multipart/byteranges responses.
+ * </p>
+ * <pre>
+ * A range header might be forwarded by a 1.0 proxy that does not
+ * understand multipart/byteranges; in this case the server MUST
+ * delimit the message using methods defined in items 1,3 or 5 of
+ * this section.
+ * </pre>
+ * <p>
+ * 5.By the server closing the connection. (Closing the connection cannot be used to indicate
+ * the end of a request body, since that would leave no possibility for the server to send back
+ * a response.)
+ * </p>
+ * <p>
+ * For compatibility with HTTP/1.0 applications, HTTP/1.1 requests containing a message-body
+ * MUST include a valid Content-Length header field unless the server is known to be HTTP/1.1
+ * compliant. If a request contains a message-body and a Content-Length is not given, the
+ * server SHOULD respond with 400 (bad request) if it cannot determine the length of the
+ * message, or with 411 (length required) if it wishes to insist on receiving a valid
+ * Content-Length.
+ * </p>
+ * <p>All HTTP/1.1 applications that receive entities MUST accept the "chunked" transfer-coding
+ * (section 3.6), thus allowing this mechanism to be used for messages when the message
+ * length cannot be determined in advance.
+ * </p>
+ * <h>3.6 Transfer Codings</h>
+ * <p>
+ * Transfer-coding values are used to indicate an encoding transformation that
+ * has been, can be, or may need to be applied to an entity-body in order to ensure
+ * "safe transport" through the network. This differs from a content coding in that
+ * the transfer-coding is a property of the message, not of the original entity.
+ * </p>
+ * <pre>
+ * transfer-coding = "chunked" | transfer-extension
+ * transfer-extension = token *( ";" parameter )
+ * </pre>
+ * <p>
+ * Parameters are in the form of attribute/value pairs.
+ * </p>
+ * <pre>
+ * parameter = attribute "=" value
+ * attribute = token
+ * value = token | quoted-string
+ * </pre>
+ * <p>
+ * All transfer-coding values are case-insensitive. HTTP/1.1 uses transfer-coding values in
+ * the TE header field (section 14.39) and in the Transfer-Encoding header field (section 14.41).
+ * </p>
+ * <p>
+ * Whenever a transfer-coding is applied to a message-body, the set of transfer-codings MUST
+ * include "chunked", unless the message is terminated by closing the connection. When the
+ * "chunked" transfer-coding is used, it MUST be the last transfer-coding applied to the
+ * message-body. The "chunked" transfer-coding MUST NOT be applied more than once to a
+ * message-body. These rules allow the recipient to determine the transfer-length of the
+ * message (section 4.4).
+ * </p>
+ * <h>14.41 Transfer-Encoding</h>
+ * <p>
+ * The Transfer-Encoding general-header field indicates what (if any) type of transformation has
+ * been applied to the message body in order to safely transfer it between the sender and the
+ * recipient. This differs from the content-coding in that the transfer-coding is a property of
+ * the message, not of the entity.
+ * </p>
+ * <pre>
+ * Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding
+ * </pre>
+ * <p>
+ * If multiple encodings have been applied to an entity, the transfer- codings MUST be listed in
+ * the order in which they were applied. Additional information about the encoding parameters
+ * MAY be provided by other entity-header fields not defined by this specification.
+ * </p>
+ * <h>14.13 Content-Length</h>
+ * <p>
+ * The Content-Length entity-header field indicates the size of the entity-body, in decimal
+ * number of OCTETs, sent to the recipient or, in the case of the HEAD method, the size of
+ * the entity-body that would have been sent had the request been a GET.
+ * </p>
+ * <pre>
+ * Content-Length = "Content-Length" ":" 1*DIGIT
+ * </pre>
+ * <p>
+ * Applications SHOULD use this field to indicate the transfer-length of the message-body,
+ * unless this is prohibited by the rules in section 4.4.
+ * </p>
+ * <p>
+ * This entity generator currently supports only "chunked" and "identitiy" transfer-coding</a>
+ * </p>
+ *
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision$
@@ -105,7 +233,7 @@
if (strict) {
// Currently only chunk and identity are supported
for (int i = 0; i < encodings.length; i++) {
- String encoding = encodings[i].getValue();
+ String encoding = encodings[i].getName();
if (encoding != null && !encoding.equals("")
&& !encoding.equalsIgnoreCase(CHUNKED_ENCODING)
&& !encoding.equalsIgnoreCase(IDENTITY_ENCODING)) {
@@ -113,8 +241,7 @@
}
}
}
- // The chunked encoding must be the last one applied
- // RFC2616, 14.41
+ // The chunked encoding must be the last one applied RFC2616, 14.41
int len = encodings.length;
if (IDENTITY_ENCODING.equalsIgnoreCase(transferEncodingHeader.getValue())) {
entity.setChunked(false);
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedInputStream.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedInputStream.java?view=diff&r1=160205&r2=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedInputStream.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedInputStream.java Tue Apr 5 11:37:44 2005
@@ -40,16 +40,76 @@
import org.apache.http.util.HeadersParser;
/**
- * <p>Transparently coalesces chunks of a HTTP stream that uses
- * Transfer-Encoding chunked.</p>
+ * <p>This class implements chunked transfer coding as described in the
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6">Section 3.6.1</a>
+ * of <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">RFC 2616</a>.
+ * It transparently coalesces chunks of a HTTP stream that uses chunked transfer coding.</p>
+ *
+ * <h>3.6.1 Chunked Transfer Coding</h>
+ * <p>
+ * The chunked encoding modifies the body of a message in order to transfer it as a series
+ * of chunks, each with its own size indicator, followed by an OPTIONAL trailer containing
+ * entity-header fields. This allows dynamically produced content to be transferred along
+ * with the information necessary for the recipient to verify that it has received the full
+ * message.
+ * </p>
+ * <pre>
+ * Chunked-Body = *chunk
+ * last-chunk
+ * trailer
+ * CRLF
*
- * <p>Note that this class NEVER closes the underlying stream, even when close
+ * chunk = chunk-size [ chunk-extension ] CRLF
+ * chunk-data CRLF
+ * chunk-size = 1*HEX
+ * last-chunk = 1*("0") [ chunk-extension ] CRLF
+ *
+ * chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
+ * chunk-ext-name = token
+ * chunk-ext-val = token | quoted-string
+ * chunk-data = chunk-size(OCTET)
+ * trailer = *(entity-header CRLF)
+ * </pre>
+ * <p>
+ * The chunk-size field is a string of hex digits indicating the size of the chunk. The
+ * chunked encoding is ended by any chunk whose size is zero, followed by the trailer,
+ * which is terminated by an empty line.
+ * </p>
+ * <p>
+ * The trailer allows the sender to include additional HTTP header fields at the end
+ * of the message. The Trailer header field can be used to indicate which header fields
+ * are included in a trailer (see section 14.40).
+ * </p>
+ * <p>
+ * A server using chunked transfer-coding in a response MUST NOT use the trailer for any
+ * header fields unless at least one of the following is true:
+ * </p>
+ * <p>
+ * a)the request included a TE header field that indicates "trailers" is acceptable in
+ * the transfer-coding of the response, as described in section 14.39; or,
+ * </p>
+ * <p>
+ * b)the server is the origin server for the response, the trailer fields consist entirely
+ * of optional metadata, and the recipient could use the message (in a manner acceptable
+ * to the origin server) without receiving this metadata. In other words, the origin server
+ * is willing to accept the possibility that the trailer fields might be silently discarded
+ * along the path to the client.
+ * </p>
+ * <p>
+ * This requirement prevents an interoperability failure when the message is being received
+ * by an HTTP/1.1 (or later) proxy and forwarded to an HTTP/1.0 recipient. It avoids a
+ * situation where compliance with the protocol would have necessitated a possibly infinite
+ * buffer on the proxy.
+ * </p>
+ * <p>
+ * Note that this class NEVER closes the underlying stream, even when close
* gets called. Instead, it will read until the "end" of its chunking on close,
* which allows for the seamless invocation of subsequent HTTP 1.1 calls, while
* not requiring the client to remember to read the entire contents of the
- * response.</p>
+ * response.
+ * </p>
*
- * @author Ortwin Glück
+ * @author Ortwin Glueck
* @author Sean C. Sullivan
* @author Martin Elwin
* @author Eric Johnson
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedOutputStream.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedOutputStream.java?view=diff&r1=160205&r2=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedOutputStream.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ChunkedOutputStream.java Tue Apr 5 11:37:44 2005
@@ -35,9 +35,69 @@
import org.apache.http.util.EncodingUtil;
/**
- * Implements HTTP chunking support. Writes are buffered to an internal buffer (2048 default size).
- * Chunks are guaranteed to be at least as large as the buffer size (except for the last chunk).
+ * <p>This class implements chunked transfer coding as described in the
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6">Section 3.6.1</a>
+ * of <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">RFC 2616</a>.
+ * Writes are buffered to an internal buffer (2048 default size). Chunks are guaranteed
+ * to be at least as large as the buffer size (except for the last chunk).</p>
+ *
+ * <h>3.6.1 Chunked Transfer Coding</h>
+ * <p>
+ * The chunked encoding modifies the body of a message in order to transfer it as a series
+ * of chunks, each with its own size indicator, followed by an OPTIONAL trailer containing
+ * entity-header fields. This allows dynamically produced content to be transferred along
+ * with the information necessary for the recipient to verify that it has received the full
+ * message.
+ * </p>
+ * <pre>
+ * Chunked-Body = *chunk
+ * last-chunk
+ * trailer
+ * CRLF
*
+ * chunk = chunk-size [ chunk-extension ] CRLF
+ * chunk-data CRLF
+ * chunk-size = 1*HEX
+ * last-chunk = 1*("0") [ chunk-extension ] CRLF
+ *
+ * chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
+ * chunk-ext-name = token
+ * chunk-ext-val = token | quoted-string
+ * chunk-data = chunk-size(OCTET)
+ * trailer = *(entity-header CRLF)
+ * </pre>
+ * <p>
+ * The chunk-size field is a string of hex digits indicating the size of the chunk. The
+ * chunked encoding is ended by any chunk whose size is zero, followed by the trailer,
+ * which is terminated by an empty line.
+ * </p>
+ * <p>
+ * The trailer allows the sender to include additional HTTP header fields at the end
+ * of the message. The Trailer header field can be used to indicate which header fields
+ * are included in a trailer (see section 14.40).
+ * </p>
+ * <p>
+ * A server using chunked transfer-coding in a response MUST NOT use the trailer for any
+ * header fields unless at least one of the following is true:
+ * </p>
+ * <p>
+ * a)the request included a TE header field that indicates "trailers" is acceptable in
+ * the transfer-coding of the response, as described in section 14.39; or,
+ * </p>
+ * <p>
+ * b)the server is the origin server for the response, the trailer fields consist entirely
+ * of optional metadata, and the recipient could use the message (in a manner acceptable
+ * to the origin server) without receiving this metadata. In other words, the origin server
+ * is willing to accept the possibility that the trailer fields might be silently discarded
+ * along the path to the client.
+ * </p>
+ * <p>
+ * This requirement prevents an interoperability failure when the message is being received
+ * by an HTTP/1.1 (or later) proxy and forwarded to an HTTP/1.0 recipient. It avoids a
+ * situation where compliance with the protocol would have necessitated a possibly infinite
+ * buffer on the proxy.
+ * </p>
+ *
* @author Mohammad Rezaei, Goldman, Sachs & Co.
*/
public class ChunkedOutputStream extends OutputStream {
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ContentLengthInputStream.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ContentLengthInputStream.java?view=diff&r1=160205&r2=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ContentLengthInputStream.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/io/ContentLengthInputStream.java Tue Apr 5 11:37:44 2005
@@ -33,8 +33,16 @@
import java.io.InputStream;
/**
- * Cuts the wrapped InputStream off after a specified number of bytes.
- *
+ * <p>
+ * This class cuts the wrapped InputStream off after a specified number of bytes.
+ * </p>
+ * <p>
+ * Note that this class NEVER closes the underlying stream, even when close
+ * gets called. Instead, it will read until the "end" of its chunking on close,
+ * which allows for the seamless invocation of subsequent HTTP 1.1 calls, while
+ * not requiring the client to remember to read the entire contents of the
+ * response.
+ * </p>
* <p>Implementation note: Choices abound. One approach would pass
* through the {@link InputStream#mark} and {@link InputStream#reset} calls to
* the underlying stream. That's tricky, though, because you then have to
Modified: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestAllImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestAllImpl.java?view=diff&r1=160205&r2=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestAllImpl.java (original)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestAllImpl.java Tue Apr 5 11:37:44 2005
@@ -43,6 +43,8 @@
suite.addTest(TestAutoCloseInputStream.suite());
suite.addTest(TestDefaultConnectionReuseStrategy.suite());
suite.addTest(TestDefaultEntityGenerator.suite());
+ suite.addTest(TestDefaultResponseConsumedWatcher.suite());
+ suite.addTest(TestBasicRequest.suite());
return suite;
}
Added: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java?view=auto&rev=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java (added)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java Tue Apr 5 11:37:44 2005
@@ -0,0 +1,104 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ * ====================================================================
+ *
+ * Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.http.HttpMutableRequest;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpVersion;
+import org.apache.http.RequestLine;
+import org.apache.http.params.HttpProtocolParams;
+
+public class TestBasicRequest extends TestCase {
+
+ public TestBasicRequest(String testName) {
+ super(testName);
+ }
+
+ // ------------------------------------------------------- TestCase Methods
+
+ public static Test suite() {
+ return new TestSuite(TestBasicRequest.class);
+ }
+
+ // ------------------------------------------------------------------- Main
+ public static void main(String args[]) {
+ String[] testCaseName = { TestBasicRequest.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ public void testConstructor() throws Exception {
+ new BasicHttpRequest("GET", "/stuff");
+ new BasicHttpRequest(new RequestLine("GET", "/stuff", HttpVersion.HTTP_1_1));
+ try {
+ new BasicHttpRequest(null, "/stuff");
+ fail("IllegalArgumentException should have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ new BasicHttpRequest("GET", null);
+ fail("IllegalArgumentException should have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+ public void testRequestLine() throws Exception {
+ HttpRequest request = new BasicHttpRequest("GET", "/stuff");
+ request.getParams().setParameter(
+ HttpProtocolParams.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
+ assertEquals("GET", request.getRequestLine().getMethod());
+ assertEquals("/stuff", request.getRequestLine().getUri());
+ assertEquals(HttpVersion.HTTP_1_0, request.getRequestLine().getHttpVersion());
+ }
+
+ public void testRequestLine2() throws Exception {
+ HttpRequest request = new BasicHttpRequest(
+ new RequestLine("GET", "/stuff", HttpVersion.HTTP_1_0));
+ assertEquals("GET", request.getRequestLine().getMethod());
+ assertEquals("/stuff", request.getRequestLine().getUri());
+ assertEquals(HttpVersion.HTTP_1_0, request.getRequestLine().getHttpVersion());
+ }
+
+ public void testNullRequestLine() throws Exception {
+ HttpMutableRequest request = new BasicHttpRequest("GET", "/stuff");
+ try {
+ request.setRequestLine(null);
+ fail("IllegalArgumentException should have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+}
+
Propchange: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestBasicRequest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java?view=diff&r1=160205&r2=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java (original)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java Tue Apr 5 11:37:44 2005
@@ -72,7 +72,6 @@
entity.setContentLength(-1);
HttpMutableResponse response = new BasicHttpResponse();
response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_0, 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
response.setEntity(entity);
ConnectionReuseStrategy s = new DefaultConnectionReuseStrategy();
@@ -86,7 +85,6 @@
HttpMutableResponse response = new BasicHttpResponse();
// Use HTTP 1.1
response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_1, 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
response.addHeader(new Header("Connection", "close"));
response.setEntity(entity);
@@ -101,7 +99,6 @@
HttpMutableResponse response = new BasicHttpResponse();
// Use HTTP 1.0
response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_0, 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
response.addHeader(new Header("Connection", "keep-alive"));
response.setEntity(entity);
@@ -112,7 +109,6 @@
public void testHTTP10Default() throws Exception {
HttpMutableResponse response = new BasicHttpResponse();
response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_0, 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
ConnectionReuseStrategy s = new DefaultConnectionReuseStrategy();
assertFalse(s.keepAlive(response));
@@ -121,7 +117,6 @@
public void testHTTP11Default() throws Exception {
HttpMutableResponse response = new BasicHttpResponse();
response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_1, 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
ConnectionReuseStrategy s = new DefaultConnectionReuseStrategy();
assertTrue(s.keepAlive(response));
@@ -130,7 +125,6 @@
public void testFutureHTTP() throws Exception {
HttpMutableResponse response = new BasicHttpResponse();
response.setStatusLine(new StatusLine(new HttpVersion(3, 45), 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
ConnectionReuseStrategy s = new DefaultConnectionReuseStrategy();
assertTrue(s.keepAlive(response));
@@ -140,7 +134,6 @@
HttpMutableResponse response = new BasicHttpResponse();
// Use HTTP 1.0
response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_0, 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
response.addHeader(new Header("Connection", "keep--alive"));
ConnectionReuseStrategy s = new DefaultConnectionReuseStrategy();
@@ -151,7 +144,6 @@
HttpMutableResponse response = new BasicHttpResponse();
// Use HTTP 1.0
response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_0, 200, "OK"));
- response.setParams(new DefaultHttpParams(null));
response.addHeader(new Header("Connection", null));
ConnectionReuseStrategy s = new DefaultConnectionReuseStrategy();
Modified: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultEntityGenerator.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultEntityGenerator.java?view=diff&r1=160205&r2=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultEntityGenerator.java (original)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultEntityGenerator.java Tue Apr 5 11:37:44 2005
@@ -41,7 +41,6 @@
import org.apache.http.io.HttpDataReceiver;
import org.apache.http.io.InputStreamHttpDataReceiver;
import org.apache.http.mockup.HttpDataReceiverMockup;
-import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import junit.framework.Test;
@@ -66,7 +65,7 @@
junit.textui.TestRunner.main(testCaseName);
}
- public void testIllegalResponseArg() throws Exception {
+ public void testIllegalGenerateArg() throws Exception {
EntityGenerator entitygen = new DefaultEntityGenerator();
try {
entitygen.generate(null, null);
@@ -82,14 +81,107 @@
}
}
+ public void testEntityWithTransferEncoding() throws Exception {
+ HttpDataReceiver datareceiver = new HttpDataReceiverMockup("0\r\n", "US-ASCII");
+ HttpMutableMessage message = new BasicHttpMessage();
+
+ // lenient mode
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.addHeader(new Header("Content-Type", "unknown"));
+ message.addHeader(new Header("Transfer-Encoding", "identity, chunked"));
+ message.addHeader(new Header("Content-Length", "plain wrong"));
+ EntityGenerator entitygen = new DefaultEntityGenerator();
+ HttpEntity entity = entitygen.generate(datareceiver, message);
+ assertNotNull(entity);
+ assertEquals(-1, entity.getContentLength());
+ assertTrue(entity.isChunked());
+ assertTrue(entity.getInputStream() instanceof ChunkedInputStream);
+
+ // strict mode
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
+ entity = entitygen.generate(datareceiver, message);
+ assertNotNull(entity);
+ assertEquals(-1, entity.getContentLength());
+ assertTrue(entity.isChunked());
+ assertTrue(entity.getInputStream() instanceof ChunkedInputStream);
+ }
+
+ public void testEntityWithIdentityTransferEncoding() throws Exception {
+ InputStream instream = new ByteArrayInputStream(new byte[] {});
+ HttpDataReceiver datareceiver = new InputStreamHttpDataReceiver(instream);
+ HttpMutableMessage message = new BasicHttpMessage();
+
+ // lenient mode
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.addHeader(new Header("Content-Type", "unknown"));
+ message.addHeader(new Header("Transfer-Encoding", "identity"));
+ message.addHeader(new Header("Content-Length", "plain wrong"));
+ EntityGenerator entitygen = new DefaultEntityGenerator();
+ HttpEntity entity = entitygen.generate(datareceiver, message);
+ assertNotNull(entity);
+ assertEquals(-1, entity.getContentLength());
+ assertFalse(entity.isChunked());
+ assertTrue(entity.getInputStream() instanceof ByteArrayInputStream);
+ }
+
+ public void testEntityWithUnsupportedTransferEncoding() throws Exception {
+ HttpDataReceiver datareceiver = new HttpDataReceiverMockup("0\r\n", "US-ASCII");
+ HttpMutableMessage message = new BasicHttpMessage();
+
+ // lenient mode
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.addHeader(new Header("Content-Type", "unknown"));
+ message.addHeader(new Header("Transfer-Encoding", "whatever; param=value, chunked"));
+ message.addHeader(new Header("Content-Length", "plain wrong"));
+ EntityGenerator entitygen = new DefaultEntityGenerator();
+ HttpEntity entity = entitygen.generate(datareceiver, message);
+ assertNotNull(entity);
+ assertEquals(-1, entity.getContentLength());
+ assertTrue(entity.isChunked());
+ assertTrue(entity.getInputStream() instanceof ChunkedInputStream);
+
+ // strict mode
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
+ try {
+ entitygen.generate(datareceiver, message);
+ fail("ProtocolException should have been thrown");
+ } catch (ProtocolException ex) {
+ // expected
+ }
+ }
+
+ public void testChunkedTransferEncodingMustBeLast() throws Exception {
+ HttpDataReceiver datareceiver = new HttpDataReceiverMockup("0\r\n", "US-ASCII");
+ HttpMutableMessage message = new BasicHttpMessage();
+
+ // lenient mode
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.addHeader(new Header("Content-Type", "unknown"));
+ message.addHeader(new Header("Transfer-Encoding", "chunked, identity"));
+ message.addHeader(new Header("Content-Length", "plain wrong"));
+ EntityGenerator entitygen = new DefaultEntityGenerator();
+ HttpEntity entity = entitygen.generate(datareceiver, message);
+ assertNotNull(entity);
+ assertEquals(-1, entity.getContentLength());
+ assertFalse(entity.isChunked());
+ assertFalse(entity.getInputStream() instanceof ChunkedInputStream);
+
+ // strict mode
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
+ try {
+ entitygen.generate(datareceiver, message);
+ fail("ProtocolException should have been thrown");
+ } catch (ProtocolException ex) {
+ // expected
+ }
+ }
+
public void testEntityWithContentLength() throws Exception {
HttpDataReceiver datareceiver = new HttpDataReceiverMockup(new byte[] {});
HttpMutableMessage message = new BasicHttpMessage();
- HttpParams params = new DefaultHttpParams(null);
- message.setParams(params);
// lenient mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
message.addHeader(new Header("Content-Type", "unknown"));
message.addHeader(new Header("Content-Length", "0"));
EntityGenerator entitygen = new DefaultEntityGenerator();
@@ -103,11 +195,9 @@
public void testEntityWithMultipleContentLength() throws Exception {
HttpDataReceiver datareceiver = new HttpDataReceiverMockup(new byte[] {'0'});
HttpMutableMessage message = new BasicHttpMessage();
- HttpParams params = new DefaultHttpParams(null);
- message.setParams(params);
// lenient mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
message.addHeader(new Header("Content-Type", "unknown"));
message.addHeader(new Header("Content-Length", "0"));
message.addHeader(new Header("Content-Length", "0"));
@@ -121,7 +211,7 @@
assertTrue(entity.getInputStream() instanceof ContentLengthInputStream);
// strict mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
try {
entitygen.generate(datareceiver, message);
fail("ProtocolException should have been thrown");
@@ -133,11 +223,9 @@
public void testEntityWithMultipleContentLengthSomeWrong() throws Exception {
HttpDataReceiver datareceiver = new HttpDataReceiverMockup(new byte[] {'0'});
HttpMutableMessage message = new BasicHttpMessage();
- HttpParams params = new DefaultHttpParams(null);
- message.setParams(params);
// lenient mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
message.addHeader(new Header("Content-Type", "unknown"));
message.addHeader(new Header("Content-Length", "1"));
message.addHeader(new Header("Content-Length", "yyy"));
@@ -151,7 +239,7 @@
assertTrue(entity.getInputStream() instanceof ContentLengthInputStream);
// strict mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
try {
entitygen.generate(datareceiver, message);
fail("ProtocolException should have been thrown");
@@ -163,11 +251,9 @@
public void testEntityWithMultipleContentLengthAllWrong() throws Exception {
HttpDataReceiver datareceiver = new HttpDataReceiverMockup(new byte[] {'0'});
HttpMutableMessage message = new BasicHttpMessage();
- HttpParams params = new DefaultHttpParams(null);
- message.setParams(params);
// lenient mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
message.addHeader(new Header("Content-Type", "unknown"));
message.addHeader(new Header("Content-Length", "yyy"));
message.addHeader(new Header("Content-Length", "xxx"));
@@ -181,7 +267,7 @@
assertTrue(entity.getInputStream() instanceof HttpDataInputStream);
// strict mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
try {
entitygen.generate(datareceiver, message);
fail("ProtocolException should have been thrown");
@@ -193,11 +279,9 @@
public void testEntityWithInvalidContentLength() throws Exception {
HttpDataReceiver datareceiver = new HttpDataReceiverMockup(new byte[] {'0'});
HttpMutableMessage message = new BasicHttpMessage();
- HttpParams params = new DefaultHttpParams(null);
- message.setParams(params);
// lenient mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
message.addHeader(new Header("Content-Type", "unknown"));
message.addHeader(new Header("Content-Length", "xxx"));
EntityGenerator entitygen = new DefaultEntityGenerator();
@@ -210,7 +294,7 @@
assertTrue(entity.getInputStream() instanceof HttpDataInputStream);
// strict mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, true);
try {
entitygen.generate(datareceiver, message);
fail("ProtocolException should have been thrown");
@@ -222,11 +306,9 @@
public void testEntityNeitherContentLengthNorTransferEncoding() throws Exception {
HttpDataReceiver datareceiver = new HttpDataReceiverMockup(new byte[] {'0'});
HttpMutableMessage message = new BasicHttpMessage();
- HttpParams params = new DefaultHttpParams(null);
- message.setParams(params);
// lenient mode
- params.setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
+ message.getParams().setBooleanParameter(HttpProtocolParams.STRICT_TRANSFER_ENCODING, false);
EntityGenerator entitygen = new DefaultEntityGenerator();
HttpEntity entity = entitygen.generate(datareceiver, message);
assertNotNull(entity);
Added: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java?view=auto&rev=160206
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java (added)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java Tue Apr 5 11:37:44 2005
@@ -0,0 +1,127 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ * ====================================================================
+ *
+ * Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.http.Header;
+import org.apache.http.HttpConnection;
+import org.apache.http.HttpMutableEntity;
+import org.apache.http.HttpMutableResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.StatusLine;
+import org.apache.http.mockup.HttpConnectionMockup;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class TestDefaultResponseConsumedWatcher extends TestCase {
+
+ public TestDefaultResponseConsumedWatcher(String testName) {
+ super(testName);
+ }
+
+ // ------------------------------------------------------- TestCase Methods
+
+ public static Test suite() {
+ return new TestSuite(TestDefaultResponseConsumedWatcher.class);
+ }
+
+ // ------------------------------------------------------------------- Main
+ public static void main(String args[]) {
+ String[] testCaseName = { TestDefaultResponseConsumedWatcher.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ public void testIllegalResponseArg() throws Exception {
+ try {
+ ResponseConsumedWatcher watcher = new DefaultResponseConsumedWatcher(null, null);
+ fail("IllegalArgumentException should have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ try {
+ ResponseConsumedWatcher watcher = new DefaultResponseConsumedWatcher(
+ new HttpConnectionMockup(), null);
+ fail("IllegalArgumentException should have been thrown");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+
+ public void testConnectionAutoClose() throws Exception {
+ byte[] data = new byte[] {'1', '2', '3'};
+ HttpConnection conn = new HttpConnectionMockup();
+ HttpMutableEntity entity = new BasicHttpEntity();
+ entity.setChunked(false);
+ entity.setContentLength(data.length);
+ entity.setInputStream(new ByteArrayInputStream(data));
+
+ HttpMutableResponse response = new BasicHttpResponse();
+ response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_0, 200, "OK"));
+ response.setHeader(new Header("Connection", "Close"));
+ response.setParams(new DefaultHttpParams(null));
+ response.setEntity(entity);
+
+ // Wrap the entity input stream
+ ResponseConsumedWatcher watcher = new DefaultResponseConsumedWatcher(conn, response);
+ entity.setInputStream(new AutoCloseInputStream(entity.getInputStream(), watcher));
+
+ assertTrue(conn.isOpen());
+ int b;
+ while ((b = entity.getInputStream().read()) != -1) {}
+ assertFalse(conn.isOpen());
+ }
+
+ public void testConnectionKeepAlive() throws Exception {
+ byte[] data = new byte[] {'1', '2', '3'};
+ HttpConnection conn = new HttpConnectionMockup();
+ HttpMutableEntity entity = new BasicHttpEntity();
+ entity.setChunked(false);
+ entity.setContentLength(data.length);
+ entity.setInputStream(new ByteArrayInputStream(data));
+
+ HttpMutableResponse response = new BasicHttpResponse();
+ response.setStatusLine(new StatusLine(HttpVersion.HTTP_1_1, 200, "OK"));
+ response.setHeader(new Header("Connection", "Keep-alive"));
+ response.setParams(new DefaultHttpParams(null));
+ response.setEntity(entity);
+
+ // Wrap the entity input stream
+ ResponseConsumedWatcher watcher = new DefaultResponseConsumedWatcher(conn, response);
+ entity.setInputStream(new AutoCloseInputStream(entity.getInputStream(), watcher));
+
+ assertTrue(conn.isOpen());
+ int b;
+ while ((b = entity.getInputStream().read()) != -1) {}
+ assertTrue(conn.isOpen());
+ }
+}
+
Propchange: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestDefaultResponseConsumedWatcher.java
------------------------------------------------------------------------------
svn:mime-type = text/plain