From 99973b7c98071e95480949e8c4c917aa689a7b01 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Thu, 14 Jul 2016 17:50:39 +0200 Subject: [PATCH] Fixed file upload --- Zutil.iml | 1 + src/zutil/io/BufferedBoundaryInputStream.java | 47 ++++++++++--------- src/zutil/net/http/HttpClient.java | 23 ++++----- src/zutil/net/http/HttpHeaderParser.java | 4 +- src/zutil/net/http/HttpServer.java | 4 +- .../http/multipart/MultipartFileField.java | 3 -- .../net/http/multipart/MultipartParser.java | 9 +--- .../io/BufferedBoundaryInputStreamTest.java | 21 +++++++++ 8 files changed, 61 insertions(+), 51 deletions(-) diff --git a/Zutil.iml b/Zutil.iml index 66692df..b0bd30d 100755 --- a/Zutil.iml +++ b/Zutil.iml @@ -5,6 +5,7 @@ + diff --git a/src/zutil/io/BufferedBoundaryInputStream.java b/src/zutil/io/BufferedBoundaryInputStream.java index b31f551..b63e67e 100755 --- a/src/zutil/io/BufferedBoundaryInputStream.java +++ b/src/zutil/io/BufferedBoundaryInputStream.java @@ -157,14 +157,16 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ * Skips over the closest boundary */ public void next() throws IOException { + // read data until we find the next boundary or get to the end of the stream + if (buf_bound_pos < 0) { + while (fillBuffer() >= 0 && buf_bound_pos < 0) + buf_pos = buf_end; + } + if (buf_bound_pos >= 0){ // is boundary in buffer? buf_pos += boundary.length; searchNextBoundary(); } - else { // read data until we find the next boundary or get to the end of the stream - while (buf_bound_pos < 0 && fillBuffer() >= 0) - buf_pos = buf_end; - } } @@ -236,9 +238,6 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ // Do we need to fill the buffer if(buf_pos < buf_end-boundary.length) return 0; - // is there any data available - if(leftover <= 0 && super.available() <= 0) - return -1; // EOF // Move the end of the buffer to the start to not miss any split boundary if (leftover > 0 && buf_pos != 0) @@ -247,12 +246,16 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ buf_end = leftover; // Copy in new data from the stream - int n = super.read(buffer, buf_end, buffer.length-buf_end); - if (n >= 0) - buf_end = buf_end + n; + int n = -1; + if (super.available() > 0) { // is there any data available + n = super.read(buffer, buf_end, buffer.length - buf_end); + if (n >= 0) + buf_end = leftover = buf_end + n; + } + // Update boundary position searchNextBoundary(); - return ((n < 0 && this.available() > 0) ? 0 : n); + return ((leftover > 0 && n < 0) ? 0 : n); } /** @@ -260,18 +263,16 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ */ private void searchNextBoundary(){ // No need to check for boundary if buffer is smaller than the boundary length - if (this.available() >= boundary.length) { - for (int i = buf_pos; i < buf_end; i++) { - for (int b = 0; b < boundary.length; b++) { - if (buffer[i + b] != boundary[b]) - break; - else if (b == boundary.length - 1) { - buf_bound_pos = i; - return; - } - } - } - } + for (int i = buf_pos; i <= buf_end-boundary.length; i++) { + for (int b = 0; b < boundary.length; b++) { + if (buffer[i + b] != boundary[b]) + break; + else if (b == boundary.length - 1) { + buf_bound_pos = i; + return; + } + } + } buf_bound_pos = -1; } } diff --git a/src/zutil/net/http/HttpClient.java b/src/zutil/net/http/HttpClient.java index e8316cd..92163fb 100755 --- a/src/zutil/net/http/HttpClient.java +++ b/src/zutil/net/http/HttpClient.java @@ -26,10 +26,7 @@ package zutil.net.http; import zutil.net.http.HttpPrintStream.HttpMessageType; -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.net.Socket; import java.net.URL; import java.util.HashMap; @@ -54,7 +51,7 @@ public class HttpClient implements AutoCloseable{ // Response variables private HttpHeaderParser rspHeader; - private BufferedInputStream rspReader; + private InputStream rspStream; @@ -127,10 +124,10 @@ public class HttpClient implements AutoCloseable{ request.close(); // Response - if(rspHeader != null || rspReader != null) // Close previous request + if(rspHeader != null || rspStream != null) // Close previous request this.close(); - rspReader = new BufferedInputStream(conn.getInputStream()); - rspHeader = new HttpHeaderParser( rspReader ); + rspStream = new BufferedInputStream(conn.getInputStream()); + rspHeader = new HttpHeaderParser(rspStream); return rspHeader; } @@ -138,15 +135,15 @@ public class HttpClient implements AutoCloseable{ public HttpHeaderParser getResponseHeader(){ return rspHeader; } - public BufferedInputStream getResponseReader(){ - return rspReader; + public InputStream getResponseInputStream(){ + return rspStream; } @Override public void close() throws IOException { - if(rspReader != null) - rspReader.close(); - rspReader = null; + if(rspStream != null) + rspStream.close(); + rspStream = null; rspHeader = null; } } diff --git a/src/zutil/net/http/HttpHeaderParser.java b/src/zutil/net/http/HttpHeaderParser.java index 44d2989..2aa5821 100755 --- a/src/zutil/net/http/HttpHeaderParser.java +++ b/src/zutil/net/http/HttpHeaderParser.java @@ -73,7 +73,7 @@ public class HttpHeaderParser { // First line if (readStatusLine) { - if( (line= IOUtil.readLine(in)) != null && !line.isEmpty() ) + if( (line=IOUtil.readLine(in)) != null && !line.isEmpty() ) parseStatusLine(header, line); else return null; @@ -102,7 +102,7 @@ public class HttpHeaderParser { * @param header the header object where the cookies will be stored. * @param statusLine the status line String */ - public static void parseStatusLine(HttpHeader header, String statusLine){ + private static void parseStatusLine(HttpHeader header, String statusLine){ // Server Response if( statusLine.startsWith("HTTP/") ){ header.setIsRequest(false); diff --git a/src/zutil/net/http/HttpServer.java b/src/zutil/net/http/HttpServer.java index 77066bf..7f93511 100755 --- a/src/zutil/net/http/HttpServer.java +++ b/src/zutil/net/http/HttpServer.java @@ -176,11 +176,11 @@ public class HttpServer extends ThreadedTCPNetworkServer{ header.getHeader("Content-Type") != null && header.getHeader("Content-Type").contains("application/x-www-form-urlencoded")) { // Reads the post data size - int post_data_length = Integer.parseInt(header.getHeader("Content-Length")); + int postDataLength = Integer.parseInt(header.getHeader("Content-Length")); // read the data StringBuilder tmpBuff = new StringBuilder(); // read the data - for (int i = 0; i < post_data_length; i++) { + for (int i = 0; i < postDataLength; i++) { tmpBuff.append((char) in.read()); } // get the variables diff --git a/src/zutil/net/http/multipart/MultipartFileField.java b/src/zutil/net/http/multipart/MultipartFileField.java index 9bec786..dc91459 100755 --- a/src/zutil/net/http/multipart/MultipartFileField.java +++ b/src/zutil/net/http/multipart/MultipartFileField.java @@ -54,9 +54,6 @@ public class MultipartFileField implements MultipartField{ this.filename = headers.get("filename"); this.contentType = headers.get(HEADER_CONTENT_TYPE); this.in = in; - - if (contentType != null && !contentType.equalsIgnoreCase("application/octet-stream")) - logger.warning("Unsupported Content-Type: "+contentType); } /** diff --git a/src/zutil/net/http/multipart/MultipartParser.java b/src/zutil/net/http/multipart/MultipartParser.java index 9ae048e..ef9ba6c 100755 --- a/src/zutil/net/http/multipart/MultipartParser.java +++ b/src/zutil/net/http/multipart/MultipartParser.java @@ -72,20 +72,13 @@ public class MultipartParser implements Iterable{ parseDelimiter(header.getHeader("Content-type")), Long.parseLong(header.getHeader("Content-Length"))); } -/* public MultipartParser(HttpServletRequest req) throws IOException { - this(req.getInputStream(), - parseDelimiter(req.getHeader("Content-type")), - req.getContentLength()); - } -*/ + private static String parseDelimiter(String contentTypeHeader){ String delimiter = contentTypeHeader.split(" *; *")[1]; delimiter = delimiter.split(" *= *")[1]; return delimiter; } - - public long getContentLength(){ return contentLength; } diff --git a/test/zutil/io/BufferedBoundaryInputStreamTest.java b/test/zutil/io/BufferedBoundaryInputStreamTest.java index 160c991..c4302a5 100755 --- a/test/zutil/io/BufferedBoundaryInputStreamTest.java +++ b/test/zutil/io/BufferedBoundaryInputStreamTest.java @@ -225,6 +225,27 @@ public class BufferedBoundaryInputStreamTest { assertFalse(in.hasNext()); } @Test + public void read_largeDataOnlyNext() throws IOException { + String data = "#aaaaaaaaaaaa#aa#aaaaaaaaaaaaaaa#"; + StringInputStream inin = new StringInputStream(data); + BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin, 10); + in.setBoundary("#"); + + in.next(); + for (int i=0; i<12; ++i) + assertEquals('a', in.read()); + assertEquals(-1, in.read()); + + in.next(); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + + in.next(); + for (int i=0; i<15; ++i) + assertEquals('a', in.read()); + assertEquals(-1, in.read()); + } + @Test public void readArr_largeData() throws IOException { String data = "aaaaaaaaaaaa#aa#aaaaaaaaaaaaaaa#"; StringInputStream inin = new StringInputStream(data);