diff --git a/src/zutil/net/torrent/TorrentFile.java b/src/zutil/net/torrent/TorrentFile.java index 107c638..4e205b1 100755 --- a/src/zutil/net/torrent/TorrentFile.java +++ b/src/zutil/net/torrent/TorrentFile.java @@ -31,24 +31,18 @@ package zutil.net.torrent; */ public class TorrentFile{ private String filename; - private long length; + private long size; - public TorrentFile(String filename, long length){ + public TorrentFile(String filename, long size){ this.filename = filename; - this.length = length; + this.size = size; } public String getFilename() { return filename; } - public void setFilename(String filename) { - this.filename = filename; - } - public long getLength() { - return length; - } - public void setLength(long length) { - this.length = length; + public long getSize() { + return size; } } diff --git a/src/zutil/net/torrent/TorrentMetainfo.java b/src/zutil/net/torrent/TorrentMetainfo.java index d78e277..793f069 100755 --- a/src/zutil/net/torrent/TorrentMetainfo.java +++ b/src/zutil/net/torrent/TorrentMetainfo.java @@ -32,10 +32,13 @@ import zutil.parser.DataNode; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.text.ParseException; import java.util.ArrayList; import java.util.Iterator; public class TorrentMetainfo { + /** Name **/ + private String name; /** Comment (optional) **/ private String comment; /** Signature of the software which created the torrent (optional) **/ @@ -63,16 +66,16 @@ public class TorrentMetainfo { - public TorrentMetainfo(File torrent) throws IOException{ + public TorrentMetainfo(File torrent) throws IOException, ParseException { this(FileUtil.getContent(torrent)); } - public TorrentMetainfo(String data){ + public TorrentMetainfo(String data) throws ParseException { decode(data); } - private void decode(String data){ + private void decode(String data) throws ParseException { DataNode metainfo = BEncodedParser.read(data); // Main values @@ -91,66 +94,70 @@ public class TorrentMetainfo { // info data DataNode info = metainfo.get("info"); - String name = info.getString("name"); + name = info.getString("name"); piece_length = info.getLong("piece length"); if( info.get("private") != null ) is_private = (info.getInt("private") != 0); // Split the hashes String hashes = info.getString("pieces"); piece_hashes = new ArrayList(); - for(int i=0; i(); // Single-file torrent if( info.get("files") == null ){ - Long length = info.getLong("length"); - file_list.add( new TorrentFile(name, length) ); + Long fileSize = size = info.getLong("length"); + file_list.add( new TorrentFile(name, fileSize) ); } // Multi-file torrent else{ DataNode files = info.get("files"); for( DataNode file : files ){ - String filename = ""; + StringBuilder filename = new StringBuilder(); DataNode tmp = file.get("path"); // File in subdir if( tmp.isList() ){ Iterator it = tmp.iterator(); while( it.hasNext() ){ - filename += it.next().getString(); - if(it.hasNext()) filename += File.separator; + filename.append(it.next().getString()); + if(it.hasNext()) + filename.append(File.separator); } } // File in root dir else - filename = tmp.getString(); - Long length = file.getLong("length"); - filename = name + File.separator + filename; - file_list.add( new TorrentFile(filename, length) ); + filename.append(tmp.getString()); + Long fileSize = file.getLong("length"); + size += fileSize; + file_list.add( new TorrentFile(filename.toString(), fileSize) ); } } } + public String getName() { + return name; + } public String getComment() { return comment; } - public String getCreated_by() { + public String getCreatedBy() { return created_by; } - public long getCreation_date() { + public long getCreationDate() { return creation_date; } public String getAnnounce() { return announce; } - public ArrayList getAnnounce_list() { + public ArrayList getAnnounceList() { return announce_list; } public String getEncoding() { @@ -159,31 +166,17 @@ public class TorrentMetainfo { public long getSize() { return size; } - public long getPiece_length() { + public long getPieceLength() { return piece_length; } - public ArrayList getPiece_hashes() { + public ArrayList getPieceHashes() { return piece_hashes; } - public boolean isIs_private() { + public boolean isPrivate() { return is_private; } - public ArrayList getFile_list() { + public ArrayList getFileList() { return file_list; } - /** - * Example use - */ - public static void main(String[] args){ - try { - TorrentMetainfo tmp = new TorrentMetainfo(FileUtil.find("test.torrent")); - MultiPrintStream.out.dump(tmp); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } } diff --git a/src/zutil/net/upnp/service/UPnPContentDirectory.java b/src/zutil/net/upnp/service/UPnPContentDirectory.java index 1214198..8b9f506 100755 --- a/src/zutil/net/upnp/service/UPnPContentDirectory.java +++ b/src/zutil/net/upnp/service/UPnPContentDirectory.java @@ -153,7 +153,7 @@ public class UPnPContentDirectory implements UPnPService, HttpPage, WSInterface } - @WSDisabled + @WSIgnore public void respond(HttpPrintStream out, HttpHeader headers, Map session, Map cookie, diff --git a/src/zutil/net/ws/WSInterface.java b/src/zutil/net/ws/WSInterface.java old mode 100644 new mode 100755 index 7257a61..1857a95 --- a/src/zutil/net/ws/WSInterface.java +++ b/src/zutil/net/ws/WSInterface.java @@ -30,14 +30,16 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * - * Specifies web service parameter names and other things. + * Specifies web service definitions. Which methods that will + * be published and other related metadata. + * * Example: *
  *	private static class Test implements WSInterface{
  *		public Test(){}
  *	
  *		@WSDocumentation("blabla")
- *		@WSDLParamDocumentation("olle = an variable?")
+ *		@WSDLParamDocumentation("olle = a variable?")
  *		public void pubZ( 
  *				@WSParamName("olle") int lol) 
  *				throws Exception{ 
@@ -51,7 +53,7 @@ import java.lang.annotation.Target;
  *			....
  *		}
  *	
- *		@WSDisabled()
+ *		@WSIgnore()
  *		public void privaZ(....){ 
  *			...
  *		}		
@@ -87,13 +89,13 @@ public interface WSInterface {
 	}
 	
 	/**
-	 * Disables publication of the given method
+	 * Skipp publication of the given method
 	 * 
 	 * @author Ziver
 	 */
 	@Retention(RetentionPolicy.RUNTIME)
 	@Target(ElementType.METHOD)
-	public @interface WSDisabled { }
+	public @interface WSIgnore { }
 	
 	/**
 	 * Method or Parameter comments for the WSDL. 
diff --git a/src/zutil/net/ws/WSMethodDef.java b/src/zutil/net/ws/WSMethodDef.java
old mode 100644
new mode 100755
index 080c7aa..af22ee1
--- a/src/zutil/net/ws/WSMethodDef.java
+++ b/src/zutil/net/ws/WSMethodDef.java
@@ -228,16 +228,8 @@ public class WSMethodDef {
 	 * @param		obj 		the object the method will called on
 	 * @param 		params 		a vector with arguments
 	 */
-	public Object invoke(Object obj, Object[] params) throws Throwable{
-		try {
-			return this.method.invoke(obj, params );
-		} catch (IllegalArgumentException e) {
-			throw e;
-		} catch (IllegalAccessException e) {
-			throw e;
-		} catch (InvocationTargetException e) {
-			throw e.getCause();
-		}
+	public Object invoke(Object obj, Object[] params) throws Exception {
+		return this.method.invoke(obj, params );
 	}
 	
 	
diff --git a/src/zutil/net/ws/WebServiceDef.java b/src/zutil/net/ws/WebServiceDef.java
old mode 100644
new mode 100755
index f56c574..46cb20d
--- a/src/zutil/net/ws/WebServiceDef.java
+++ b/src/zutil/net/ws/WebServiceDef.java
@@ -57,7 +57,7 @@ public class WebServiceDef {
 		for(Method m : intf.getDeclaredMethods()){
 			// check for public methods
 			if((m.getModifiers() & Modifier.PUBLIC) > 0 && 
-					!m.isAnnotationPresent(WSInterface.WSDisabled.class)){
+					!m.isAnnotationPresent(WSInterface.WSIgnore.class)){
 				WSMethodDef method = new WSMethodDef(this, m);
 				methods.put(method.getName(), method);
 			}
diff --git a/src/zutil/net/ws/rest/RestHttpPage.java b/src/zutil/net/ws/rest/RestHttpPage.java
index 33dbbb4..3962c9c 100755
--- a/src/zutil/net/ws/rest/RestHttpPage.java
+++ b/src/zutil/net/ws/rest/RestHttpPage.java
@@ -70,7 +70,7 @@ public class RestHttpPage implements HttpPage {
     }
 
 
-    private String execute(String targetMethod, Map input) throws Throwable {
+    protected String execute(String targetMethod, Map input) throws Exception {
         if( wsDef.hasMethod(targetMethod) ){
             // Parse request
             WSMethodDef m = wsDef.getMethod(targetMethod);
@@ -82,6 +82,7 @@ public class RestHttpPage implements HttpPage {
             // Generate Response
             StringOutputStream dummyOut = new StringOutputStream();
             JSONObjectOutputStream out = new JSONObjectOutputStream(dummyOut);
+            out.enableMetaData(false);
             out.writeObject(ret);
             out.close();
             return dummyOut.toString();
@@ -103,8 +104,4 @@ public class RestHttpPage implements HttpPage {
         }
         return inputParams;
     }
-
-    private void generateResponse(){
-
-    }
 }
diff --git a/src/zutil/net/ws/soap/SOAPClientFactory.java b/src/zutil/net/ws/soap/SOAPClientFactory.java
index 87dff28..da53f74 100755
--- a/src/zutil/net/ws/soap/SOAPClientFactory.java
+++ b/src/zutil/net/ws/soap/SOAPClientFactory.java
@@ -40,19 +40,6 @@ import java.util.logging.Logger;
 public class SOAPClientFactory {
     private static Logger logger = LogUtil.getLogger();
 
-    /**
-     * 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(URL url, Class intf){
-        return createClient(url, intf,
-                new WebServiceDef((Class)intf) );
-    }
 
     /**
      * Generates a Client Object for the web service.
@@ -60,12 +47,11 @@ public class SOAPClientFactory {
      * @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(URL url, Class intf, WebServiceDef wsDef){
+    public static  T createClient(URL url, Class intf){
         T obj = WSClientFactory.createClient( intf,
-                new SOAPClientInvocationHandler(url, wsDef));
+                new SOAPClientInvocationHandler(url, new WebServiceDef(intf)));
         return obj;
     }
 
diff --git a/src/zutil/parser/BEncodedParser.java b/src/zutil/parser/BEncodedParser.java
index 449308e..ff5fc0e 100755
--- a/src/zutil/parser/BEncodedParser.java
+++ b/src/zutil/parser/BEncodedParser.java
@@ -27,6 +27,9 @@ package zutil.parser;
 import zutil.parser.DataNode.DataType;
 import zutil.struct.MutableInt;
 
+import java.nio.charset.MalformedInputException;
+import java.text.ParseException;
+
 /**
  * http://wiki.theory.org/BitTorrentSpecification
  * @author Ziver
@@ -40,7 +43,7 @@ public class BEncodedParser {
 	 * @param	data	is the data to be decoded
 	 * @return
 	 */
-	public static DataNode read(String data){
+	public static DataNode read(String data) throws ParseException {
 		return decode_BEncoded(new MutableInt(), new StringBuilder(data));
 	}
 
@@ -51,9 +54,10 @@ public class BEncodedParser {
 	 * @param	index	is the index in data to start from
 	 * @return
 	 */
-	private static DataNode decode_BEncoded(MutableInt index, StringBuilder data){
+	private static DataNode decode_BEncoded(MutableInt index, StringBuilder data) throws ParseException {
 		String tmp;
 		char c = ' ';
+        int end;
 
 		switch (data.charAt(index.i)) {
 		/**
@@ -63,7 +67,10 @@ public class BEncodedParser {
 		 */
 		case 'i':
 			index.i++;
-			tmp = data.substring(index.i, data.indexOf("e"));
+            end = data.indexOf("e", index.i);
+            if (end < 0)
+                throw new ParseException("Corrupt bEncoding", index.i);
+			tmp = data.substring(index.i, end);
 			index.i += tmp.length() + 1;
 			return new DataNode( new Long(tmp));
 		/**
@@ -97,6 +104,8 @@ public class BEncodedParser {
 			while(c != 'e'){
 				DataNode tmp2 = decode_BEncoded(index, data);
 				map.set(tmp2.getString(), decode_BEncoded(index, data));
+                if (index.i >= data.length())
+                    throw new ParseException("Incorrect bEncoding ending of element", index.i);
 				c = data.charAt(index.i);
 			}
 			index.i++;
@@ -107,10 +116,13 @@ public class BEncodedParser {
 		 * would bEncode to 11:BitTorrents.
 		 */
 		default:
-			tmp = data.substring(index.i, data.indexOf(":"));
+			end = data.indexOf(":", index.i);
+			if (end < 0)
+				throw new ParseException("Corrupt bEncoding", index.i);
+			tmp = data.substring(index.i, end);
 			int length = Integer.parseInt(tmp);
 			index.i += tmp.length() + 1;
-			String ret = data.substring(index.i, length);
+			String ret = data.substring(index.i, index.i+length);
 			index.i += length;
 			return new DataNode( ret );
 		}
diff --git a/src/zutil/parser/json/JSONObjectOutputStream.java b/src/zutil/parser/json/JSONObjectOutputStream.java
index 8f70972..1544cac 100755
--- a/src/zutil/parser/json/JSONObjectOutputStream.java
+++ b/src/zutil/parser/json/JSONObjectOutputStream.java
@@ -200,10 +200,16 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
     }
 
     public void flush() throws IOException {
-        super.flush();
         out.flush();
     }
 
+    public void close() throws IOException {
+        if (out != null) {
+            out.flush();
+            out.close();
+        }
+    }
+
 
 
     @Override public void writeBoolean(boolean v) throws IOException {
diff --git a/test/zutil/net/torrent/TorrentMetainfoTest.java b/test/zutil/net/torrent/TorrentMetainfoTest.java
new file mode 100755
index 0000000..edc6c3c
--- /dev/null
+++ b/test/zutil/net/torrent/TorrentMetainfoTest.java
@@ -0,0 +1,41 @@
+package zutil.net.torrent;
+
+import org.junit.Test;
+
+import java.text.ParseException;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by Ziver on 2016-09-27.
+ */
+public class TorrentMetainfoTest {
+
+
+    @Test
+    public void decode() throws ParseException {
+        TorrentMetainfo tmp = new TorrentMetainfo(
+                "d8:announce39:http://torrent.ubuntu.com:6969/announce13:announce-listll" +
+                        "39:http://torrent.ubuntu.com:6969/announceel44:http://ipv6.torrent.ubuntu.com:6969/announceee" +
+                        "7:comment29:Ubuntu CD releases.ubuntu.com13:creation datei1469103218e4:infod" +
+                        "6:lengthi1513308160e4:name32:ubuntu-16.04.1-desktop-amd64.iso12:piece lengthi524288e" +
+                        "6:pieces60:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaee");
+
+        assertEquals("http://torrent.ubuntu.com:6969/announce", tmp.getAnnounce());
+        assertArrayEquals(new String[]{
+                        "http://torrent.ubuntu.com:6969/announce",
+                        "http://ipv6.torrent.ubuntu.com:6969/announce"},
+                tmp.getAnnounceList().toArray());
+        assertEquals("Ubuntu CD releases.ubuntu.com", tmp.getComment());
+        assertEquals(1469103218, tmp.getCreationDate());
+        assertEquals(1513308160, tmp.getSize());
+        assertEquals("ubuntu-16.04.1-desktop-amd64.iso", tmp.getName());
+        assertEquals(1, tmp.getFileList().size());
+        assertEquals("ubuntu-16.04.1-desktop-amd64.iso", tmp.getFileList().get(0).getFilename());
+        assertEquals(524288, tmp.getPieceLength());
+        assertEquals(3, tmp.getPieceHashes().size());
+        assertEquals("aaaaaaaaaaaaaaaaaaaa", tmp.getPieceHashes().get(0));
+        assertEquals("aaaaaaaaaaaaaaaaaaaa", tmp.getPieceHashes().get(1));
+        assertEquals("aaaaaaaaaaaaaaaaaaaa", tmp.getPieceHashes().get(2));
+    }
+}
\ No newline at end of file
diff --git a/test/zutil/net/ws/rest/RestHttpPageTest.java b/test/zutil/net/ws/rest/RestHttpPageTest.java
new file mode 100755
index 0000000..96cab7e
--- /dev/null
+++ b/test/zutil/net/ws/rest/RestHttpPageTest.java
@@ -0,0 +1,49 @@
+package zutil.net.ws.rest;
+
+import org.junit.Test;
+import zutil.net.ws.WSInterface;
+
+import java.util.HashMap;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by Ziver on 2016-09-27.
+ */
+public class RestHttpPageTest {
+
+    public static class TestClass implements WSInterface{
+        public String hello(){
+            return "hello world";
+        }
+    }
+
+    @Test
+    public void noInput() throws Throwable {
+        RestHttpPage rest = new RestHttpPage(new TestClass());
+
+        HashMap input = new HashMap<>();
+        String output = rest.execute("hello", input);
+        assertEquals("\"hello world\"\n", output);
+    }
+
+
+
+
+    public static class TestEchoClass implements WSInterface{
+        public String echo(@WSParamName("input") String input){
+            return "echo: "+input;
+        }
+    }
+
+    @Test
+    public void oneInput() throws Throwable {
+        RestHttpPage rest = new RestHttpPage(new TestEchoClass());
+
+        HashMap input = new HashMap<>();
+        input.put("input", "test input");
+        String output = rest.execute("echo", input);
+        assertEquals("\"echo: test input\"\n", output);
+    }
+
+}
\ No newline at end of file
diff --git a/test/zutil/net/ws/soap/SOAPTest.java b/test/zutil/net/ws/soap/SOAPTest.java
index 2988236..e49750c 100755
--- a/test/zutil/net/ws/soap/SOAPTest.java
+++ b/test/zutil/net/ws/soap/SOAPTest.java
@@ -38,10 +38,6 @@ import zutil.parser.wsdl.WSDLWriter;
 public class SOAPTest {
     /************************* TEST CASES ************************/
 	public static void main(String[] args){
-		new SOAPTest();
-	}
-	
-	public SOAPTest(){
 		WebServiceDef wsDef = new WebServiceDef( MainSOAPClass.class );
 		SOAPHttpPage soap = new SOAPHttpPage( wsDef );
 
@@ -84,7 +80,7 @@ public class SOAPTest {
 	public static class SpecialReturnClass extends WSReturnObject{
 		@WSValueName(value="otherValue1")
 		public String param1 = "otherValue1";
-		@WSValueName("otherValue2")
+		@WSValueName("otherName2")
 		public String param2 = "otherValue2";
 		public byte[] b = new byte[]{0x12, 0x23};
 		public InnerClass inner = new InnerClass();
@@ -147,7 +143,7 @@ public class SOAPTest {
 		@WSParamDocumentation("void method documentation")
 		public void voidMethod (){ }
 		
-		@WSDisabled()
+		@WSIgnore()
 		public void disabledMethod(){ }
 		protected void protectedMethod(){ }