[#4010] Correctly handle whitespaces in HttpPostMultipartRequestDecoder
Motivation: Due not using a cast we insert 32 and not a whitespace into the String. Modifications: Correclty cast to char. Result: Correct handling of whitespaces.
This commit is contained in:
parent
d2683c3911
commit
fd27c403d3
@ -71,6 +71,11 @@ public final class HttpConstants {
|
|||||||
*/
|
*/
|
||||||
public static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8;
|
public static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Horizontal space
|
||||||
|
*/
|
||||||
|
public static final char SP_CHAR = (char) SP;
|
||||||
|
|
||||||
private HttpConstants() {
|
private HttpConstants() {
|
||||||
// Unused
|
// Unused
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ import static io.netty.buffer.Unpooled.*;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequestDecoder {
|
public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequestDecoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory used to create InterfaceHttpData
|
* Factory used to create InterfaceHttpData
|
||||||
*/
|
*/
|
||||||
@ -1732,15 +1733,15 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
|
|||||||
for (int i = 0; i < field.length(); i++) {
|
for (int i = 0; i < field.length(); i++) {
|
||||||
char nextChar = field.charAt(i);
|
char nextChar = field.charAt(i);
|
||||||
if (nextChar == HttpConstants.COLON) {
|
if (nextChar == HttpConstants.COLON) {
|
||||||
sb.append(HttpConstants.SP);
|
sb.append(HttpConstants.SP_CHAR);
|
||||||
} else if (nextChar == HttpConstants.COMMA) {
|
} else if (nextChar == HttpConstants.COMMA) {
|
||||||
sb.append(HttpConstants.SP);
|
sb.append(HttpConstants.SP_CHAR);
|
||||||
} else if (nextChar == HttpConstants.EQUALS) {
|
} else if (nextChar == HttpConstants.EQUALS) {
|
||||||
sb.append(HttpConstants.SP);
|
sb.append(HttpConstants.SP_CHAR);
|
||||||
} else if (nextChar == HttpConstants.SEMICOLON) {
|
} else if (nextChar == HttpConstants.SEMICOLON) {
|
||||||
sb.append(HttpConstants.SP);
|
sb.append(HttpConstants.SP_CHAR);
|
||||||
} else if (nextChar == HttpConstants.HT) {
|
} else if (nextChar == HttpConstants.HT) {
|
||||||
sb.append(HttpConstants.SP);
|
sb.append(HttpConstants.SP_CHAR);
|
||||||
} else if (nextChar == HttpConstants.DOUBLE_QUOTE) {
|
} else if (nextChar == HttpConstants.DOUBLE_QUOTE) {
|
||||||
// nothing added, just removes it
|
// nothing added, just removes it
|
||||||
} else {
|
} else {
|
||||||
|
@ -26,6 +26,7 @@ import io.netty.handler.codec.http.DefaultHttpRequest;
|
|||||||
import io.netty.handler.codec.http.HttpContent;
|
import io.netty.handler.codec.http.HttpContent;
|
||||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
import io.netty.handler.codec.http.HttpHeaderValues;
|
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||||
|
import io.netty.handler.codec.http.HttpHeaders;
|
||||||
import io.netty.handler.codec.http.HttpMethod;
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
import io.netty.handler.codec.http.HttpVersion;
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
import io.netty.handler.codec.http.LastHttpContent;
|
import io.netty.handler.codec.http.LastHttpContent;
|
||||||
@ -347,4 +348,33 @@ public class HttpPostRequestDecoderTest {
|
|||||||
assertFalse(decoder.getBodyHttpDatas().isEmpty());
|
assertFalse(decoder.getBodyHttpDatas().isEmpty());
|
||||||
decoder.destroy();
|
decoder.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilenameContainingSemicolon2() throws Exception {
|
||||||
|
final String boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
|
||||||
|
final DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,
|
||||||
|
"http://localhost");
|
||||||
|
req.headers().add(HttpHeaderNames.CONTENT_TYPE, "multipart/form-data; boundary=" + boundary);
|
||||||
|
// Force to use memory-based data.
|
||||||
|
final DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false);
|
||||||
|
final String data = "asdf";
|
||||||
|
final String filename = "tmp;0.txt";
|
||||||
|
final String body =
|
||||||
|
"--" + boundary + "\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\"\r\n" +
|
||||||
|
"Content-Type: image/gif\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
data + "\r\n" +
|
||||||
|
"--" + boundary + "--\r\n";
|
||||||
|
|
||||||
|
req.content().writeBytes(body.getBytes(CharsetUtil.UTF_8.name()));
|
||||||
|
// Create decoder instance to test.
|
||||||
|
final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(inMemoryFactory, req);
|
||||||
|
assertFalse(decoder.getBodyHttpDatas().isEmpty());
|
||||||
|
InterfaceHttpData part1 = decoder.getBodyHttpDatas().get(0);
|
||||||
|
assertTrue(part1 instanceof FileUpload);
|
||||||
|
FileUpload fileUpload = (FileUpload) part1;
|
||||||
|
assertEquals("tmp 0.txt", fileUpload.getFilename());
|
||||||
|
decoder.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user