diff --git a/Zutil.jar b/Zutil.jar index b5a6e74..7d8ff0e 100755 Binary files a/Zutil.jar and b/Zutil.jar differ diff --git a/src/zutil/io/IOUtil.java b/src/zutil/io/IOUtil.java index aec370b..f7e758b 100755 --- a/src/zutil/io/IOUtil.java +++ b/src/zutil/io/IOUtil.java @@ -60,10 +60,26 @@ public class IOUtil { * @param stream * @return a String with the content of the stream */ - public static String getContentString(InputStream stream) throws IOException{ + public static String getContentAsString(InputStream stream) throws IOException{ + return getContentAsString(new InputStreamReader(stream)); + } + + /** + * Reads and returns all the content of a stream as a String. + * This function will close the input stream at the end. + * + * @param reader + * @return a String with the content of the stream + */ + public static String getContentAsString(Reader reader) throws IOException{ StringBuilder str = new StringBuilder(); + BufferedReader in = null; + if(reader instanceof BufferedReader) + reader = (BufferedReader) reader; + else + in = new BufferedReader(reader); + String line; - BufferedReader in = new BufferedReader(new InputStreamReader(stream)); while((line = in.readLine()) != null){ str.append(line).append("\n"); } diff --git a/src/zutil/net/http/HttpClient.java b/src/zutil/net/http/HttpClient.java old mode 100644 new mode 100755 index 4b78365..1cb39a7 --- a/src/zutil/net/http/HttpClient.java +++ b/src/zutil/net/http/HttpClient.java @@ -39,27 +39,25 @@ import java.util.HashMap; * * @author Ziver */ -public class HttpClient { - public static enum HttpRequestType{ +public class HttpClient implements AutoCloseable{ + public static enum HttpRequestType{ GET, POST } - + + // Request variables private HttpURL url; private HttpRequestType type; private HashMap headers; private HashMap cookies; + private String data; + + // Response variables + private HttpHeaderParser rspHeader; + private BufferedReader rspReader; + - public static HttpClient POST(){ - return new HttpClient( HttpRequestType.POST ); - } - - public static HttpClient GET(){ - return new HttpClient( HttpRequestType.GET ); - } - - - private HttpClient(HttpRequestType type){ + public HttpClient(HttpRequestType type){ this.type = type; headers = new HashMap(); cookies = new HashMap(); @@ -90,7 +88,19 @@ public class HttpClient { public void setHeader( String key, String value ){ headers.put(key, value); } - + + /** + * Sets the content data that will be included in the request. + * NOTE: this will override the POST data parameter inclusion. + */ + public void setData( String data ){ + this.data = data; + } + + /** + * Will send a HTTP request to the target host. + * NOTE: any previous request connections will be closed + */ public HttpHeaderParser send() throws IOException{ Socket conn = new Socket( url.getHost(), url.getPort()); @@ -102,20 +112,40 @@ public class HttpClient { request.setCookies( cookies ); if( type == HttpRequestType.POST ){ - String data = url.getParameterString(); - request.setHeader("Content-Length", data); + String postData = null; + if(data != null) + postData = data; + else + postData = url.getParameterString(); + request.setHeader("Content-Length", ""+postData.length()); request.println(); - request.print( data ); + request.print( postData ); } else request.println(); request.close(); // Response - BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - HttpHeaderParser response = new HttpHeaderParser( in ); - conn.close(); - - return response; + if(rspHeader != null || rspReader != null) // Close previous request + this.close(); + rspReader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + rspHeader = new HttpHeaderParser( rspReader ); + + return rspHeader; } + + public HttpHeaderParser getResponseHeader(){ + return rspHeader; + } + public BufferedReader getResponseReader(){ + return rspReader; + } + + @Override + public void close() throws IOException { + if(rspReader != null) + rspReader.close(); + rspReader = null; + rspHeader = null; + } } diff --git a/src/zutil/net/http/HttpServer.java b/src/zutil/net/http/HttpServer.java index f6c238b..cad0b45 100755 --- a/src/zutil/net/http/HttpServer.java +++ b/src/zutil/net/http/HttpServer.java @@ -154,7 +154,6 @@ public class HttpServer extends ThreadedTCPNetworkServer{ out = new HttpPrintStream(socket.getOutputStream()); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); this.socket = socket; - //logger.finest("New Connection: " + socket.getInetAddress().getHostName()); } public void run(){ @@ -167,7 +166,6 @@ public class HttpServer extends ThreadedTCPNetworkServer{ try { long time = System.currentTimeMillis(); HttpHeaderParser parser = new HttpHeaderParser(in); - //logger.finest(parser.toString()); request = parser.getURLAttributes(); cookie = parser.getCookies(); @@ -231,6 +229,7 @@ public class HttpServer extends ThreadedTCPNetworkServer{ out.setHeader( "Content-Type", "text/html" ); out.setCookie( "session_id", ""+client_session.get("session_id") ); + logRequest(parser, client_session, cookie, request, time); if( parser.getRequestURL() != null && !parser.getRequestURL().isEmpty() && pages.containsKey(parser.getRequestURL()) ){ pages.get(parser.getRequestURL()).respond(out, parser, client_session, cookie, request); logRequest(parser, client_session, cookie, request, time); diff --git a/src/zutil/net/torrent/TorrentTracker.java b/src/zutil/net/torrent/TorrentTracker.java old mode 100644 new mode 100755 index dc757e7..ae4740a --- a/src/zutil/net/torrent/TorrentTracker.java +++ b/src/zutil/net/torrent/TorrentTracker.java @@ -43,7 +43,7 @@ public class TorrentTracker { // TODO: incomplete public void update() throws IOException { - HttpClient request = HttpClient.GET(); + HttpClient request = new HttpClient(HttpClient.HttpRequestType.GET); request.setURL( trackerURL ); HttpHeaderParser response = request.send(); } diff --git a/src/zutil/net/ws/soap/SOAPClientFactory.java b/src/zutil/net/ws/soap/SOAPClientFactory.java index 32dd556..3aee94e 100755 --- a/src/zutil/net/ws/soap/SOAPClientFactory.java +++ b/src/zutil/net/ws/soap/SOAPClientFactory.java @@ -32,6 +32,7 @@ import zutil.net.ws.WebServiceDef; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; +import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; @@ -47,24 +48,28 @@ public class SOAPClientFactory { * Generates a Client Object for the web service. * * @param is the class of the web service definition + * @param url is the target service url * @param intf is the class of the web service definition * @return a client Object */ @SuppressWarnings("unchecked") - public static T createClient(Class intf){ - return createClient( intf, new WebServiceDef((Class)intf) ); + public static T createClient(URL url, Class intf){ + return createClient(url, intf, + new WebServiceDef((Class)intf) ); } /** * Generates a Client Object for the web service. * * @param is the class of the web service definition + * @param url is the target service url * @param intf is the class of the web service definition * @param wsDef is the web service definition of the intf parameter * @return a client Object */ - public static T createClient(Class intf, WebServiceDef wsDef){ - T obj = WSClientFactory.createClient(intf, new SOAPClientInvocationHandler()); + public static T createClient(URL url, Class intf, WebServiceDef wsDef){ + T obj = WSClientFactory.createClient( intf, + new SOAPClientInvocationHandler(url, wsDef)); return obj; } diff --git a/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java b/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java index a951876..b427232 100755 --- a/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java +++ b/src/zutil/net/ws/soap/SOAPClientInvocationHandler.java @@ -28,7 +28,7 @@ import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; -import org.xml.sax.SAXException; +import zutil.io.IOUtil; import zutil.log.LogUtil; import zutil.net.http.HttpClient; import zutil.net.http.HttpHeaderParser; @@ -39,6 +39,7 @@ import zutil.net.ws.WebServiceDef; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; +import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; @@ -53,22 +54,46 @@ public class SOAPClientInvocationHandler implements InvocationHandler { private WebServiceDef wsDef; /** Web address of the web service */ - protected String url; - + protected URL url; + + + public SOAPClientInvocationHandler(URL url, WebServiceDef wsDef){ + this.url = url; + this.wsDef = wsDef; + } + + /** * Makes a request to the target web service */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - HttpClient request = HttpClient.POST(); + // Generate XML + Document document = genSOAPRequest((WSInterface)proxy, method.getName(), args); + String reqXml = document.asXML(); + + // Send request + HttpClient request = new HttpClient(HttpClient.HttpRequestType.POST); + request.setURL(url); + request.setData(reqXml); HttpHeaderParser response = request.send(); + String rspXml = IOUtil.getContentAsString( request.getResponseReader()); - return null; + // DEBUG + if( logger.isLoggable(Level.FINEST) ){ + System.out.println("********** Request"); + System.out.println(reqXml); + System.out.println("********** Response"); + System.out.println(rspXml); + } + + return parseSOAPResponse(rspXml); } private Document genSOAPRequest(WSInterface obj, String targetMethod, Object[] args){ + logger.fine("Sending request for "+targetMethod); Document document = DocumentHelper.createDocument(); Element envelope = document.addElement("soap:Envelope"); WSMethodDef methodDef = wsDef.getMethod( targetMethod ); diff --git a/src/zutil/net/ws/soap/SOAPHttpPage.java b/src/zutil/net/ws/soap/SOAPHttpPage.java index 97218e0..8be21e2 100755 --- a/src/zutil/net/ws/soap/SOAPHttpPage.java +++ b/src/zutil/net/ws/soap/SOAPHttpPage.java @@ -139,18 +139,17 @@ public class SOAPHttpPage implements HttpPage{ Document document = genSOAPResponse( request.get(""), obj); - OutputFormat format = OutputFormat.createCompactFormat(); + OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter( out, format ); writer.write( document ); // DEBUG if( logger.isLoggable(Level.FINEST) ){ - OutputFormat format2 = OutputFormat.createPrettyPrint(); - System.err.println("********** Request"); - System.err.println(request); + System.out.println("********** Request"); + System.out.println(request); System.out.println("********** Response"); - writer = new XMLWriter( System.out, format2 ); + writer = new XMLWriter( System.out, format ); writer.write( document ); } } catch (Exception e) { diff --git a/src/zutil/plugin/PluginManager.java b/src/zutil/plugin/PluginManager.java index 2cf7a26..728ff66 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.getContentString(file.getInputStream())); + DataNode node = JSONParser.read(IOUtil.getContentAsString(file.getInputStream())); log.fine("Found plugin: "+file.getPath()); PluginData plugin = new PluginData(node); diff --git a/test/zutil/test/SOAPClientTest.java b/test/zutil/test/SOAPClientTest.java index f0831fb..c193154 100755 --- a/test/zutil/test/SOAPClientTest.java +++ b/test/zutil/test/SOAPClientTest.java @@ -28,15 +28,17 @@ import zutil.log.LogUtil; import zutil.net.ws.WSInterface; import zutil.net.ws.soap.SOAPClientFactory; +import java.net.MalformedURLException; +import java.net.URL; import java.util.logging.Level; public class SOAPClientTest { - public static void main(String[] args) throws InstantiationException, IllegalAccessException{ + public static void main(String[] args) throws InstantiationException, IllegalAccessException, MalformedURLException { LogUtil.setGlobalLevel(Level.ALL); LogUtil.setFormatter("", new CompactLogFormatter()); - TestClient intf = SOAPClientFactory.createClient(TestClient.class); + TestClient intf = SOAPClientFactory.createClient(new URL("http://localhost:3289"), TestClient.class); intf.m(); intf.c(); }