Add support for 'charset' property for multipart boundaries

- Fixes #2004
This commit is contained in:
Frederic Bregier 2013-12-07 12:18:56 +01:00 committed by Trustin Lee
parent f41e2f830d
commit d7faf042a1
2 changed files with 55 additions and 19 deletions

View File

@ -59,7 +59,7 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
/**
* Default charset to use
*/
private final Charset charset;
private Charset charset;
/**
* Does the last chunk already received
@ -193,10 +193,18 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
}
/**
* Set from the request ContentType the multipartDataBoundary.
* Set from the request ContentType the multipartDataBoundary and the possible charset.
*/
private void setMultipart(String contentType) {
multipartDataBoundary = HttpPostRequestDecoder.getMultipartDataBoundary(contentType);
String[] dataBoundary = HttpPostRequestDecoder.getMultipartDataBoundary(contentType);
if (dataBoundary != null) {
multipartDataBoundary = dataBoundary[0];
if (dataBoundary.length > 1 && dataBoundary[1] != null) {
charset = Charset.forName(dataBoundary[1]);
}
} else {
multipartDataBoundary = null;
}
currentStatus = MultiPartStatus.HEADERDELIMITER;
}

View File

@ -148,23 +148,40 @@ public class HttpPostRequestDecoder implements InterfaceHttpPostRequestDecoder {
/**
* Check from the request ContentType if this request is a Multipart request.
* @return the multipartDataBoundary if it exists, else null
* @return an array of String if multipartDataBoundary exists with the multipartDataBoundary
* as first element, charset if any as second (missing if not set), else null
*/
protected static String getMultipartDataBoundary(String contentType) {
// Check if Post using "multipart/form-data; boundary=--89421926422648"
protected static String[] getMultipartDataBoundary(String contentType) {
// Check if Post using "multipart/form-data; boundary=--89421926422648 [; charset=xxx]"
String[] headerContentType = splitHeaderContentType(contentType);
if (headerContentType[0].toLowerCase().startsWith(
HttpHeaders.Values.MULTIPART_FORM_DATA.toString()) &&
headerContentType[1].toLowerCase().startsWith(
HttpHeaders.Values.BOUNDARY.toString())) {
String[] boundary = StringUtil.split(headerContentType[1], '=');
HttpHeaders.Values.MULTIPART_FORM_DATA.toString())) {
int mrank = 1, crank = 2;
if (headerContentType[1].toLowerCase().startsWith(
HttpHeaders.Values.BOUNDARY.toString())) {
mrank = 1;
crank = 2;
} else if (headerContentType[2].toLowerCase().startsWith(
HttpHeaders.Values.BOUNDARY.toString())) {
mrank = 2;
crank = 1;
} else {
return null;
}
String[] boundary = StringUtil.split(headerContentType[mrank], '=');
if (boundary.length != 2) {
throw new ErrorDataDecoderException("Needs a boundary value");
}
return "--" + boundary[1];
} else {
return null;
if (headerContentType[crank].toLowerCase().startsWith(
HttpHeaders.Values.CHARSET.toString())) {
String[] charset = StringUtil.split(headerContentType[crank], '=');
if (charset.length > 1) {
return new String[] {"--" + boundary[1], charset[1]};
}
}
return new String[] {"--" + boundary[1]};
}
return null;
}
@Override
@ -228,26 +245,37 @@ public class HttpPostRequestDecoder implements InterfaceHttpPostRequestDecoder {
}
/**
* Split the very first line (Content-Type value) in 2 Strings
* Split the very first line (Content-Type value) in 3 Strings
*
* @return the array of 2 Strings
* @return the array of 3 Strings
*/
private static String[] splitHeaderContentType(String sb) {
int aStart;
int aEnd;
int bStart;
int bEnd;
int cStart;
int cEnd;
aStart = HttpPostBodyUtil.findNonWhitespace(sb, 0);
aEnd = sb.indexOf(';');
if (aEnd == -1) {
return new String[] { sb, "" };
return new String[] { sb, "", "" };
}
bStart = HttpPostBodyUtil.findNonWhitespace(sb, aEnd + 1);
if (sb.charAt(aEnd - 1) == ' ') {
aEnd--;
}
bStart = HttpPostBodyUtil.findNonWhitespace(sb, aEnd + 1);
bEnd = HttpPostBodyUtil.findEndOfString(sb);
return new String[] { sb.substring(aStart, aEnd), sb.substring(bStart, bEnd) };
bEnd = sb.indexOf(';', bStart);
if (bEnd == -1) {
bEnd = HttpPostBodyUtil.findEndOfString(sb);
return new String[] { sb.substring(aStart, aEnd), sb.substring(bStart, bEnd), "" };
}
cStart = HttpPostBodyUtil.findNonWhitespace(sb, bEnd + 1);
if (sb.charAt(bEnd - 1) == ' ') {
bEnd--;
}
cEnd = HttpPostBodyUtil.findEndOfString(sb);
return new String[] { sb.substring(aStart, aEnd), sb.substring(bStart, bEnd), sb.substring(cStart, cEnd) };
}
/**