You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by Elizabeth Fong <el...@threerings.net> on 2006/04/17 03:22:00 UTC

[PATCH] detect keepalive connection close, allow all collections as return type

Hi -

I've discovered three issues in the 2.0 branch of the XML-RPC libraries,
which are solved by this series of patches (which can be applied
independently, without dependency on one another):
Problems verified on version 2.0.1 of the Apache XML-RPC libraries, but
were also present in version 2.0 (so not a regression, per se).

Hope this helps and thanks for your time,

Elizabeth Fong
Intern software engineer, Three Rings Design
http://www.threerings.net

Fix issue with NoSuchElementException being thrown after each request
(tested by using XmlRpcClient)
--- src/java/org/apache/xmlrpc/WebServer.java   (revision 394582)
+++ src/java/org/apache/xmlrpc/WebServer.java   (working copy)
@@ -719,6 +720,10 @@

                     // tokenize first line of HTTP request
                     StringTokenizer tokens = new StringTokenizer(line);
+                    if (!tokens.hasMoreElements())
+                    {
+                        continue;
+                    }
                     String method = tokens.nextToken();
                     String uri = tokens.nextToken();
                     String httpVersion = tokens.nextToken();

Properly detect and bail out when a keepalive socket connection is closed,
instead of instantiating new empty Strings each time readLine() is called.
 If keepalive is on and the connection is closed, then keepalive cannot be
set to off and readLine() is called in an infinite loop.  This behavior
resulted in extremely frequent garbage collection until I applied the
patch.
--- src/java/org/apache/xmlrpc/WebServer.java   (revision 394582)
+++ src/java/org/apache/xmlrpc/WebServer.java   (working copy
@@ -19,6 +19,7 @@

 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.io.UnsupportedEncodingException;
@@ -776,6 +781,9 @@
                 }
                 while (keepAlive);
             }
+            catch (EOFException ignore)
+            {
+            }
             catch (Exception exception)
             {
                 if (XmlRpc.debug)
@@ -818,6 +823,10 @@
             for (;;)
             {
                 next = input.read();
+                if (count == 0 && next < 0)
+                {
+                    throw new EOFException("Connection closed");
+                }
                 if (next < 0 || next == '\n')
                 {
                     break;

Support using all Collections and Maps, not just Vectors and Hashtables. 
There's no need to specify that return types be specific when we can be
more generic - all we're doing is iterating through the collection/map
elements and stuffing them in the response, and the specific
implementation doesn't matter.
--- src/java/org/apache/xmlrpc/XmlWriter.java   (revision 394582)
+++ src/java/org/apache/xmlrpc/XmlWriter.java   (working copy)
@@ -21,11 +21,11 @@
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
+import java.util.Collection;
 import java.util.Date;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Properties;
-import java.util.Vector;

 import org.apache.xmlrpc.util.DateTool;
 import org.apache.commons.codec.binary.Base64;
@@ -286,27 +286,29 @@
             endElement("data");
             endElement("array");
         }
-        else if (obj instanceof Vector)
+        else if (obj instanceof Collection)
         {
             startElement("array");
             startElement("data");
-            Vector array = (Vector) obj;
-            int size = array.size();
-            for (int i = 0; i < size; i++)
+            Collection array = (Collection)obj;
+            Iterator it = array.iterator();
+            while (it.hasNext())
             {
-                writeObject(array.elementAt(i));
+                writeObject(it.next());
             }
             endElement("data");
             endElement("array");
         }
-        else if (obj instanceof Hashtable)
+        else if (obj instanceof Map)
         {
             startElement("struct");
-            Hashtable struct = (Hashtable) obj;
-            for (Enumeration e = struct.keys(); e.hasMoreElements(); )
+            Map struct = (Map)obj;
+            Iterator it = struct.entrySet().iterator();
+            while (it.hasNext())
             {
-                String key = (String) e.nextElement();
-                Object value = struct.get(key);
+                Map.Entry entry = (Map.Entry)it.next();
+                String key = (String)entry.getKey();
+                Object value = entry.getValue();
                 startElement("member");
                 startElement("name");
                 chardata(key);



Re: [PATCH] detect keepalive connection close, allow all collections as return type

Posted by Jochen Wiedmann <jo...@gmail.com>.
Hi, Elizabeth,

afaik, I didn't reply so far, due to lack of time. I have added your first
two patches, thanks very much. I won't add the third patch: Versions 1 and 2
of Apache XML-RPC have been specifically designed for running with JDK 1.1.

If you are interested in collections, and the like, then I suggest you give
version 3 a try.


Jochen