Some progress on fileupload
This commit is contained in:
parent
f2939f819f
commit
5606f57514
17 changed files with 193 additions and 116 deletions
|
|
@ -26,6 +26,7 @@
|
|||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$MODULE_DIR$/lib" />
|
||||
<root url="jar://$USER_HOME$/.ideaLibSources/commons-fileupload-1.2.1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
|
||||
<jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" type="SOURCES" />
|
||||
|
|
|
|||
Binary file not shown.
BIN
lib/commons-io-2.5.jar
Executable file
BIN
lib/commons-io-2.5.jar
Executable file
Binary file not shown.
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
4
src/zutil/net/FTPClient.java
Normal file → Executable file
4
src/zutil/net/FTPClient.java
Normal file → Executable file
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String, String> urlAttributes;
|
||||
private float version;
|
||||
private int httpCode;
|
||||
private InputStream in;
|
||||
|
||||
// Parameters
|
||||
private HashMap<String, String> 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<String> 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<String> 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<String> 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<String,String> getHeaderMap(){
|
||||
return headers;
|
||||
|
|
|
|||
|
|
@ -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<String,String> 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<String,String> 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *********************************
|
||||
|
|
|
|||
|
|
@ -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<String,String> 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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ import java.util.logging.Logger;
|
|||
*/
|
||||
public class MultipartParser implements Iterable<MultipartField>{
|
||||
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<MultipartField>{
|
|||
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<MultipartField>{
|
|||
|
||||
protected class MultiPartIterator implements Iterator<MultipartField>{
|
||||
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<MultipartField>{
|
|||
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<String,String> 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<String,String> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<String,String> headers, InputStream in) throws IOException {
|
||||
this.name = headers.get("name");
|
||||
value = IOUtil.readLine(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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) ){
|
||||
|
|
|
|||
|
|
@ -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<String, String> 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 );
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public class PluginManager<T> implements Iterable<PluginData>{
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue