Here's the patch for system.multicall(), plus a new file it adds
(SystemMethods.java). This patch also includes my last patch for HTTP
Basic authentication.

  - a

______________________________________________________________________________
org/apache/xmlrpc/SystemMethods.java

package org.apache.xmlrpc;

/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright(c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation(http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "XML-RPC" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import org.apache.xmlrpc.*;
import java.util.*;

/** Implements the XML-RPC standard system.* methods */
public class SystemMethods {

    XmlRpcServer serv = null;

    SystemMethods(XmlRpcServer serv) { this.serv = serv; }

    public Vector multicall(Vector in) {
        Vector ret = new Vector();
        for(int i=0; i<in.size(); i++) {
            try {
                Hashtable call = (Hashtable)in.elementAt(i);
                String methodName = (String)call.get("methodName");
                Vector params = (Vector)call.get("params");
                Object handler = serv.getHandler(methodName);
                Vector v = new Vector();
                v.addElement(serv.invokeHandler(handler, methodName, params, null, 
null));
                ret.addElement(v);
            } catch (Exception x) {
                String message = x.toString();
                int code = x instanceof XmlRpcException ? ((XmlRpcException) x).code : 
0;
                Hashtable h = new Hashtable();
                h.put("faultString", message);
                h.put("faultCode", new Integer(code));
                ret.addElement(h);
            }
        }
        return ret;
    }
    
}




______________________________________________________________________________
patch

Index: src/java/org/apache/xmlrpc/WebServer.java
===================================================================
RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v
retrieving revision 1.13
diff -u -r1.13 WebServer.java
--- src/java/org/apache/xmlrpc/WebServer.java   13 Aug 2002 22:27:16 -0000      1.13
+++ src/java/org/apache/xmlrpc/WebServer.java   14 Aug 2002 04:24:39 -0000
@@ -94,6 +94,7 @@
     protected static final byte[] conclose = "Connection: close\r\n".getBytes();
     protected static final byte[] ok = " 200 OK\r\n".getBytes();
     protected static final byte[] server = "Server: Apache XML-RPC 
1.0\r\n".getBytes();
+    protected static final byte[] www_authenticate = "WWW-Authenticate: Basic 
+realm=XMLRPC\r\n".getBytes();
 
     private static final String HTTP_11 = "HTTP/1.1";
     private static final String STAR = "*";
@@ -584,29 +585,40 @@
                     {
                         ServerInputStream sin = new ServerInputStream(input,
                                 contentLength);
-                        byte result[] = xmlrpc.execute(sin, user, password);
-                        output.write(httpversion.getBytes());
-                        output.write(ok);
-                        output.write(server);
-                        if (keepalive)
-                        {
-                            output.write(conkeep);
-                        }
-                        else
-                        {
-                            output.write (conclose);
+                        try {
+                            byte result[] = xmlrpc.execute(sin, user, password);
+                            output.write(httpversion.getBytes());
+                            output.write(ok);
+                            output.write(server);
+                            if (keepalive)
+                                {
+                                    output.write(conkeep);
+                                }
+                            else
+                                {
+                                    output.write (conclose);
+                                }
+                            output.write(ctype);
+                            output.write(clength);
+                            output.write(Integer.toString(result.length)
+                                         .getBytes());
+                            output.write(doubleNewline);
+                            output.write(result);
+                        } catch (XmlRpcServer.AuthenticationRequiredException are) {
+                            output.write("HTTP/1.0".getBytes());
+                            output.write(" 401 Unauthorized\r\n".getBytes());
+                            output.write(server);
+                            output.write(www_authenticate);
+                            output.write("\r\n".getBytes());
+                            output.write(("Method " + method
+                                          + " requires a username and 
+password").getBytes());
+                            keepalive = false;
                         }
-                        output.write(ctype);
-                        output.write(clength);
-                        output.write(Integer.toString(result.length)
-                                .getBytes());
-                        output.write(doubleNewline);
-                        output.write(result);
                         output.flush();
                     }
                     else
                     {
-                        output.write(httpversion.getBytes());
+                        output.write("HTTP/1.0".getBytes());
                         output.write(" 400 Bad Request\r\n".getBytes());
                         output.write(server);
                         output.write("\r\n".getBytes());
Index: src/java/org/apache/xmlrpc/XmlRpcServer.java
===================================================================
RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v
retrieving revision 1.28
diff -u -r1.28 XmlRpcServer.java
--- src/java/org/apache/xmlrpc/XmlRpcServer.java        9 Aug 2002 09:14:24 -0000      
 1.28
+++ src/java/org/apache/xmlrpc/XmlRpcServer.java        14 Aug 2002 04:24:41 -0000
@@ -93,6 +93,7 @@
         handlers = new Hashtable();
         pool = new Stack();
         workers = 0;
+        addHandler("system", new SystemMethods(this));
     }
 
     /**
@@ -136,6 +137,7 @@
      * since this is all packed into the response.
      */
     public byte[] execute(InputStream is)
+        throws AuthenticationRequiredException
     {
         return execute(is, null, null);
     }
@@ -146,6 +148,7 @@
      * use the credentials to authenticate the user.
      */
     public byte[] execute(InputStream is, String user, String password)
+        throws AuthenticationRequiredException
     {
         Worker worker = getWorker();
         byte[] retval = worker.execute(is, user, password);
@@ -179,6 +182,61 @@
         }
     }
 
+    /** find the handler for a given method */
+    Object getHandler(String methodName) throws Exception {
+        Object handler = null;
+        String handlerName = null;
+        int dot = methodName.lastIndexOf('.');
+        if (dot > -1)
+            {
+                handlerName = methodName.substring(0, dot);
+                handler = handlers.get(handlerName);
+                if (handler != null)
+                    {
+                        methodName = methodName.substring(dot + 1);
+                    }
+            }
+        
+        if (handler == null)
+            {
+                handler = handlers.get("$default");
+            }
+        
+        if (handler == null)
+            {
+                if (dot > -1)
+                    {
+                        throw new Exception("RPC handler object \""
+                                            + handlerName + "\" not found and no 
+default "
+                                            + "handler registered.");
+                    }
+                else
+                    {
+                        throw new Exception("RPC handler object not found for \""
+                                            + methodName
+                                            + "\": no default handler registered.");
+                    }
+            }
+        
+        return handler;
+    }
+    
+    Object invokeHandler(Object handler, String methodName,
+                         Vector inParams, String user, String password)
+        throws Exception {
+        if (handler instanceof AuthenticatedXmlRpcHandler)
+            {
+                if (user == null) throw new 
+XmlRpcServer.AuthenticationRequiredException();
+                return ((AuthenticatedXmlRpcHandler) handler)
+                    .execute(methodName, inParams, user, password);
+            }
+        else
+            {
+                return ((XmlRpcHandler) handler).execute(methodName, inParams);
+            }
+    }
+
+
     /**
      * Performs streaming, parsing, and handler execution.
      * Implementation is not thread-safe.
@@ -202,6 +260,7 @@
          * Given a request for the server, generates a response.
          */
         public byte[] execute(InputStream is, String user, String password)
+            throws AuthenticationRequiredException
         {
             try
             {
@@ -223,10 +282,10 @@
          * @param password
          * @return
          */
-        private byte[] executeInternal(InputStream is, String user,
-                String password)
+        byte[] executeInternal(InputStream is, String user,
+                String password) throws AuthenticationRequiredException
         {
-            byte[] result;
+            byte[] result = null;
             long now = 0;
 
             if (XmlRpc.debug)
@@ -246,63 +305,20 @@
                 {
                     throw new Exception(errorMsg);
                 }
-                Object handler = null;
-
-                String handlerName = null;
-                int dot = methodName.lastIndexOf('.');
-                if (dot > -1)
-                {
-                    handlerName = methodName.substring(0, dot);
-                    handler = handlers.get(handlerName);
-                    if (handler != null)
-                    {
-                        methodName = methodName.substring(dot + 1);
-                    }
-                }
-
-                if (handler == null)
-                {
-                    handler = handlers.get("$default");
-                }
 
-                if (handler == null)
-                {
-                    if (dot > -1)
-                    {
-                        throw new Exception("RPC handler object \""
-                                + handlerName + "\" not found and no default "
-                                + "handler registered.");
-                    }
-                    else
-                    {
-                        throw new Exception("RPC handler object not found for \""
-                                + methodName
-                                + "\": no default handler registered.");
-                    }
-                }
+                Object handler = getHandler(methodName);
+                Object outParam = invokeHandler(handler, methodName, inParams, user, 
+password);
 
-                Object outParam;
-                if (handler instanceof AuthenticatedXmlRpcHandler)
-                {
-                    outParam =((AuthenticatedXmlRpcHandler) handler)
-                            .execute(methodName, inParams, user, password);
-                }
-                else
-                {
-                    outParam =((XmlRpcHandler) handler)
-                            .execute(methodName, inParams);
-                }
                 if (XmlRpc.debug)
                 {
                     System.out.println("outparam = " + outParam);
                 }
-                writer = new XmlWriter(buffer, encoding);
-                writeResponse(outParam, writer);
-                writer.flush();
-                result = buffer.toByteArray();
             }
             catch(Exception x)
             {
+                if (x instanceof XmlRpcServer.AuthenticationRequiredException)
+                    throw (XmlRpcServer.AuthenticationRequiredException)x;
+
                 if (XmlRpc.debug)
                 {
                     x.printStackTrace();
@@ -427,6 +443,11 @@
             writer.endElement("methodResponse");
         }
     } // end of inner class Worker
+
+    public static class AuthenticationRequiredException extends IOException {
+        AuthenticationRequiredException() { }
+    }
+
 } // XmlRpcServer
 
 /**
@@ -555,4 +576,6 @@
         }
         return returnValue;
     }
+
 }
+

Reply via email to