olegk 2003/07/25 11:29:32
Modified: httpclient/src/java/org/apache/commons/httpclient
ConnectMethod.java HttpMethodBase.java
httpclient/src/java/org/apache/commons/httpclient/methods
EntityEnclosingMethod.java MultipartPostMethod.java
Log:
Bug fix #21880 (Content-Length & Transfer-Encoding request headers should be handled
by entity enclosing methods)
Contributed by Oleg Kalnichevski
Reviewed by Michael Becke
Revision Changes Path
1.20 +4 -22
jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java
Index: ConnectMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- ConnectMethod.java 13 Jul 2003 21:29:05 -0000 1.19
+++ ConnectMethod.java 25 Jul 2003 18:29:31 -0000 1.20
@@ -123,24 +123,6 @@
/**
* This method does nothing. <tt>CONNECT</tt> request is not supposed
- * to contain <tt>Content-Length</tt> request header.
- *
- * @param state current state of http requests
- * @param conn the connection to use for I/O
- *
- * @throws IOException when errors occur reading or writing to/from the
- * connection
- * @throws HttpException when a recoverable error occurs
- *
- * @see HttpMethodBase#addContentLengthRequestHeader(HttpState, HttpConnection)
- */
- protected void addContentLengthRequestHeader(HttpState state, HttpConnection
conn)
- throws IOException, HttpException {
- // Do nothing. Not applicable to CONNECT method
- }
-
- /**
- * This method does nothing. <tt>CONNECT</tt> request is not supposed
* to contain <tt>Cookie</tt> request header.
*
* @param state current state of http requests
1.173 +6 -70
jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java
Index: HttpMethodBase.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
retrieving revision 1.172
retrieving revision 1.173
diff -u -r1.172 -r1.173
--- HttpMethodBase.java 22 Jul 2003 18:17:48 -0000 1.172
+++ HttpMethodBase.java 25 Jul 2003 18:29:31 -0000 1.173
@@ -94,17 +94,6 @@
* </ul>
*
* <p>
- * When a method's request may contain a body, subclasses will typically want
- * to override:
- * <ul>
- * <li>[EMAIL PROTECTED] #getRequestContentLength} to indicate the length (in
bytes)
- * of that body</li>
- * <li>[EMAIL PROTECTED] #writeRequestBody
writeRequestBody(HttpState,HttpConnection)}
- * to write the body</li>
- * </ul>
- * </p>
- *
- * <p>
* When a method requires additional request headers, subclasses will typically
* want to override:
* <ul>
@@ -1328,25 +1317,6 @@
}
/**
- * Return the length (in bytes) of my request body, suitable for use in a
- * <tt>Content-Length</tt> header.
- *
- * <p>
- * Return <tt>-1</tt> when the content-length is unknown.
- * </p>
- *
- * <p>
- * This implementation returns <tt>0</tt>, indicating that the request has
- * no body.
- * </p>
- *
- * @return <tt>0</tt>, indicating that the request has no body.
- */
- protected long getRequestContentLength() {
- return 0;
- }
-
- /**
* Adds an <tt>Authorization</tt> request if needed, as long as no
* <tt>Authorization</tt> request header already exists.
*
@@ -1382,39 +1352,6 @@
}
/**
- * Adds a <tt>Content-Length</tt> or <tt>Transfer-Encoding: Chunked</tt>
- * request header, as long as no <tt>Content-Length</tt> request header
- * already exists.
- *
- * TODO: Revise this method as it is potentially error-prone.
- * 'Transfer-encoding: chunked' header should not be set here
- * as some sub classes may not support chunk-encoding.
- *
- * @param state current state of http requests
- * @param conn the connection to use for I/O
- *
- * @throws IOException when errors occur reading or writing to/from the
- * connection
- * @throws HttpException when a recoverable error occurs
- */
- protected void addContentLengthRequestHeader(HttpState state,
- HttpConnection conn)
- throws IOException, HttpException {
- LOG.trace("enter HttpMethodBase.addContentLengthRequestHeader("
- + "HttpState, HttpConnection)");
-
- // add content length or chunking
- long len = getRequestContentLength();
- if (getRequestHeader("content-length") == null) {
- if (0 < len) {
- setRequestHeader("Content-Length", String.valueOf(len));
- } else if (http11 && (len < 0)) {
- setRequestHeader("Transfer-Encoding", "chunked");
- }
- }
- }
-
- /**
* Adds a <tt>Cookie</tt> request containing the matching [EMAIL PROTECTED]
Cookie}s.
*
* @param state current state of http requests
@@ -1567,8 +1504,8 @@
*
* <p>
* This implementation adds <tt>User-Agent</tt>, <tt>Host</tt>,
- * <tt>Cookie</tt>, <tt>Content-Length</tt>, <tt>Transfer-Encoding</tt>,
- * and <tt>Authorization</tt> headers, when appropriate.
+ * <tt>Cookie</tt>, <tt>Authorization</tt>, <tt>Proxy-Authorization</tt>
+ * and <tt>Proxy-Connection</tt> headers, when appropriate.
* </p>
*
* <p>
@@ -1596,7 +1533,6 @@
addAuthorizationRequestHeader(state, conn);
addProxyAuthorizationRequestHeader(state, conn);
addProxyConnectionHeader(state, conn);
- addContentLengthRequestHeader(state, conn);
}
/**
1.24 +39 -11
jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java
Index: EntityEnclosingMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- EntityEnclosingMethod.java 17 Jul 2003 21:57:42 -0000 1.23
+++ EntityEnclosingMethod.java 25 Jul 2003 18:29:32 -0000 1.24
@@ -235,10 +235,7 @@
*/
public void setFollowRedirects(boolean followRedirects) {
if (followRedirects == true) {
- // TODO: EntityEnclosingMethod should inherit from HttpMethodBase
rather than GetMethod
- // Enable exception once the inheritence is fixed
- //throw new IllegalArgumentException(
- // "Entity enclosing requests cannot be redirected without user
intervention");
+ throw new IllegalArgumentException("Entity enclosing requests cannot be
redirected without user intervention");
}
super.setFollowRedirects(false);
}
@@ -296,8 +293,7 @@
}
/**
- * Override method of [EMAIL PROTECTED]
org.apache.commons.httpclient.HttpMethodBase}
- * to return the length of the request body.
+ * Return the length of the request body.
*
* @return number of bytes in the request body
*/
@@ -317,6 +313,38 @@
}
/**
+ * Populates the request headers map to with additional
+ * [EMAIL PROTECTED] org.apache.commons.httpclient.Header headers} to be
submitted to
+ * the given [EMAIL PROTECTED] HttpConnection}.
+ *
+ * <p>
+ * This implementation adds tt>Content-Length</tt> or <tt>Transfer-Encoding</tt>
+ * headers.
+ * </p>
+ *
+ * <p>
+ * Subclasses may want to override this method to to add additional
+ * headers, and may choose to invoke this implementation (via
+ * <tt>super</tt>) to add the "standard" headers.
+ * </p>
+ *
+ * @param state the client state
+ * @param conn the [EMAIL PROTECTED] HttpConnection} the headers will
eventually be
+ * written to
+ * @throws IOException when an error occurs writing the request
+ * @throws HttpException when a HTTP protocol error occurs
+ *
+ * @see #writeRequestHeaders
+ */
+ protected void addRequestHeaders(HttpState state, HttpConnection conn)
+ throws IOException, HttpException {
+ LOG.trace("enter EntityEnclosingMethod.addRequestHeaders(HttpState, "
+ + "HttpConnection)");
+
+ super.addRequestHeaders(state, conn);
+ addContentLengthRequestHeader(state, conn);
+ }
+ /**
* Adds a <tt>Content-Length</tt> or <tt>Transfer-Encoding: Chunked</tt>
* request header, as long as no <tt>Content-Length</tt> request header
* already exists.
@@ -331,7 +359,7 @@
protected void addContentLengthRequestHeader(HttpState state,
HttpConnection conn)
throws IOException, HttpException {
- LOG.trace("enter HttpMethodBase.addContentLengthRequestHeader("
+ LOG.trace("enter EntityEnclosingMethod.addContentLengthRequestHeader("
+ "HttpState, HttpConnection)");
if ((getRequestHeader("content-length") == null)
1.20 +73 -17
jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/MultipartPostMethod.java
Index: MultipartPostMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/MultipartPostMethod.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- MultipartPostMethod.java 15 Jul 2003 12:40:57 -0000 1.19
+++ MultipartPostMethod.java 25 Jul 2003 18:29:32 -0000 1.20
@@ -195,32 +195,88 @@
public Part[] getParts() {
return (Part[]) parameters.toArray(new Part[parameters.size()]);
}
+
/**
- * Add content type header and set the <tt>Expect</tt> header
- * if it has not already been set, in addition to the "standard"
- * set of headers
- *
+ * Adds a <tt>Content-Length</tt> request header, as long as no
+ * <tt>Content-Length</tt> request header already exists.
+ *
+ * @param state current state of http requests
+ * @param conn the connection to use for I/O
+ *
+ * @throws IOException when errors occur reading or writing to/from the
+ * connection
+ * @throws HttpException when a recoverable error occurs
+ */
+ protected void addContentLengthRequestHeader(HttpState state,
+ HttpConnection conn)
+ throws IOException, HttpException {
+ LOG.trace("enter EntityEnclosingMethod.addContentLengthRequestHeader("
+ + "HttpState, HttpConnection)");
+
+ if (getRequestHeader("Content-Length") == null) {
+ long len = getRequestContentLength();
+ addRequestHeader("Content-Length", String.valueOf(len));
+ }
+ removeRequestHeader("Transfer-Encoding");
+ }
+
+ /**
+ * Adds a <tt>Content-Type</tt> request header.
+ *
+ * @param state current state of http requests
+ * @param conn the connection to use for I/O
+ *
+ * @throws IOException when errors occur reading or writing to/from the
+ * connection
+ * @throws HttpException when a recoverable error occurs
+ */
+ protected void addContentTypeRequestHeader(HttpState state,
+ HttpConnection conn)
+ throws IOException, HttpException {
+ LOG.trace("enter EntityEnclosingMethod.addContentTypeRequestHeader("
+ + "HttpState, HttpConnection)");
+
+ if (!parameters.isEmpty()) {
+ StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE);
+ if (Part.getBoundary() != null) {
+ buffer.append("; boundary=");
+ buffer.append(Part.getBoundary());
+ }
+ setRequestHeader("Content-Type", buffer.toString());
+ }
+ }
+
+ /**
+ * Populates the request headers map to with additional
+ * [EMAIL PROTECTED] org.apache.commons.httpclient.Header headers} to be
submitted to
+ * the given [EMAIL PROTECTED] HttpConnection}.
+ *
+ * <p>
+ * This implementation adds tt>Content-Length</tt> and <tt>Content-Type</tt>
+ * headers, when appropriate.
+ * </p>
+ *
+ * <p>
+ * Subclasses may want to override this method to to add additional
+ * headers, and may choose to invoke this implementation (via
+ * <tt>super</tt>) to add the "standard" headers.
+ * </p>
+ *
* @param state the client state
* @param conn the [EMAIL PROTECTED] HttpConnection} the headers will
eventually be
* written to
- *
* @throws IOException when an error occurs writing the request
* @throws HttpException when a HTTP protocol error occurs
+ *
+ * @see #writeRequestHeaders
*/
protected void addRequestHeaders(HttpState state, HttpConnection conn)
throws IOException, HttpException {
LOG.trace("enter MultipartPostMethod.addRequestHeaders(HttpState state, "
+ "HttpConnection conn)");
super.addRequestHeaders(state, conn);
-
- if (!parameters.isEmpty()) {
- StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE);
- if (Part.getBoundary() != null) {
- buffer.append("; boundary=");
- buffer.append(Part.getBoundary());
- }
- setRequestHeader("Content-Type", buffer.toString());
- }
+ addContentLengthRequestHeader(state, conn);
+ addContentTypeRequestHeader(state, conn);
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]