[#1358] Fix Encoding of multipart attribute names and filenames for non ASCII chars

This commit is contained in:
Norman Maurer 2013-05-14 15:24:01 +02:00
parent dbad71366d
commit a331c87a7a
2 changed files with 38 additions and 30 deletions

View File

@ -471,14 +471,14 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput<HttpContent>
*/
if (data instanceof Attribute) {
if (duringMixedMode) {
InternalAttribute internal = new InternalAttribute();
InternalAttribute internal = new InternalAttribute(charset);
internal.addValue("\r\n--" + multipartMixedBoundary + "--");
multipartHttpDatas.add(internal);
multipartMixedBoundary = null;
currentFileUpload = null;
duringMixedMode = false;
}
InternalAttribute internal = new InternalAttribute();
InternalAttribute internal = new InternalAttribute(charset);
if (!multipartHttpDatas.isEmpty()) {
// previously a data field so CRLF
internal.addValue("\r\n");
@ -503,7 +503,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput<HttpContent>
globalBodySize += attribute.length() + internal.size();
} else if (data instanceof FileUpload) {
FileUpload fileUpload = (FileUpload) data;
InternalAttribute internal = new InternalAttribute();
InternalAttribute internal = new InternalAttribute(charset);
if (!multipartHttpDatas.isEmpty()) {
// previously a data field so CRLF
internal.addValue("\r\n");
@ -525,7 +525,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput<HttpContent>
multipartMixedBoundary = null;
// start a new one (could be replaced if mixed start again
// from here
internal = new InternalAttribute();
internal = new InternalAttribute(charset);
internal.addValue("\r\n");
localMixed = false;
// new currentFileUpload and no more in Mixed mode
@ -640,7 +640,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput<HttpContent>
// Finalize the multipartHttpDatas
if (!headerFinalized) {
if (isMultipart) {
InternalAttribute internal = new InternalAttribute();
InternalAttribute internal = new InternalAttribute(charset);
if (duringMixedMode) {
internal.addValue("\r\n--" + multipartMixedBoundary + "--");
}
@ -799,14 +799,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput<HttpContent>
}
ByteBuf buffer;
if (currentData instanceof InternalAttribute) {
String internal = currentData.toString();
byte[] bytes;
try {
bytes = internal.getBytes("ASCII");
} catch (UnsupportedEncodingException e) {
throw new ErrorDataEncoderException(e);
}
buffer = wrappedBuffer(bytes);
buffer = ((InternalAttribute) currentData).toByteBuf();
currentData = null;
} else {
if (currentData instanceof Attribute) {

View File

@ -15,6 +15,10 @@
*/
package io.netty.handler.codec.http.multipart;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@ -23,36 +27,46 @@ import java.util.List;
* (like Multipart Mixed mode)
*/
final class InternalAttribute implements InterfaceHttpData {
private final List<String> value = new ArrayList<String>();
private final List<ByteBuf> value = new ArrayList<ByteBuf>();
private final Charset charset;
private int size;
public InternalAttribute(Charset charset) {
this.charset = charset;
}
@Override
public HttpDataType getHttpDataType() {
return HttpDataType.InternalAttribute;
}
public List<String> getValue() {
return value;
}
public void addValue(String value) {
if (value == null) {
throw new NullPointerException("value");
}
this.value.add(value);
ByteBuf buf = Unpooled.copiedBuffer(value, charset);
this.value.add(buf);
size += buf.readableBytes();
}
public void addValue(String value, int rank) {
if (value == null) {
throw new NullPointerException("value");
}
this.value.add(rank, value);
ByteBuf buf = Unpooled.copiedBuffer(value, charset);
this.value.add(rank, buf);
size += buf.readableBytes();
}
public void setValue(String value, int rank) {
if (value == null) {
throw new NullPointerException("value");
}
this.value.set(rank, value);
ByteBuf buf = Unpooled.copiedBuffer(value, charset);
ByteBuf old = this.value.set(rank, buf);
if (old != null) {
size -= old.readableBytes();
}
size += buf.readableBytes();
}
@Override
@ -82,22 +96,23 @@ final class InternalAttribute implements InterfaceHttpData {
return getName().compareToIgnoreCase(o.getName());
}
public int size() {
int size = 0;
for (String elt : value) {
size += elt.length();
}
return size;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (String elt : value) {
result.append(elt);
for (ByteBuf elt : value) {
result.append(elt.toString(charset));
}
return result.toString();
}
public int size() {
return size;
}
public ByteBuf toByteBuf() {
return Unpooled.compositeBuffer().addComponents(value).writerIndex(size()).readerIndex(0);
}
@Override
public String getName() {
return "InternalAttribute";