You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by og...@apache.org on 2006/12/01 12:26:35 UTC
svn commit: r481225 - in /jakarta/commons/proper/httpclient/trunk: ./
src/java/org/apache/commons/httpclient/
src/test/org/apache/commons/httpclient/
Author: oglueck
Date: Fri Dec 1 03:26:28 2006
New Revision: 481225
URL: http://svn.apache.org/viewvc?view=rev&rev=481225
Log:
Added a convenience method that is memory-safe.
PR: HTTPCLIENT-610
Contributed by: Ortwin Glück
Reviewed by: Oleg Kalnichevski
Added:
jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpContentTooLargeException.java
Modified:
jakarta/commons/proper/httpclient/trunk/release_notes.txt
jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpMethodBase.java
jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHttpMethodFundamentals.java
Modified: jakarta/commons/proper/httpclient/trunk/release_notes.txt
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/release_notes.txt?view=diff&rev=481225&r1=481224&r2=481225
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/release_notes.txt (original)
+++ jakarta/commons/proper/httpclient/trunk/release_notes.txt Fri Dec 1 03:26:28 2006
@@ -1,3 +1,8 @@
+Changes since Release 3.1 Beta 1:
+
+* [HTTPCLIENT-610] - Added for convenience HttpMethodBase.getResponseBodyAsString(int)
+ Contributed by Ortwin Glueck <oglueck at apache.org>
+
Release 3.1 Beta 1
-------------------
Changes since Release 3.1 Alpha 1:
Added: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpContentTooLargeException.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpContentTooLargeException.java?view=auto&rev=481225
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpContentTooLargeException.java (added)
+++ jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpContentTooLargeException.java Fri Dec 1 03:26:28 2006
@@ -0,0 +1,22 @@
+package org.apache.commons.httpclient;
+
+/**
+ * Signals that the response content was larger than anticipated.
+ *
+ * @author Ortwin Glück
+ */
+public class HttpContentTooLargeException extends HttpException {
+ private int maxlen;
+
+ public HttpContentTooLargeException(String message, int maxlen) {
+ super(message);
+ this.maxlen = maxlen;
+ }
+
+ /**
+ * @return the maximum anticipated content length in bytes.
+ */
+ public int getMaxLength() {
+ return maxlen;
+ }
+}
Modified: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpMethodBase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpMethodBase.java?view=diff&rev=481225&r1=481224&r2=481225
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpMethodBase.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpMethodBase.java Fri Dec 1 03:26:28 2006
@@ -34,7 +34,9 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.InterruptedIOException;
+import java.io.Reader;
import java.util.Collection;
import org.apache.commons.httpclient.auth.AuthState;
@@ -698,7 +700,7 @@
* Returns the response body of the HTTP method, if any, as an {@link InputStream}.
* If response body is not available, returns <tt>null</tt>
*
- * @return The response body
+ * @return The response body or <code>null</code>.
*
* @throws IOException If an I/O (transport) problem occurs while obtaining the
* response body.
@@ -726,7 +728,7 @@
* recommended, to use getResponseAsStream if the content length of the response
* is unknown or resonably large.
*
- * @return The response body.
+ * @return The response body or <code>null</code>.
*
* @throws IOException If an I/O (transport) problem occurs while obtaining the
* response body.
@@ -741,6 +743,61 @@
} else {
return null;
}
+ }
+
+ /**
+ * Returns the response body of the HTTP method, if any, as a {@link String}.
+ * If response body is not available or cannot be read, returns <tt>null</tt>
+ * The string conversion on the data is done using the character encoding specified
+ * in <tt>Content-Type</tt> header.<p>
+ *
+ * Note: This will cause the entire response body to be buffered in memory. This method is
+ * safe if the content length of the response is unknown, because the amount of memory used
+ * is limited.<p>
+ *
+ * If the response is large this method involves lots of array copying and many object
+ * allocations, which makes it unsuitable for high-performance / low-footprint applications.
+ * Those applications should use {@link #getResponseBodyAsStream()}.
+ *
+ * @param maxlen the maximum content length to accept (number of bytes). Note that,
+ * depending on the encoding, this is not equal to the number of characters.
+ * @return The response body or <code>null</code>.
+ *
+ * @throws IOException If an I/O (transport) problem occurs while obtaining the
+ * response body.
+ */
+ public String getResponseBodyAsString(int maxlen) throws IOException {
+ if (maxlen < 0) throw new IllegalArgumentException("maxlen must be positive");
+
+ // we might already know that the content is larger
+ long contentLength = getResponseContentLength();
+ if ((contentLength != -1) && (contentLength > maxlen)) {
+ throw new HttpContentTooLargeException("Content-Length is "+ contentLength, maxlen);
+ }
+
+ LOG.debug("Buffering response body");
+ ByteArrayOutputStream rawdata = new ByteArrayOutputStream(
+ contentLength > 0 ? (int) contentLength : DEFAULT_INITIAL_BUFFER_SIZE);
+ InputStream in = getResponseBodyAsStream();
+ if (in == null) return null;
+ byte[] buffer = new byte[2048];
+ int pos = 0;
+ int len;
+ do {
+ len = in.read(buffer, 0, Math.min(buffer.length, maxlen-pos));
+ if (len == -1) break;
+ rawdata.write(buffer, 0, len);
+ pos += len;
+ } while (pos < maxlen);
+
+ // check if there is even more data
+ if (pos == maxlen) {
+ if (in.read() != -1)
+ throw new HttpContentTooLargeException("Content-Length not known but larger than "
+ + maxlen, maxlen);
+ }
+
+ return EncodingUtil.getString(rawdata.toByteArray(), 0, pos, getResponseCharSet());
}
/**
Modified: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHttpMethodFundamentals.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHttpMethodFundamentals.java?view=diff&rev=481225&r1=481224&r2=481225
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHttpMethodFundamentals.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHttpMethodFundamentals.java Fri Dec 1 03:26:28 2006
@@ -249,6 +249,11 @@
assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
String response = httpget.getResponseBodyAsString();
assertNull(response);
+
+ this.client.executeMethod(httpget);
+ assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
+ response = httpget.getResponseBodyAsString(1);
+ assertNull(response);
} finally {
httpget.releaseConnection();
}
@@ -264,6 +269,34 @@
assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
byte[] response = httpget.getResponseBody();
assertNull(response);
+ } finally {
+ httpget.releaseConnection();
+ }
+ }
+
+ public void testLongBodyAsString() throws Exception {
+ this.server.setHttpService(new SimpleChunkedService());
+
+ GetMethod httpget = new GetMethod("/test/");
+ try {
+ this.client.executeMethod(httpget);
+ assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
+ try {
+ httpget.getResponseBodyAsString(5); // too small
+ } catch(HttpContentTooLargeException e) {
+ /* expected */
+ assertEquals(5, e.getMaxLength());
+ }
+
+ this.client.executeMethod(httpget);
+ assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
+ String response = httpget.getResponseBodyAsString(13); // exact size
+ assertEquals("1234567890123", response);
+
+ this.client.executeMethod(httpget);
+ assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
+ response = httpget.getResponseBodyAsString(128); // plenty
+ assertEquals("1234567890123", response);
} finally {
httpget.releaseConnection();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org