Index: java/org/apache/commons/httpclient/methods/ByteArrayRequestEntity.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/ByteArrayRequestEntity.java,v retrieving revision 1.1 diff -u -r1.1 ByteArrayRequestEntity.java --- java/org/apache/commons/httpclient/methods/ByteArrayRequestEntity.java 28 Apr 2004 02:23:17 -0000 1.1 +++ java/org/apache/commons/httpclient/methods/ByteArrayRequestEntity.java 11 May 2004 14:36:52 -0000 @@ -41,12 +41,29 @@ /** The content */ private byte[] content; + /** The content type */ + private String contentType; + + /** + * Creates a new entity with the given content. + * @param content The content to set. + */ + public ByteArrayRequestEntity(byte[] content) { + this(content, null); + } + /** - * Creates a new entity with no content. The content must be set before this entity can be - * used. + * Creates a new entity with the given content and content type. + * @param content The content to set. + * @param contentType The content type to set or null. */ - public ByteArrayRequestEntity() { + public ByteArrayRequestEntity(byte[] content, String contentType) { super(); + if (content == null) { + throw new IllegalArgumentException("The content cannot be null"); + } + this.content = content; + this.contentType = contentType; } /** @@ -57,12 +74,16 @@ } /* (non-Javadoc) + * @see org.apache.commons.httpclient.methods.RequestEntity#getContentType() + */ + public String getContentType() { + return contentType; + } + + /* (non-Javadoc) * @see org.apache.commons.httpclient.RequestEntity#writeRequest(java.io.OutputStream) */ public void writeRequest(OutputStream out) throws IOException { - if (content == null) { - throw new IllegalStateException("Content must be set before entity is written"); - } out.write(content); } @@ -78,16 +99,6 @@ */ public byte[] getContent() { return content; - } - - /** - * @param content The content to set. - */ - public void setContent(byte[] content) { - if (content == null) { - throw new IllegalArgumentException("The content cannot be null"); - } - this.content = content; } } Index: java/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java,v retrieving revision 1.33 diff -u -r1.33 EntityEnclosingMethod.java --- java/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java 8 May 2004 10:12:07 -0000 1.33 +++ java/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java 11 May 2004 14:36:52 -0000 @@ -34,12 +34,12 @@ import java.io.OutputStream; import org.apache.commons.httpclient.ChunkedOutputStream; +import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpConnection; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.HttpVersion; import org.apache.commons.httpclient.ProtocolException; -import org.apache.commons.httpclient.util.EncodingUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -60,12 +60,14 @@ /** * The content length will be calculated automatically. This implies * buffering of the content. + * @deprecated Use {@link InputStreamRequestEntity#CONTENT_LENGTH_AUTO}. */ public static final long CONTENT_LENGTH_AUTO = -2; /** * The request will use chunked transfer encoding. Content length is not * calculated and the content is not buffered.
+ * @deprecated Use {@link #setContentChunked(boolean)}. */ public static final long CONTENT_LENGTH_CHUNKED = -1; @@ -167,19 +169,17 @@ if (requestBody != null) { // use the request body, if it exists. // this is just for backwards compatability - ByteArrayRequestEntity entity = new ByteArrayRequestEntity(); - entity.setContent(requestBody); - this.requestEntity = entity; + this.requestEntity = new ByteArrayRequestEntity(requestBody); } else if (this.requestStream != null) { - InputStreamRequestEntity entity = new InputStreamRequestEntity(); - entity.setContent(requestStream); - entity.setContentLength(requestContentLength); + this.requestEntity = new InputStreamRequestEntity( + requestStream, + requestContentLength); this.requestStream = null; - this.requestEntity = entity; } else if (this.requestString != null) { - ByteArrayRequestEntity entity = new ByteArrayRequestEntity(); - entity.setContent(EncodingUtil.getBytes(this.requestString, getRequestCharSet())); - this.requestEntity = entity; + this.requestEntity = new StringRequestEntity( + requestString, + null, + getRequestCharSet()); } return this.requestEntity; @@ -238,6 +238,25 @@ this.requestContentLength = length; } + /* (non-Javadoc) + * @see org.apache.commons.httpclient.HttpMethodBase#getRequestCharSet() + */ + public String getRequestCharSet() { + if (getRequestHeader("Content-Type") == null) { + // check the content type from request entity + // We can't call getRequestEntity() since it will probably call + // this method. + if (this.requestEntity != null) { + return getContentCharSet( + new Header("Content-Type", requestEntity.getContentType())); + } else { + return null; + } + } else { + return super.getRequestCharSet(); + } + } + /** * Sets length information about the request body. * @@ -330,7 +349,17 @@ super.addRequestHeaders(state, conn); addContentLengthRequestHeader(state, conn); + + // only use the content type of the request entity if it has not already been + // set manually + if (getRequestHeader("Content-Type") == null) { + String contentType = getRequestEntity().getContentType(); + if (contentType != null) { + setRequestHeader("Content-Type", contentType); + } + } } + /** * Generates Content-Length or Transfer-Encoding: Chunked * request header, as long as no Content-Length request header Index: java/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java,v retrieving revision 1.1 diff -u -r1.1 InputStreamRequestEntity.java --- java/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java 28 Apr 2004 02:23:17 -0000 1.1 +++ java/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java 11 May 2004 14:36:52 -0000 @@ -43,21 +43,83 @@ */ public class InputStreamRequestEntity implements RequestEntity { + /** + * The content length will be calculated automatically. This implies + * buffering of the content. + */ + public static final int CONTENT_LENGTH_AUTO = -2; + private static final Log LOG = LogFactory.getLog(InputStreamRequestEntity.class); - private long contentLength = EntityEnclosingMethod.CONTENT_LENGTH_AUTO; + private long contentLength; - private InputStream content = null; + private InputStream content; /** The buffered request body, if any. */ private byte[] buffer = null; + + /** The content type */ + private String contentType; /** - * Creates a new InputStreamRequestEntity with no content. + * Creates a new InputStreamRequestEntity with the given content and a content type of + * {@link RequestEntity#CONTENT_LENGTH_AUTO}. + * @param content The content to set. */ - public InputStreamRequestEntity() { + public InputStreamRequestEntity(InputStream content) { + this(content, null); + } + + /** + * Creates a new InputStreamRequestEntity with the given content, content type, and a + * content length of {@link RequestEntity#CONTENT_LENGTH_AUTO}. + * @param content The content to set. + * @param contentType The type of the content, or null. + */ + public InputStreamRequestEntity(InputStream content, String contentType) { + this(content, CONTENT_LENGTH_AUTO, contentType); + } + + /** + * Creates a new InputStreamRequestEntity with the given content and content length. + * @param content The content to set. + * @param contentLength The content size in bytes or any of + * {@link EntityEnclosingMethod#CONTENT_LENGTH_AUTO CONTENT_LENGTH_AUTO}, + * {@link EntityEnclosingMethod#CONTENT_LENGTH_CHUNKED CONTENT_LENGTH_CHUNKED}. If the number + * of bytes or CONTENT_LENGTH_CHUNKED is specified the content will not be + * buffered when {@link #getContentLength()} is called. + */ + public InputStreamRequestEntity(InputStream content, long contentLength) { + this(content, contentLength, null); + } + + /** + * Creates a new InputStreamRequestEntity with the given content, content length, and + * content type. + * @param content The content to set. + * @param contentLength The content size in bytes or any of + * {@link EntityEnclosingMethod#CONTENT_LENGTH_AUTO CONTENT_LENGTH_AUTO}, + * {@link EntityEnclosingMethod#CONTENT_LENGTH_CHUNKED CONTENT_LENGTH_CHUNKED}. If the number + * of bytes or CONTENT_LENGTH_CHUNKED is specified the content will not be + * buffered when {@link #getContentLength()} is called. + * @param contentType The type of the content, or null. + */ + public InputStreamRequestEntity(InputStream content, long contentLength, String contentType) { + if (content == null) { + throw new IllegalArgumentException("The content cannot be null"); + } + this.content = null; + this.contentLength = contentLength; + this.contentType = contentType; } + /* (non-Javadoc) + * @see org.apache.commons.httpclient.methods.RequestEntity#getContentType() + */ + public String getContentType() { + return contentType; + } + /** * Buffers request body input stream. */ @@ -125,37 +187,17 @@ * @see #setContentLength(long) */ public long getContentLength() { - if (contentLength == EntityEnclosingMethod.CONTENT_LENGTH_AUTO && buffer == null) { + if (contentLength == CONTENT_LENGTH_AUTO && buffer == null) { bufferContent(); } return contentLength; } /** - * Sets the content length. - * - * @param contentLength The content size in bytes or any of - * {@link EntityEnclosingMethod#CONTENT_LENGTH_AUTO CONTENT_LENGTH_AUTO}, - * {@link EntityEnclosingMethod#CONTENT_LENGTH_CHUNKED CONTENT_LENGTH_CHUNKED}. If the number - * of bytes or CONTENT_LENGTH_CHUNKED is specified the content will not be - * buffered when {@link #getContentLength()} is called. - */ - public void setContentLength(long contentLength) { - this.contentLength = contentLength; - } - - /** * @return Returns the content. */ public InputStream getContent() { return content; - } - - /** - * @param inputStream The content to set. - */ - public void setContent(InputStream inputStream) { - this.content = inputStream; } } Index: java/org/apache/commons/httpclient/methods/PostMethod.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/PostMethod.java,v retrieving revision 1.54 diff -u -r1.54 PostMethod.java --- java/org/apache/commons/httpclient/methods/PostMethod.java 28 Apr 2004 02:23:17 -0000 1.54 +++ java/org/apache/commons/httpclient/methods/PostMethod.java 11 May 2004 14:36:53 -0000 @@ -29,13 +29,9 @@ package org.apache.commons.httpclient.methods; -import java.io.IOException; import java.util.Iterator; import java.util.Vector; -import org.apache.commons.httpclient.HttpConnection; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.util.EncodingUtil; import org.apache.commons.logging.Log; @@ -163,9 +159,7 @@ protected RequestEntity generateRequestEntity() { if (!this.params.isEmpty()) { String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet()); - ByteArrayRequestEntity entity = new ByteArrayRequestEntity(); - entity.setContent(EncodingUtil.getAsciiBytes(content)); - return entity; + return new StringRequestEntity(content, FORM_URL_ENCODED_CONTENT_TYPE, "US-ASCII"); } else { return super.generateRequestEntity(); } @@ -400,33 +394,5 @@ } clearRequestBody(); addParameters(parametersBody); - } - - /** - * Adds Content Type: application/x-www-form-urlencoded header in - * addition to the "standard" set of headers, if no Content Type - * header has been set by the user - * - * @param state the {@link HttpState state} information associated with this method - * @param conn the {@link HttpConnection connection} used to execute - * this HTTP method - * - * @throws IOException if an I/O (transport) error occurs. Some transport exceptions - * can be recovered from. - * @throws HttpException if a protocol exception occurs. Usually protocol exceptions - * cannot be recovered from. - * - * @since 2.0 - */ - protected void addRequestHeaders(HttpState state, HttpConnection conn) - throws IOException, HttpException { - super.addRequestHeaders(state, conn); - - if (!this.params.isEmpty()) { - //there are some parameters, so set the contentType header - if (getRequestHeader("Content-Type") == null) { - setRequestHeader("Content-Type", FORM_URL_ENCODED_CONTENT_TYPE); - } - } } } Index: java/org/apache/commons/httpclient/methods/RequestEntity.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/RequestEntity.java,v retrieving revision 1.1 diff -u -r1.1 RequestEntity.java --- java/org/apache/commons/httpclient/methods/RequestEntity.java 28 Apr 2004 02:23:17 -0000 1.1 +++ java/org/apache/commons/httpclient/methods/RequestEntity.java 11 May 2004 14:36:53 -0000 @@ -56,4 +56,12 @@ */ long getContentLength(); + /** + * Gets the entity's content type. This content type will be used as the value for the + * "Content-Type" header. + * @return + * @see org.apache.commons.httpclient.HttpMethod#setRequestHeader(String, String) + */ + String getContentType(); + } Index: java/org/apache/commons/httpclient/methods/StringRequestEntity.java =================================================================== RCS file: java/org/apache/commons/httpclient/methods/StringRequestEntity.java diff -N java/org/apache/commons/httpclient/methods/StringRequestEntity.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ java/org/apache/commons/httpclient/methods/StringRequestEntity.java 11 May 2004 14:36:53 -0000 @@ -0,0 +1,149 @@ +/* + * $Header$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Copyright 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 + * . + * + * [Additional notices, if required by prior licensing conditions] + * + */ +package org.apache.commons.httpclient.methods; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import org.apache.commons.httpclient.HeaderElement; +import org.apache.commons.httpclient.NameValuePair; + +/** + * A RequestEntity that contains a String. + */ +public class StringRequestEntity implements RequestEntity { + + /** The content */ + private String content; + + /** The charset */ + private String charset; + + /** The content type (i.e. text/html; charset=EUC-JP). */ + private String contentType; + + + /** + * Creates a new entity with the given content + * + * @param content The content to set. + */ + public StringRequestEntity(final String content) { + this(content, null, null); + } + + /** + * Creates a new entity with the given content, content type, and charset. + * + * @param content The content to set. + * @param contentType The type of the content, or null. The value retured + * by {@link #getContentType()}. This value will be parsed to determine the content's + * charset. + */ + public StringRequestEntity(String content, String contentType) { + this(content, contentType, null); + } + + /** + * Creates a new entity with the given content, content type, and charset. + * + * @param content The content to set. + * @param contentType The type of the content, or null. The value retured + * by {@link #getContentType()}. This value will be parsed to determine the content's + * charset. + * @param charset The charset of the content, or null. Used to convert the + * content to bytes. If this value is null, the content type will be parsed to + * determine the content's charset. + */ + public StringRequestEntity(String content, String contentType, String charset) { + super(); + if (content == null) { + throw new IllegalArgumentException("The content cannot be null"); + } + this.content = content; + this.contentType = contentType; + this.charset = charset; + + if (content != null && charset == null) { + HeaderElement[] elements = HeaderElement.parseElements(content); + if (elements.length > 0) { + NameValuePair param = elements[0].getParameterByName("charset"); + if (param != null) { + this.charset = param.getValue(); + } + } + } + } + + /* (non-Javadoc) + * @see org.apache.commons.httpclient.methods.RequestEntity#getContentType() + */ + public String getContentType() { + return contentType; + } + + /** + * @return true + */ + public boolean isRepeatable() { + return true; + } + + /* (non-Javadoc) + * @see org.apache.commons.httpclient.RequestEntity#writeRequest(java.io.OutputStream) + */ + public void writeRequest(OutputStream out) throws IOException { + Writer writer = null; + if (this.charset != null) { + writer = new OutputStreamWriter(out, this.charset); + } else { + writer = new OutputStreamWriter(out); + } + writer.write(content); + } + + /** + * @return The length of the content. + */ + public long getContentLength() { + return content.length(); + } + + /** + * @return Returns the content. + */ + public String getContent() { + return this.content; + } + +}