MIME multipart/form-data: added method to calculate the content length of a multipart entity. This method buffers only small amount of data in memory in order to determine the total

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@617158 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2008-01-31 16:56:25 +00:00
parent 291da5706e
commit 3fd74f63bc
2 changed files with 74 additions and 16 deletions

View File

@ -38,9 +38,12 @@ import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.List;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.http.client.mime.content.ContentBody;
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.Body;
import org.apache.james.mime4j.message.BodyPart;
import org.apache.james.mime4j.message.Entity;
import org.apache.james.mime4j.message.Multipart;
@ -68,13 +71,10 @@ public class HttpMultipart extends Multipart {
this.mode = mode;
}
@Override
public void writeTo(OutputStream out) throws IOException {
protected Charset getCharset() {
Entity e = getParent();
ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
Field.CONTENT_TYPE);
String boundary = cField.getBoundary();
Charset charset = null;
switch (this.mode) {
@ -89,8 +89,21 @@ public class HttpMultipart extends Multipart {
}
break;
}
return charset;
}
protected String getBoundary() {
Entity e = getParent();
ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
Field.CONTENT_TYPE);
return cField.getBoundary();
}
private void writeTo(final OutputStream out, boolean writeContent) throws IOException {
List<?> bodyParts = getBodyParts();
Charset charset = getCharset();
String boundary = getBoundary();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(out, charset),
@ -107,7 +120,10 @@ public class HttpMultipart extends Multipart {
writer.write("\r\n");
writer.flush();
BodyPart part = (BodyPart) bodyParts.get(i);
part.writeTo(out);
part.getHeader().writeTo(out);
if (writeContent) {
part.getBody().writeTo(out);
}
writer.write("\r\n");
}
@ -138,7 +154,9 @@ public class HttpMultipart extends Multipart {
writer.write("\r\n");
writer.write("\r\n");
writer.flush();
part.getBody().writeTo(out);
if (writeContent) {
part.getBody().writeTo(out);
}
writer.write("\r\n");
}
@ -151,5 +169,40 @@ public class HttpMultipart extends Multipart {
break;
}
}
@Override
public void writeTo(final OutputStream out) throws IOException {
writeTo(out, true);
}
public long getTotalLength() {
List<?> bodyParts = getBodyParts();
long contentLen = 0;
for (int i = 0; i < bodyParts.size(); i++) {
BodyPart part = (BodyPart) bodyParts.get(i);
Body body = part.getBody();
if (body instanceof ContentBody) {
long len = ((ContentBody) body).getContentLength();
if (len >= 0) {
contentLen += len;
} else {
return -1;
}
} else {
return -1;
}
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
writeTo(out, false);
byte[] extra = out.toByteArray();
return contentLen + extra.length;
} catch (IOException ex) {
// Should never happen
return -1;
}
}
}

View File

@ -50,7 +50,6 @@ 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 {
@ -78,7 +77,7 @@ public class TestMultipartForm extends TestCase {
Field.parse("Content-Type: multipart/form-data; boundary=foo"));
message.setHeader(header);
Multipart multipart = new HttpMultipart();
HttpMultipart multipart = new HttpMultipart();
multipart.setParent(message);
BodyPart p1 = new BodyPart();
Header h1 = new Header();
@ -121,6 +120,7 @@ public class TestMultipartForm extends TestCase {
"\r\n";
String s = out.toString("US-ASCII");
assertEquals(expected, s);
assertEquals(s.length(), multipart.getTotalLength());
}
public void testMultipartFormStringParts() throws Exception {
@ -130,7 +130,7 @@ public class TestMultipartForm extends TestCase {
Field.parse("Content-Type: multipart/form-data; boundary=foo"));
message.setHeader(header);
Multipart multipart = new HttpMultipart();
HttpMultipart multipart = new HttpMultipart();
multipart.setParent(message);
FormBodyPart p1 = new FormBodyPart(
"field1",
@ -173,6 +173,7 @@ public class TestMultipartForm extends TestCase {
"\r\n";
String s = out.toString("US-ASCII");
assertEquals(expected, s);
assertEquals(s.length(), multipart.getTotalLength());
}
public void testMultipartFormBinaryParts() throws Exception {
@ -191,7 +192,7 @@ public class TestMultipartForm extends TestCase {
writer.close();
}
Multipart multipart = new HttpMultipart();
HttpMultipart multipart = new HttpMultipart();
multipart.setParent(message);
FormBodyPart p1 = new FormBodyPart(
"field1",
@ -226,6 +227,7 @@ public class TestMultipartForm extends TestCase {
"\r\n";
String s = out.toString("US-ASCII");
assertEquals(expected, s);
assertEquals(-1, multipart.getTotalLength());
tmpfile.delete();
}
@ -279,6 +281,7 @@ public class TestMultipartForm extends TestCase {
"\r\n";
String s = out.toString("US-ASCII");
assertEquals(expected, s);
assertEquals(-1, multipart.getTotalLength());
tmpfile.delete();
}
@ -354,6 +357,7 @@ public class TestMultipartForm extends TestCase {
"\r\n";
String s = out.toString("UTF-8");
assertEquals(expected, s);
assertEquals(-1, multipart.getTotalLength());
tmpfile.delete();
}
@ -368,7 +372,7 @@ public class TestMultipartForm extends TestCase {
Field.parse("Content-Type: multipart/form-data; boundary=foo"));
message.setHeader(header);
Multipart multipart = new HttpMultipart();
HttpMultipart multipart = new HttpMultipart();
multipart.setParent(message);
FormBodyPart p1 = new FormBodyPart(
"field1",
@ -387,11 +391,11 @@ public class TestMultipartForm extends TestCase {
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
out2.write(("\r\n" +
"--foo\r\n" +
"Content-Disposition: form-data; name=\"field1\"\r\n" +
"Content-Type: text/plain; charset=ISO-8859-1\r\n" +
"Content-Transfer-Encoding: 8bit\r\n" +
"\r\n").getBytes("US-ASCII"));
"--foo\r\n" +
"Content-Disposition: form-data; name=\"field1\"\r\n" +
"Content-Type: text/plain; charset=ISO-8859-1\r\n" +
"Content-Transfer-Encoding: 8bit\r\n" +
"\r\n").getBytes("US-ASCII"));
out2.write(s1.getBytes("ISO-8859-1"));
out2.write(("\r\n" +
"--foo\r\n" +
@ -412,6 +416,7 @@ public class TestMultipartForm extends TestCase {
for (int i = 0; i < actual.length; i++) {
assertEquals(expected[i], actual[i]);
}
assertEquals(expected.length, multipart.getTotalLength());
}
}