From a6fd8a96bf54fb369927c0375f90502c2ac3d41e Mon Sep 17 00:00:00 2001 From: houdejun214 Date: Thu, 21 Jan 2016 17:02:19 +0800 Subject: [PATCH] Set default CONTENT_TYPE when it is absent in multipart request body Motivation: I am use netty as a http server, it fail to decode some POST request when the request absent Content-Type in the multipart/form-data body. Modifications: Set content_type with default application/octet-stream to parse the uploaded file data when the Content-Type is absent in multipart request body Result: Can decode the http request as normal. --- .../HttpPostMultipartRequestDecoder.java | 11 ++++--- .../multipart/HttpPostRequestDecoderTest.java | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java index 21f36a1cde..fc58adc174 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java @@ -863,9 +863,6 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest Attribute filenameAttribute = currentFieldAttributes.get(HttpHeaderValues.FILENAME); Attribute nameAttribute = currentFieldAttributes.get(HttpHeaderValues.NAME); Attribute contentTypeAttribute = currentFieldAttributes.get(HttpHeaderNames.CONTENT_TYPE); - if (contentTypeAttribute == null) { - throw new ErrorDataDecoderException("Content-Type is absent but required"); - } Attribute lengthAttribute = currentFieldAttributes.get(HttpHeaderNames.CONTENT_LENGTH); long size; try { @@ -876,9 +873,15 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest size = 0; } try { + String contentType; + if (contentTypeAttribute != null) { + contentType = contentTypeAttribute.getValue(); + } else { + contentType = HttpPostBodyUtil.DEFAULT_BINARY_CONTENT_TYPE; + } currentFileUpload = factory.createFileUpload(request, cleanString(nameAttribute.getValue()), cleanString(filenameAttribute.getValue()), - contentTypeAttribute.getValue(), mechanism.value(), localCharset, + contentType, mechanism.value(), localCharset, size); } catch (NullPointerException e) { throw new ErrorDataDecoderException(e); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java index 72cde4a799..b5ccef3994 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java @@ -379,4 +379,34 @@ public class HttpPostRequestDecoderTest { assertEquals("tmp 0.txt", fileUpload.getFilename()); decoder.destroy(); } + + @Test + public void testMultipartRequestWithoutContentTypeBody() { + final String boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO"; + + final DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, + "http://localhost"); + + req.setDecoderResult(DecoderResult.SUCCESS); + req.headers().add(HttpHeaderNames.CONTENT_TYPE, "multipart/form-data; boundary=" + boundary); + req.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); + + // Force to use memory-based data. + final DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false); + + for (String data : Arrays.asList("", "\r", "\r\r", "\r\r\r")) { + final String body = + "--" + boundary + "\r\n" + + "Content-Disposition: form-data; name=\"file\"; filename=\"tmp-0.txt\"\r\n" + + "\r\n" + + data + "\r\n" + + "--" + boundary + "--\r\n"; + + req.content().writeBytes(body.getBytes(CharsetUtil.UTF_8)); + } + // Create decoder instance to test without any exception. + final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(inMemoryFactory, req); + assertFalse(decoder.getBodyHttpDatas().isEmpty()); + decoder.destroy(); + } }