diff --git a/Zutil.iml b/Zutil.iml index 0848f64..66692df 100755 --- a/Zutil.iml +++ b/Zutil.iml @@ -26,6 +26,7 @@ + diff --git a/lib/commons-io-1.4.jar b/lib/commons-io-1.4.jar deleted file mode 100644 index 133dc6c..0000000 Binary files a/lib/commons-io-1.4.jar and /dev/null differ diff --git a/lib/commons-io-2.5.jar b/lib/commons-io-2.5.jar new file mode 100755 index 0000000..1234918 Binary files /dev/null and b/lib/commons-io-2.5.jar differ diff --git a/src/zutil/io/IOUtil.java b/src/zutil/io/IOUtil.java index 05c87de..86f3c2b 100755 --- a/src/zutil/io/IOUtil.java +++ b/src/zutil/io/IOUtil.java @@ -41,7 +41,7 @@ public class IOUtil { * @param stream * @return the stream contents */ - public static byte[] getContent(InputStream stream) throws IOException{ + public static byte[] readContent(InputStream stream) throws IOException{ DynamicByteArrayStream dyn_buff = new DynamicByteArrayStream(); byte[] buff = new byte[8192]; int len = 0; @@ -60,8 +60,8 @@ public class IOUtil { * @param stream * @return a String with the content of the stream */ - public static String getContentAsString(InputStream stream) throws IOException{ - return getContentAsString(new InputStreamReader(stream)); + public static String readContentAsString(InputStream stream) throws IOException{ + return readContentAsString(new InputStreamReader(stream)); } /** @@ -71,7 +71,7 @@ public class IOUtil { * @param reader * @return a String with the content of the stream */ - public static String getContentAsString(Reader reader) throws IOException{ + public static String readContentAsString(Reader reader) throws IOException{ StringBuilder str = new StringBuilder(); BufferedReader in = null; if(reader instanceof BufferedReader) @@ -89,7 +89,8 @@ public class IOUtil { } /** - * Reads on line terminated by a new line or carriage return from a stream. + * Reads one line terminated by a new line or carriage return from a stream. + * Will only read ASCII based char streams. * * @param in the stream to read from * @return a String that contains one line excluding line terminating @@ -106,6 +107,26 @@ public class IOUtil { return null; // End of the stream return str.toString(); } + /** + * Reads one line terminated by a new line or carriage return from a Reader. + * Will only read ASCII based char streams. + * + * @param in the Reader to read from + * @return a String that contains one line excluding line terminating + * characters, null if it is the end of the stream + */ + public static String readLine(Reader in) throws IOException { + StringBuilder str = new StringBuilder(80); + int c = 0; + while ((c=in.read()) >= 0 && (c != '\n') && (c != '\r')) + str.append((char)c); + if (c == '\r') + in.read(); // if the last char is carriage return we assume the next char in the stream will be new line so skip it + if (c == -1 && str.length() == 0) + return null; // End of the stream + return str.toString(); + } + /** * Copies all data from one InputStream to another OutputStream. diff --git a/src/zutil/io/file/FileUtil.java b/src/zutil/io/file/FileUtil.java index 658d83d..1debbe5 100755 --- a/src/zutil/io/file/FileUtil.java +++ b/src/zutil/io/file/FileUtil.java @@ -163,7 +163,7 @@ public class FileUtil { } public static byte[] getByteContent(File file) throws IOException { InputStream in = new FileInputStream(file); - byte[] data = IOUtil.getContent(in); + byte[] data = IOUtil.readContent(in); in.close(); return data; } @@ -176,7 +176,7 @@ public class FileUtil { */ public static String getContent(URL url) throws IOException{ InputStream in = url.openStream(); - String data = new String(IOUtil.getContent(in)); + String data = new String(IOUtil.readContent(in)); in.close(); return data; } diff --git a/src/zutil/net/FTPClient.java b/src/zutil/net/FTPClient.java old mode 100644 new mode 100755 index c7e330a..9bc3d17 --- a/src/zutil/net/FTPClient.java +++ b/src/zutil/net/FTPClient.java @@ -175,7 +175,7 @@ public class FTPClient extends Thread{ BufferedInputStream data_in = getDataInputStream(); sendCommand("NLST "+path); - String data = new String(IOUtil.getContent(data_in)); + String data = new String(IOUtil.readContent(data_in)); data_in.close(); readCommand(); @@ -194,7 +194,7 @@ public class FTPClient extends Thread{ BufferedInputStream data_in = getDataInputStream(); sendCommand("LIST "+path); - String data = new String(IOUtil.getContent(data_in)); + String data = new String(IOUtil.readContent(data_in)); data_in.close(); readCommand(); diff --git a/src/zutil/net/http/HttpClient.java b/src/zutil/net/http/HttpClient.java index 1cb39a7..e8316cd 100755 --- a/src/zutil/net/http/HttpClient.java +++ b/src/zutil/net/http/HttpClient.java @@ -26,6 +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; @@ -52,8 +53,8 @@ public class HttpClient implements AutoCloseable{ private String data; // Response variables - private HttpHeaderParser rspHeader; - private BufferedReader rspReader; + private HttpHeaderParser rspHeader; + private BufferedInputStream rspReader; @@ -128,7 +129,7 @@ public class HttpClient implements AutoCloseable{ // Response if(rspHeader != null || rspReader != null) // Close previous request this.close(); - rspReader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + rspReader = new BufferedInputStream(conn.getInputStream()); rspHeader = new HttpHeaderParser( rspReader ); return rspHeader; @@ -137,7 +138,7 @@ public class HttpClient implements AutoCloseable{ public HttpHeaderParser getResponseHeader(){ return rspHeader; } - public BufferedReader getResponseReader(){ + public BufferedInputStream getResponseReader(){ return rspReader; } diff --git a/src/zutil/net/http/HttpHeader.java b/src/zutil/net/http/HttpHeader.java index 460e836..a0af5ae 100755 --- a/src/zutil/net/http/HttpHeader.java +++ b/src/zutil/net/http/HttpHeader.java @@ -26,6 +26,8 @@ package zutil.net.http; import zutil.converter.Converter; +import java.io.BufferedReader; +import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; @@ -37,6 +39,7 @@ public class HttpHeader { private HashMap urlAttributes; private float version; private int httpCode; + private InputStream in; // Parameters private HashMap headers; @@ -51,13 +54,13 @@ public class HttpHeader { /** - * @return true if this header represents a server response + * @return true if this header represents a server response */ public boolean isResponse(){ return !request; } /** - * @return true if this header represents a client request + * @return true if this header represents a client request */ public boolean isRequest(){ return request; @@ -103,47 +106,47 @@ public class HttpHeader { return null; } /** - * @return a Iterator with all defined url keys + * @return a Iterator with all defined url keys */ public Iterator getURLAttributeKeys(){ return urlAttributes.keySet().iterator(); } /** - * Returns the URL attribute value of the given name. - * - * returns null if there is no such attribute + * @return the URL attribute value of the given name. null if there is no such attribute */ public String getURLAttribute(String name){ return urlAttributes.get( name ); } /** - * @return a Iterator with all defined headers + * @return a Iterator with all defined headers */ public Iterator getHeaderKeys(){ return headers.keySet().iterator(); } /** - * Returns the HTTP attribute value of the given name. - * - * returns null if there is no such attribute + * @return the HTTP attribute value of the given name. null if there is no such attribute */ public String getHeader(String name){ return headers.get( name.toUpperCase() ); } /** - * @return a Iterator with all defined cookies + * @return a Iterator with all defined cookies */ public Iterator getCookieKeys(){ return cookies.keySet().iterator(); } /** - * Returns the cookie value of the given name. - * - * returns null if there is no such attribute + * @return the cookie value of the given name. null if there is no such attribute. */ public String getCookie(String name){ return cookies.get( name ); } + /** + * @return a Reader that contains the body of the http request. + */ + public InputStream getInputStream(){ + return in; + } protected void setIsRequest(boolean request) { this.request = request; } @@ -159,6 +162,9 @@ public class HttpHeader { protected void setRequestURL(String url){ this.url = url.trim().replaceAll("//", "/"); } + protected void setInputStream(InputStream in){ + this.in = in; + } protected HashMap getHeaderMap(){ return headers; diff --git a/src/zutil/net/http/HttpHeaderParser.java b/src/zutil/net/http/HttpHeaderParser.java index 3c5e4ce..44d2989 100755 --- a/src/zutil/net/http/HttpHeaderParser.java +++ b/src/zutil/net/http/HttpHeaderParser.java @@ -24,17 +24,18 @@ package zutil.net.http; +import com.mysql.jdbc.Buffer; import zutil.StringUtil; +import zutil.io.IOUtil; +import zutil.io.StringInputStream; import zutil.parser.URLDecoder; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; +import java.io.*; import java.util.Map; import java.util.regex.Pattern; public class HttpHeaderParser { - public static final String HEADER_COOKIE = "COOKIE"; + private static final String HEADER_COOKIE = "COOKIE"; private static final Pattern PATTERN_COLON = Pattern.compile(":"); private static final Pattern PATTERN_EQUAL = Pattern.compile("="); @@ -42,7 +43,7 @@ public class HttpHeaderParser { private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";"); - private BufferedReader in; + private InputStream in; private boolean readStatusLine; @@ -51,8 +52,8 @@ public class HttpHeaderParser { * * @param in is the stream */ - public HttpHeaderParser(BufferedReader in){ - this.in = in; + public HttpHeaderParser(InputStream in){ + this.in = in; this.readStatusLine = true; } @@ -62,28 +63,29 @@ public class HttpHeaderParser { * @param in is the String */ public HttpHeaderParser(String in){ - this(new BufferedReader(new StringReader(in))); + this(new StringInputStream(in)); } public HttpHeader read() throws IOException { HttpHeader header = new HttpHeader(); - String line = null; + String line; // First line if (readStatusLine) { - if( (line=in.readLine()) != null && !line.isEmpty() ) + if( (line= IOUtil.readLine(in)) != null && !line.isEmpty() ) parseStatusLine(header, line); else return null; } // Read header body - while( (line=in.readLine()) != null && !line.isEmpty() ){ - parseHeaderLine(header, line); + while( (line=IOUtil.readLine(in)) != null && !line.isEmpty() ){ + parseHeaderLine(header.getHeaderMap(), line); } + // Post processing parseHeaderValue(header.getCookieMap(), header.getHeader(HEADER_COOKIE)); - + header.setInputStream(in); return header; } @@ -119,7 +121,7 @@ public class HttpHeaderParser { if(index > -1){ header.setRequestURL( statusLine.substring(0, index)); statusLine = statusLine.substring( index+1, statusLine.length()); - parseURLParameters(header, statusLine); + parseURLParameters(header.getUrlAttributeMap(), statusLine); } else{ header.setRequestURL(statusLine); @@ -128,14 +130,16 @@ public class HttpHeaderParser { } /** - * Parses a http key value paired header line + * Parses a http key value paired header line. + * Note that all header keys will be stored with + * uppercase notation to make them case insensitive. * - * @param header the header object where the cookies will be stored. + * @param map a map where the header key(Uppercase) and value will be stored. * @param line is the next line in the header */ - public static void parseHeaderLine(HttpHeader header, String line){ + public static void parseHeaderLine(Map map, String line){ String[] data = PATTERN_COLON.split( line, 2 ); - header.getHeaderMap().put( + map.put( data[0].trim().toUpperCase(), // Key (data.length>1 ? data[1] : "").trim()); //Value } @@ -160,20 +164,30 @@ public class HttpHeaderParser { } } + /** * Parses a string with variables from a get or post request that was sent from a client * - * @param header the header object where the cookies will be stored. + * @param header the header object where the url attributes key and value will be stored. * @param urlAttributes is the String containing all the attributes */ public static void parseURLParameters(HttpHeader header, String urlAttributes){ + parseURLParameters(header.getUrlAttributeMap(), urlAttributes); + } + /** + * Parses a string with variables from a get or post request that was sent from a client + * + * @param map a map where the url attributes key and value will be stored. + * @param urlAttributes is the String containing all the attributes + */ + public static void parseURLParameters(Map map, String urlAttributes){ String[] tmp; urlAttributes = URLDecoder.decode(urlAttributes); // get the variables String[] data = PATTERN_AND.split( urlAttributes ); for(String element : data){ tmp = PATTERN_EQUAL.split(element, 2); - header.getUrlAttributeMap().put( + map.put( tmp[0].trim(), // Key (tmp.length>1 ? tmp[1] : "").trim()); //Value } diff --git a/src/zutil/net/http/HttpServer.java b/src/zutil/net/http/HttpServer.java index 60f60a2..77066bf 100755 --- a/src/zutil/net/http/HttpServer.java +++ b/src/zutil/net/http/HttpServer.java @@ -29,10 +29,7 @@ import zutil.log.LogUtil; import zutil.net.threaded.ThreadedTCPNetworkServer; import zutil.net.threaded.ThreadedTCPNetworkServerThread; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.net.Socket; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -151,12 +148,12 @@ public class HttpServer extends ThreadedTCPNetworkServer{ */ protected class HttpServerThread implements ThreadedTCPNetworkServerThread{ private HttpPrintStream out; - private BufferedReader in; + private BufferedInputStream in; private Socket socket; public HttpServerThread(Socket socket) throws IOException{ out = new HttpPrintStream(socket.getOutputStream()); - in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + in = new BufferedInputStream(socket.getInputStream()); this.socket = socket; } @@ -175,30 +172,19 @@ public class HttpServer extends ThreadedTCPNetworkServer{ String tmp = null; //******* Read in the post data if available - if (header.getHeader("Content-Length") != null) { + if (header.getHeader("Content-Length") != null && + header.getHeader("Content-Type") != null && + header.getHeader("Content-Type").contains("application/x-www-form-urlencoded")) { // Reads the post data size - tmp = header.getHeader("Content-Length"); - int post_data_length = Integer.parseInt(tmp); + int post_data_length = 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++) { tmpBuff.append((char) in.read()); } - - tmp = header.getHeader("Content-Type"); - if (tmp.contains("application/x-www-form-urlencoded")) { - // get the variables - HttpHeaderParser.parseURLParameters(header, tmpBuff.toString()); - } else if (tmp.contains("application/soap+xml") || - tmp.contains("text/xml") || - tmp.contains("text/plain")) { - // save the variables - header.getUrlAttributeMap().put("", tmpBuff.toString()); - } else if (tmp.contains("multipart/form-data")) { - // TODO: File upload - throw new UnsupportedOperationException("HTTP Content-Type 'multipart-form-data' not supported."); - } + // get the variables + HttpHeaderParser.parseURLParameters(header, tmpBuff.toString()); } //**************************** HANDLE REQUEST ********************************* diff --git a/src/zutil/net/http/multipart/MultipartFileField.java b/src/zutil/net/http/multipart/MultipartFileField.java index 142da73..9bec786 100755 --- a/src/zutil/net/http/multipart/MultipartFileField.java +++ b/src/zutil/net/http/multipart/MultipartFileField.java @@ -25,10 +25,13 @@ package zutil.net.http.multipart; import zutil.io.IOUtil; +import zutil.log.LogUtil; import java.io.*; -import java.util.HashMap; import java.util.Map; +import java.util.logging.Logger; + +import static zutil.net.http.multipart.MultipartParser.HEADER_CONTENT_TYPE; /** @@ -37,16 +40,23 @@ import java.util.Map; * @author Ziver */ public class MultipartFileField implements MultipartField{ + private static final Logger logger = LogUtil.getLogger(); + private String fieldname; private String filename; private String contentType; + private byte[] content; private InputStream in; - protected MultipartFileField(String name, String filename, String contentType, BufferedReader in) throws IOException { - this.fieldname = name; - this.filename = filename; - this.contentType = contentType; + protected MultipartFileField(Map headers, InputStream in) throws IOException { + this.fieldname = headers.get("name"); + 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); } /** @@ -71,19 +81,42 @@ public class MultipartFileField implements MultipartField{ return contentType; } - public InputStream getInputStream(){ - return in; + + + /** + * First time this method is called the contents of the + * file will be read into a byte array and returned. + * Subsequent calls will just return the array without + * reading any more data from the stream. + * + * Note: Only one of the methods {@link #getContent()} or + * {@link #saveToFile(File)} can be used as they will consume the data in the stream. + * + * @return a byte array containing the file data. null if the Stream has already been consumed + */ + public byte[] getContent() throws IOException { + if (in != null) { + content = IOUtil.readContent(in); + in = null; // reset InputStream + } + return content; } - /** - * Reads in all data and save it into the specified file - * + /** + * Reads in all data and save it into the specified file. + * + * Note: Only one of the methods {@link #getContent()} or + * {@link #saveToFile(File)} can be used as they will consume the data in the stream. + * * @param file is the new file where the data will be stored */ public void saveToFile(File file) throws IOException { + if (in == null) + throw new IOException("Stream already consumed."); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file)); IOUtil.copyStream(in, out); out.close(); + in = null; // reset InputStream } } diff --git a/src/zutil/net/http/multipart/MultipartParser.java b/src/zutil/net/http/multipart/MultipartParser.java index 61f62bc..9ae048e 100755 --- a/src/zutil/net/http/multipart/MultipartParser.java +++ b/src/zutil/net/http/multipart/MultipartParser.java @@ -49,8 +49,8 @@ import java.util.logging.Logger; */ public class MultipartParser implements Iterable{ private static final Logger logger = LogUtil.getLogger(); - private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; - private static final String HEADER_CONTENT_TYPE = "Content-Type"; + protected static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition".toUpperCase(); + protected static final String HEADER_CONTENT_TYPE = "Content-Type".toUpperCase(); /** This is the delimiter that will separate the fields */ private String delimiter; @@ -67,17 +67,17 @@ public class MultipartParser implements Iterable{ this.delimiter = delimiter; this.contentLength = length; } - public MultipartParser(InputStream in, HttpHeader header){ - this(in, + public MultipartParser(HttpHeader header){ + this(header.getInputStream(), parseDelimiter(header.getHeader("Content-type")), - Long.parseLong( header.getHeader("Content-Length"))); + Long.parseLong(header.getHeader("Content-Length"))); } - public MultipartParser(HttpServletRequest req) throws IOException { +/* 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]; @@ -102,22 +102,20 @@ public class MultipartParser implements Iterable{ protected class MultiPartIterator implements Iterator{ private BufferedBoundaryInputStream boundaryIn; - private BufferedReader buffIn; - private HttpHeaderParser parser; private boolean firstIteration; protected MultiPartIterator(){ this.boundaryIn = new BufferedBoundaryInputStream(in); - this.buffIn = new BufferedReader(new InputStreamReader(boundaryIn)); - this.parser = new HttpHeaderParser(buffIn); - this.parser.setReadStatusLine(false); this.boundaryIn.setBoundary("--"+delimiter); firstIteration = true; } + /** + * TODO: there is a bug where this returns true after the last MultiPart as it cannot read ahead. So use next() != null instead + */ @Override public boolean hasNext() { try { @@ -137,31 +135,26 @@ public class MultipartParser implements Iterable{ this.boundaryIn.setBoundary("\n--"+delimiter); // Add new-line to boundary after the first iteration firstIteration = false; } - String tmp = buffIn.readLine(); // read the new line after the delimiter + String tmp = IOUtil.readLine(boundaryIn); // read the new line after the delimiter if (tmp == null || tmp.equals("--")) return null; - HttpHeader header = parser.read(); - String disposition = header.getHeader(HEADER_CONTENT_DISPOSITION); - String contentType = header.getHeader("Content-Type"); - if (contentType != null && !contentType.equalsIgnoreCase("application/octet-stream")) - logger.warning("Unsupported ontent-Type: "+contentType); + // Read Headers + HashMap headers = new HashMap<>(); + while ((tmp=IOUtil.readLine(boundaryIn)) != null && !tmp.isEmpty()) + HttpHeaderParser.parseHeaderLine(headers, tmp); + + // Parse + String disposition = headers.get(HEADER_CONTENT_DISPOSITION); if (disposition != null){ - HashMap map = new HashMap<>(); - HttpHeaderParser.parseHeaderValue(map, disposition); - if (map.containsKey("form-data")){ - if (map.containsKey("filename")){ - MultipartFileField field = new MultipartFileField( - map.get("name"), - map.get("filename"), - contentType, - buffIn); + HttpHeaderParser.parseHeaderValue(headers, disposition); + if (headers.containsKey("form-data")){ + if (headers.containsKey("filename")){ + MultipartFileField field = new MultipartFileField(headers, boundaryIn); return field; } else{ - MultipartStringField field = new MultipartStringField( - map.get("name"), - buffIn); + MultipartStringField field = new MultipartStringField(headers, boundaryIn); return field; } } diff --git a/src/zutil/net/http/multipart/MultipartStringField.java b/src/zutil/net/http/multipart/MultipartStringField.java index 229bf06..bb36940 100755 --- a/src/zutil/net/http/multipart/MultipartStringField.java +++ b/src/zutil/net/http/multipart/MultipartStringField.java @@ -2,9 +2,11 @@ package zutil.net.http.multipart; import zutil.io.IOUtil; +import zutil.io.InputStreamCloser; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.util.Map; @@ -15,9 +17,9 @@ public class MultipartStringField implements MultipartField { private String name; private String value; - protected MultipartStringField(String name, BufferedReader in) throws IOException { - this.name = name; - value = in.readLine(); + protected MultipartStringField(Map headers, InputStream in) throws IOException { + this.name = headers.get("name"); + value = IOUtil.readLine(in); } @Override diff --git a/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java b/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java index b427232..ab69f25 100755 --- a/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java +++ b/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java @@ -78,7 +78,7 @@ public class SOAPClientInvocationHandler implements InvocationHandler { request.setURL(url); request.setData(reqXml); HttpHeaderParser response = request.send(); - String rspXml = IOUtil.getContentAsString( request.getResponseReader()); + String rspXml = IOUtil.readContentAsString( request.getResponseReader()); // DEBUG if( logger.isLoggable(Level.FINEST) ){ diff --git a/src/zutil/net/ws/soap/SOAPHttpPage.java b/src/zutil/net/ws/soap/SOAPHttpPage.java index 54fcb5d..0090336 100755 --- a/src/zutil/net/ws/soap/SOAPHttpPage.java +++ b/src/zutil/net/ws/soap/SOAPHttpPage.java @@ -39,6 +39,8 @@ import zutil.net.http.HttpPrintStream; import zutil.net.ws.*; import zutil.net.ws.WSReturnObject.WSValueName; +import java.io.BufferedReader; +import java.io.InputStreamReader; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.Iterator; @@ -120,6 +122,22 @@ public class SOAPHttpPage implements HttpPage{ Map request) { try { + // Read http body + StringBuilder data = null; + String contentType = headers.getHeader("Content-Type"); + if (contentType != null && + (contentType.contains("application/soap+xml") || + contentType.contains("text/xml") || + contentType.contains("text/plain"))) { + int post_data_length = Integer.parseInt(headers.getHeader("Content-Length")); + BufferedReader in = new BufferedReader(new InputStreamReader(headers.getInputStream())); + data = new StringBuilder(post_data_length); + for (int i = 0; i < post_data_length; i++) { + data.append((char) in.read()); + } + } + + // Response out.setHeader("Content-Type", "text/xml"); out.flush(); @@ -138,7 +156,7 @@ public class SOAPHttpPage implements HttpPage{ obj = ws; } - Document document = genSOAPResponse( request.get(""), obj); + Document document = genSOAPResponse( (data!=null ? data.toString() : ""), obj); OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter( out, format ); diff --git a/src/zutil/plugin/PluginManager.java b/src/zutil/plugin/PluginManager.java index fb7513e..763a705 100755 --- a/src/zutil/plugin/PluginManager.java +++ b/src/zutil/plugin/PluginManager.java @@ -70,7 +70,7 @@ public class PluginManager implements Iterable{ log.fine("Searching for plugins..."); for(FileSearcher.FileSearchItem file : search){ try { - DataNode node = JSONParser.read(IOUtil.getContentAsString(file.getInputStream())); + DataNode node = JSONParser.read(IOUtil.readContentAsString(file.getInputStream())); log.fine("Found plugin: "+file.getPath()); PluginData plugin = new PluginData(node); diff --git a/test/zutil/net/http/multipart/MultipartParserTest.java b/test/zutil/net/http/multipart/MultipartParserTest.java index c8bf27f..a33ffa6 100755 --- a/test/zutil/net/http/multipart/MultipartParserTest.java +++ b/test/zutil/net/http/multipart/MultipartParserTest.java @@ -38,6 +38,8 @@ public class MultipartParserTest { assertEquals("foo", stringField.getName()); assertEquals("bar", stringField.getValue()); //assertFalse(it.hasNext()); //TODO: does not work, how to solve this? + assertEquals(null, it.next()); + assertEquals(null, it.next()); } @Test