From 2e1fbaf59f2898a1055e93c3f841d2f4bda12ff8 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Sun, 27 Jan 2008 13:21:42 +0000 Subject: [PATCH] Added HttpClient MIME module git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@615594 13f79535-47bb-0310-9956-ffa450edef68 --- module-httpmime/pom.xml | 147 ++++++++++++++++++ .../http/client/mime/HttpMultipart.java | 88 +++++++++++ .../apache/http/client/mime/StringPart.java | 45 ++++++ .../org/apache/http/client/mime/TestAll.java | 54 +++++++ .../http/client/mime/TestMultipartForm.java | 118 ++++++++++++++ 5 files changed, 452 insertions(+) create mode 100644 module-httpmime/pom.xml create mode 100644 module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java create mode 100644 module-httpmime/src/main/java/org/apache/http/client/mime/StringPart.java create mode 100644 module-httpmime/src/test/java/org/apache/http/client/mime/TestAll.java create mode 100644 module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java diff --git a/module-httpmime/pom.xml b/module-httpmime/pom.xml new file mode 100644 index 000000000..bc420ff03 --- /dev/null +++ b/module-httpmime/pom.xml @@ -0,0 +1,147 @@ + + + + + 4.0.0 + + org.apache.httpcomponents + httpcomponents-client + 4.0-alpha3-SNAPSHOT + + httpclient-mime + HttpClient (MIME entities) + 2000 + + HttpComponents HttpClient - MIME coded entities + + http://hc.apache.org/httpcomponents-client + jar + + + + Apache License + ../LICENSE.txt + repo + + + + + scm:svn:http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-httpmime + scm:svn:http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-httpmime + http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-httpmime + + + + + org.apache.httpcomponents + httpclient + ${pom.version} + + + org.apache.james + apache-mime4j + 0.3 + + + junit + junit + 3.8.1 + test + + + + + 1.5 + 1.5 + true + true + + + + + + src/main/resources + false + + META-INF/* + + + + src/main/resources + true + + **/*.properties + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compile.source} + ${maven.compile.target} + ${maven.compile.optimize} + ${maven.compile.deprecation} + + + + maven-surefire-plugin + + + **/TestAll.java + + + + + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + dependencies + issue-tracking + scm + + + + + + + + + diff --git a/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java b/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java new file mode 100644 index 000000000..a8b448530 --- /dev/null +++ b/module-httpmime/src/main/java/org/apache/http/client/mime/HttpMultipart.java @@ -0,0 +1,88 @@ +/* + * $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 + * . + * + */ + +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.List; + +import org.apache.james.mime4j.field.ContentTypeField; +import org.apache.james.mime4j.field.Field; +import org.apache.james.mime4j.message.BodyPart; +import org.apache.james.mime4j.message.Entity; +import org.apache.james.mime4j.message.Multipart; +import org.apache.james.mime4j.util.CharsetUtil; + +/** + * Extension of the mime4j standard class needed to work around + * some formatting issues in the {@link Multipart#writeTo(OutputStream)} + * method until they have been addressed downstream. + */ +public class HttpMultipart extends Multipart { + + @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(); + + List bodyParts = getBodyParts(); + + BufferedWriter writer = new BufferedWriter( + new OutputStreamWriter(out, CharsetUtil.getCharset(charset)), + 8192); + + 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) bodyParts.get(i)).writeTo(out); + writer.write("\r\n"); + } + + writer.write("--"); + writer.write(boundary); + writer.write("--\r\n"); + writer.write(getEpilogue()); + writer.write("\r\n"); + writer.flush(); + } + +} diff --git a/module-httpmime/src/main/java/org/apache/http/client/mime/StringPart.java b/module-httpmime/src/main/java/org/apache/http/client/mime/StringPart.java new file mode 100644 index 000000000..62f970abd --- /dev/null +++ b/module-httpmime/src/main/java/org/apache/http/client/mime/StringPart.java @@ -0,0 +1,45 @@ +package org.apache.http.client.mime; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; + +import org.apache.commons.io.IOUtils; +import org.apache.http.protocol.HTTP; +import org.apache.james.mime4j.message.AbstractBody; +import org.apache.james.mime4j.message.TextBody; + +public class StringPart extends AbstractBody implements TextBody { + + private final String text; + private final String charset; + + public StringPart(final String text, String charset) { + super(); + if (text == null) { + throw new IllegalArgumentException("Text may not be null"); + } + if (charset == null) { + charset = HTTP.UTF_8; + } + this.text = text; + this.charset = charset; + } + + public StringPart(final String text) { + this(text, null); + } + + public Reader getReader() throws IOException { + return new StringReader(this.text); + } + + public void writeTo(final OutputStream out) throws IOException { + if (out == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + IOUtils.copy(getReader(), out, this.charset); + } + +} diff --git a/module-httpmime/src/test/java/org/apache/http/client/mime/TestAll.java b/module-httpmime/src/test/java/org/apache/http/client/mime/TestAll.java new file mode 100644 index 000000000..142075dd2 --- /dev/null +++ b/module-httpmime/src/test/java/org/apache/http/client/mime/TestAll.java @@ -0,0 +1,54 @@ +/* + * $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 + * . + * + */ + +package org.apache.http.client.mime; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class TestAll extends TestCase { + + public TestAll(String testName) { + super(testName); + } + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(TestMultipartForm.suite()); + return suite; + } + + public static void main(String args[]) { + String[] testCaseName = { TestAll.class.getName() }; + junit.textui.TestRunner.main(testCaseName); + } + +} diff --git a/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java b/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java new file mode 100644 index 000000000..ad62352c6 --- /dev/null +++ b/module-httpmime/src/test/java/org/apache/http/client/mime/TestMultipartForm.java @@ -0,0 +1,118 @@ +/* + * $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 + * . + * + */ + +package org.apache.http.client.mime; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.apache.james.mime4j.field.Field; +import org.apache.james.mime4j.message.BodyPart; +import org.apache.james.mime4j.message.Header; +import org.apache.james.mime4j.message.Message; +import org.apache.james.mime4j.message.Multipart; + +public class TestMultipartForm extends TestCase { + + // ------------------------------------------------------------ Constructor + public TestMultipartForm(final String testName) throws IOException { + super(testName); + } + + // ------------------------------------------------------------------- Main + public static void main(String args[]) { + String[] testCaseName = { TestMultipartForm.class.getName() }; + junit.textui.TestRunner.main(testCaseName); + } + + // ------------------------------------------------------- TestCase Methods + + public static Test suite() { + return new TestSuite(TestMultipartForm.class); + } + + public void testMultipartFormContent() throws Exception { + Message message = new Message(); + Header header = new Header(); + header.addField( + Field.parse("Content-Type: multipart/form-data; boundary=foo")); + message.setHeader(header); + + Multipart multipart = new HttpMultipart(); + multipart.setParent(message); + BodyPart p1 = new BodyPart(); + Header h1 = new Header(); + h1.addField(Field.parse("Content-Type: text/plain")); + p1.setHeader(h1); + p1.setBody(new StringPart("this stuff")); + BodyPart p2 = new BodyPart(); + Header h2 = new Header(); + h2.addField(Field.parse("Content-Type: text/plain")); + p2.setHeader(h2); + p2.setBody(new StringPart("that stuff")); + BodyPart p3 = new BodyPart(); + Header h3 = new Header(); + h3.addField(Field.parse("Content-Type: text/plain")); + p3.setHeader(h3); + p3.setBody(new StringPart("all kind of stuff")); + + multipart.addBodyPart(p1); + multipart.addBodyPart(p2); + multipart.addBodyPart(p3); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + multipart.writeTo(out); + out.close(); + + String expected = "\r\n" + + "--foo\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "this stuff\r\n" + + "--foo\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "that stuff\r\n" + + "--foo\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "all kind of stuff\r\n" + + "--foo--\r\n" + + "\r\n"; + String s = out.toString("US-ASCII"); + assertEquals(expected, s); + } + +}