From 3508b7fdaf7312014312904acee9bebe338ce6f9 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Sat, 19 Dec 2015 13:32:34 +0100 Subject: [PATCH] Some SOAP Client progress --- Zutil.jar | Bin 1188224 -> 1189244 bytes src/zutil/io/IOUtil.java | 20 ++++- src/zutil/net/http/HttpClient.java | 74 ++++++++++++------ src/zutil/net/http/HttpServer.java | 3 +- src/zutil/net/torrent/TorrentTracker.java | 2 +- src/zutil/net/ws/soap/SOAPClientFactory.java | 13 ++- .../ws/soap/SOAPClientInvocationHandler.java | 35 +++++++-- src/zutil/net/ws/soap/SOAPHttpPage.java | 9 +-- src/zutil/plugin/PluginManager.java | 2 +- test/zutil/test/SOAPClientTest.java | 6 +- 10 files changed, 120 insertions(+), 44 deletions(-) mode change 100644 => 100755 src/zutil/net/http/HttpClient.java mode change 100644 => 100755 src/zutil/net/torrent/TorrentTracker.java diff --git a/Zutil.jar b/Zutil.jar index b5a6e746349cc1a4867c9c597b9ca173ba8b8709..7d8ff0e4d6eeeb13c9f6047bc463eba0ba888870 100755 GIT binary patch delta 23948 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 W2!ndG0~J>Y^6E7UwXq+^*?Z&pw&+hEb%w8{M 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 U6W;t5?*KO&&Rb*WZi2z^fAc0wf&c&j 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(); }