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 2008/01/30 12:33:03 UTC
svn commit: r616725 - in
/httpcomponents/httpclient/trunk/module-httpmime/src:
main/java/org/apache/http/client/mime/
main/java/org/apache/http/client/mime/content/
test/java/org/apache/http/client/mime/
Author: olegk
Date: Wed Jan 30 03:32:57 2008
New Revision: 616725
URL: http://svn.apache.org/viewvc?rev=616725&view=rev
Log:
MIME multipart/form-data: strict (RFC 822, RFC 2045, RFC 2046 compliant) and lenient (browser compatible) modes
Added:
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java (with props)
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java (with props)
Modified:
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/FormBodyPart.java
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/MIME.java
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/FileBody.java
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/InputStreamBody.java
httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/StringBody.java
httpcomponents/httpclient/trunk/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java
Modified: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/FormBodyPart.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/FormBodyPart.java?rev=616725&r1=616724&r2=616725&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/FormBodyPart.java (original)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/FormBodyPart.java Wed Jan 30 03:32:57 2008
@@ -50,7 +50,7 @@
}
this.name = name;
- Header header = new Header();
+ Header header = new RFC822Header();
setHeader(header);
setBody(body);
Modified: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java?rev=616725&r1=616724&r2=616725&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java (original)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java Wed Jan 30 03:32:57 2008
@@ -1,7 +1,7 @@
/*
- * $HeadURL:$
- * $Revision:$
- * $Date:$
+ * $HeadURL$
+ * $Revision$
+ * $Date$
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -35,8 +35,10 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
import java.util.List;
+import org.apache.http.protocol.HTTP;
import org.apache.james.mime4j.field.ContentTypeField;
import org.apache.james.mime4j.field.Field;
import org.apache.james.mime4j.message.BodyPart;
@@ -51,38 +53,103 @@
*/
public class HttpMultipart extends Multipart {
+ private HttpMultipartMode mode;
+
+ public HttpMultipart() {
+ super();
+ this.mode = HttpMultipartMode.STRICT;
+ }
+
+ public HttpMultipartMode getMode() {
+ return this.mode;
+ }
+
+ public void setMode(final HttpMultipartMode mode) {
+ this.mode = mode;
+ }
+
@Override
public void writeTo(OutputStream out) throws IOException {
Entity e = getParent();
+
ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
Field.CONTENT_TYPE);
String boundary = cField.getBoundary();
- String charset = cField.getCharset();
+ Charset charset = null;
+
+ switch (this.mode) {
+ case STRICT:
+ charset = MIME.DEFAULT_CHARSET;
+ break;
+ case BROWSER_COMPATIBLE:
+ if (cField.getCharset() != null) {
+ charset = CharsetUtil.getCharset(cField.getCharset());
+ } else {
+ charset = CharsetUtil.getCharset(HTTP.DEFAULT_CONTENT_CHARSET);
+ }
+ break;
+ }
List<?> bodyParts = getBodyParts();
BufferedWriter writer = new BufferedWriter(
- new OutputStreamWriter(out, CharsetUtil.getCharset(charset)),
+ new OutputStreamWriter(out, charset),
8192);
- writer.write(getPreamble());
- writer.write("\r\n");
+ switch (this.mode) {
+ case STRICT:
+ writer.write(getPreamble());
+ writer.write("\r\n");
+
+ for (int i = 0; i < bodyParts.size(); i++) {
+ writer.write("--");
+ writer.write(boundary);
+ writer.write("\r\n");
+ writer.flush();
+ BodyPart part = (BodyPart) bodyParts.get(i);
+ part.writeTo(out);
+ writer.write("\r\n");
+ }
- for (int i = 0; i < bodyParts.size(); i++) {
writer.write("--");
writer.write(boundary);
+ writer.write("--\r\n");
+ writer.write(getEpilogue());
writer.write("\r\n");
writer.flush();
- ((BodyPart) bodyParts.get(i)).writeTo(out);
+ break;
+ case BROWSER_COMPATIBLE:
+
+ // (1) Do not write preamble and epilogue
+ // (2) Only write Content-Disposition
+ // (3) Use content charset
+
writer.write("\r\n");
- }
- writer.write("--");
- writer.write(boundary);
- writer.write("--\r\n");
- writer.write(getEpilogue());
- writer.write("\r\n");
- writer.flush();
+ for (int i = 0; i < bodyParts.size(); i++) {
+ writer.write("--");
+ writer.write(boundary);
+ writer.write("\r\n");
+ writer.flush();
+ BodyPart part = (BodyPart) bodyParts.get(i);
+
+ Field cd = part.getHeader().getField(MIME.CONTENT_DISPOSITION);
+ writer.write(cd.toString());
+ writer.write("\r\n");
+ writer.write("\r\n");
+ writer.flush();
+ part.getBody().writeTo(out);
+
+ writer.write("\r\n");
+ }
+
+ writer.write("--");
+ writer.write(boundary);
+ writer.write("--\r\n");
+ writer.write("\r\n");
+ writer.flush();
+ break;
+ }
}
}
Added: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java?rev=616725&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java (added)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java Wed Jan 30 03:32:57 2008
@@ -0,0 +1,39 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.client.mime;
+
+public enum HttpMultipartMode {
+
+ STRICT,
+ BROWSER_COMPATIBLE
+
+}
Propchange: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipartMode.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/MIME.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/MIME.java?rev=616725&r1=616724&r2=616725&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/MIME.java (original)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/MIME.java Wed Jan 30 03:32:57 2008
@@ -31,7 +31,10 @@
package org.apache.http.client.mime;
+import java.nio.charset.Charset;
+
import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.CharsetUtil;
public final class MIME {
@@ -41,5 +44,7 @@
public static final String ENC_8BIT = "8bit";
public static final String ENC_BINARY = "binary";
+
+ public static final Charset DEFAULT_CHARSET = CharsetUtil.getCharset("US-ASCII");
}
Added: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java?rev=616725&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java (added)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java Wed Jan 30 03:32:57 2008
@@ -0,0 +1,56 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.client.mime;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Iterator;
+
+import org.apache.james.mime4j.message.Header;
+
+class RFC822Header extends Header {
+
+ @Override
+ public void writeTo(final OutputStream out) throws IOException {
+ BufferedWriter writer = new BufferedWriter(
+ new OutputStreamWriter(out, MIME.DEFAULT_CHARSET), 8192);
+ for (Iterator<?> it = getFields().iterator(); it.hasNext();) {
+ writer.write(it.next().toString());
+ writer.write("\r\n");
+ }
+ writer.write("\r\n");
+ writer.flush();
+ }
+
+}
Propchange: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/RFC822Header.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/FileBody.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/FileBody.java?rev=616725&r1=616724&r2=616725&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/FileBody.java (original)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/FileBody.java Wed Jan 30 03:32:57 2008
@@ -35,16 +35,15 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.Reader;
import java.nio.charset.Charset;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.mime.MIME;
import org.apache.james.mime4j.message.AbstractBody;
+import org.apache.james.mime4j.message.BinaryBody;
-public class FileBody extends AbstractBody implements ContentBody {
+public class FileBody extends AbstractBody implements BinaryBody, ContentBody {
private final File file;
@@ -56,8 +55,8 @@
this.file = file;
}
- public Reader getReader() throws IOException {
- return new InputStreamReader(new FileInputStream(this.file));
+ public InputStream getInputStream() throws IOException {
+ return new FileInputStream(this.file);
}
public void writeTo(final OutputStream out) throws IOException {
Modified: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/InputStreamBody.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/InputStreamBody.java?rev=616725&r1=616724&r2=616725&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/InputStreamBody.java (original)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/InputStreamBody.java Wed Jan 30 03:32:57 2008
@@ -33,16 +33,15 @@
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.Reader;
import java.nio.charset.Charset;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.mime.MIME;
import org.apache.james.mime4j.message.AbstractBody;
+import org.apache.james.mime4j.message.BinaryBody;
-public class InputStreamBody extends AbstractBody implements ContentBody {
+public class InputStreamBody extends AbstractBody implements BinaryBody, ContentBody {
private final InputStream in;
private final String filename;
@@ -56,8 +55,8 @@
this.filename = filename;
}
- public Reader getReader() throws IOException {
- return new InputStreamReader(this.in);
+ public InputStream getInputStream() throws IOException {
+ return this.in;
}
public void writeTo(final OutputStream out) throws IOException {
Modified: httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/StringBody.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/StringBody.java?rev=616725&r1=616724&r2=616725&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/StringBody.java (original)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/main/java/org/apache/http/client/mime/content/StringBody.java Wed Jan 30 03:32:57 2008
@@ -42,8 +42,9 @@
import org.apache.commons.io.IOUtils;
import org.apache.http.client.mime.MIME;
import org.apache.james.mime4j.message.AbstractBody;
+import org.apache.james.mime4j.message.TextBody;
-public class StringBody extends AbstractBody implements ContentBody {
+public class StringBody extends AbstractBody implements TextBody, ContentBody {
private final byte[] content;
private final Charset charset;
Modified: httpcomponents/httpclient/trunk/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java?rev=616725&r1=616724&r2=616725&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java (original)
+++ httpcomponents/httpclient/trunk/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java Wed Jan 30 03:32:57 2008
@@ -183,6 +183,7 @@
message.setHeader(header);
File tmpfile = File.createTempFile("tmp", ".bin");
+ tmpfile.deleteOnExit();
Writer writer = new FileWriter(tmpfile);
try {
writer.append("some random whatever");
@@ -225,6 +226,61 @@
"\r\n";
String s = out.toString("US-ASCII");
assertEquals(expected, s);
+
+ tmpfile.delete();
+ }
+
+ public void testMultipartFormBrowserCompatible() throws Exception {
+ Message message = new Message();
+ Header header = new Header();
+ header.addField(
+ Field.parse("Content-Type: multipart/form-data; boundary=foo"));
+ message.setHeader(header);
+
+ File tmpfile = File.createTempFile("tmp", ".bin");
+ tmpfile.deleteOnExit();
+ Writer writer = new FileWriter(tmpfile);
+ try {
+ writer.append("some random whatever");
+ } finally {
+ writer.close();
+ }
+
+ HttpMultipart multipart = new HttpMultipart();
+ multipart.setParent(message);
+ FormBodyPart p1 = new FormBodyPart(
+ "field1",
+ new FileBody(tmpfile));
+ FormBodyPart p2 = new FormBodyPart(
+ "field2",
+ new InputStreamBody(new FileInputStream(tmpfile), "file.tmp"));
+
+ multipart.addBodyPart(p1);
+ multipart.addBodyPart(p2);
+
+ multipart.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ multipart.writeTo(out);
+ out.close();
+
+ String expected = "\r\n" +
+ "--foo\r\n" +
+ "Content-Disposition: form-data; name=\"field1\"; " +
+ "filename=\"" + tmpfile.getName() + "\"\r\n" +
+ "\r\n" +
+ "some random whatever\r\n" +
+ "--foo\r\n" +
+ "Content-Disposition: form-data; name=\"field2\"; " +
+ "filename=\"file.tmp\"\r\n" +
+ "\r\n" +
+ "some random whatever\r\n" +
+ "--foo--\r\n" +
+ "\r\n";
+ String s = out.toString("US-ASCII");
+ assertEquals(expected, s);
+
+ tmpfile.delete();
}
}