From 6b302d1735579ac02f327b87cc99fdbfea09f61b Mon Sep 17 00:00:00 2001 From: ritchie Date: Sun, 18 Oct 2015 16:07:53 +0200 Subject: read the encode request header exact fix #240 --- core/src/main/java/fi/iki/elonen/NanoHTTPD.java | 23 +++++++++++++++++----- .../integration/GetAndPostIntegrationTest.java | 21 +++++++++++++------- 2 files changed, 32 insertions(+), 12 deletions(-) (limited to 'core') diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java index 847aee2..3c2a403 100644 --- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -495,6 +495,8 @@ public abstract class NanoHTTPD { public static final int BUFSIZE = 8192; + public static final int MAX_HEADER_SIZE = 1024; + private final TempFileManager tempFileManager; private final OutputStream outputStream; @@ -603,17 +605,17 @@ public abstract class NanoHTTPD { throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but contains less than two boundary strings."); } - final int MAX_HEADER_SIZE = 1024; byte[] part_header_buff = new byte[MAX_HEADER_SIZE]; for (int bi = 0; bi < boundary_idxs.length - 1; bi++) { fbuf.position(boundary_idxs[bi]); int len = (fbuf.remaining() < MAX_HEADER_SIZE) ? fbuf.remaining() : MAX_HEADER_SIZE; fbuf.get(part_header_buff, 0, len); - ByteArrayInputStream bais = new ByteArrayInputStream(part_header_buff, 0, len); - BufferedReader in = new BufferedReader(new InputStreamReader(bais, Charset.forName(encoding))); + BufferedReader in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(part_header_buff, 0, len), Charset.forName(encoding)), len); + int headerLines = 0; // First line is boundary string String mpline = in.readLine(); + headerLines++; if (!mpline.contains(boundary)) { throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but chunk does not start with boundary."); } @@ -621,6 +623,7 @@ public abstract class NanoHTTPD { String part_name = null, file_name = null, content_type = null; // Parse the reset of the header lines mpline = in.readLine(); + headerLines++; while (mpline != null && mpline.trim().length() > 0) { Matcher matcher = CONTENT_DISPOSITION_PATTERN.matcher(mpline); if (matcher.matches()) { @@ -640,10 +643,13 @@ public abstract class NanoHTTPD { content_type = matcher.group(2).trim(); } mpline = in.readLine(); + headerLines++; + } + int part_header_len = 0; + while (headerLines-- > 0) { + part_header_len = scipOverNewLine(part_header_buff, part_header_len); } - // Read the part data - int part_header_len = len - (int) in.skip(MAX_HEADER_SIZE); if (part_header_len >= len - 4) { throw new ResponseException(Response.Status.INTERNAL_ERROR, "Multipart header size exceeds MAX_HEADER_SIZE."); } @@ -678,6 +684,13 @@ public abstract class NanoHTTPD { } } + private int scipOverNewLine(byte[] part_header_buff, int index) { + while (part_header_buff[index] != '\n') { + index++; + } + return ++index; + } + /** * Decodes parameters in percent-encoded URI-format ( e.g. * "name=Jack%20Daniels&pass=Single%20Malt" ) and adds them to given diff --git a/core/src/test/java/fi/iki/elonen/integration/GetAndPostIntegrationTest.java b/core/src/test/java/fi/iki/elonen/integration/GetAndPostIntegrationTest.java index d2f5181..eef2f22 100644 --- a/core/src/test/java/fi/iki/elonen/integration/GetAndPostIntegrationTest.java +++ b/core/src/test/java/fi/iki/elonen/integration/GetAndPostIntegrationTest.java @@ -41,6 +41,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; @@ -51,9 +53,11 @@ import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; import org.junit.Test; import fi.iki.elonen.NanoHTTPD; +import fi.iki.elonen.NanoHTTPD.Response.Status; /** * @author Paul S. Hawke (paul.hawke@gmail.com) On: 5/19/13 at 5:36 PM @@ -81,8 +85,11 @@ public class GetAndPostIntegrationTest extends IntegrationTestBase