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 jo...@apache.org on 2002/02/19 03:25:02 UTC
cvs commit: xml-rpc/src/java/org/apache/xmlrpc Base64.java ServerInputStream.java WebServer.java XmlRpc.java XmlRpcClient.java
jon 02/02/18 18:25:02
Modified: src/java/org/apache/xmlrpc Base64.java
ServerInputStream.java WebServer.java XmlRpc.java
XmlRpcClient.java
Log:
I did a bunch of code cleanup and minor
optimizations, switched to the catalina Base64 (note the one FIXME, if
someone has a suggestion for a better way, let me know).
Found a couple optimizations (such as not calling System.currentTimeMillis()
unless debug is on...
Revision Changes Path
1.2 +271 -275 xml-rpc/src/java/org/apache/xmlrpc/Base64.java
Index: Base64.java
===================================================================
RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/Base64.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Base64.java 20 Jul 2001 19:38:16 -0000 1.1
+++ Base64.java 19 Feb 2002 02:25:01 -0000 1.2
@@ -1,326 +1,322 @@
package org.apache.xmlrpc;
-// We can replace this with some apache code I'm sure. jvz.
-
-//////////////////////license & copyright header/////////////////////////
-// //
-// Base64 - encode/decode data using the Base64 encoding scheme //
-// //
-// Copyright (c) 1998 by Kevin Kelley //
-// //
-// This library is free software; you can redistribute it and/or //
-// modify it under the terms of the GNU Lesser General Public //
-// License as published by the Free Software Foundation; either //
-// version 2.1 of the License, or (at your option) any later version. //
-// //
-// This library is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU Lesser General Public License for more details. //
-// //
-// You should have received a copy of the GNU Lesser General Public //
-// License along with this library; if not, write to the Free Software //
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA //
-// 02111-1307, USA, or contact the author: //
-// //
-// Kevin Kelley <ke...@ruralnet.net> - 30718 Rd. 28, La Junta, CO, //
-// 81050 USA. //
-// //
-////////////////////end license & copyright header///////////////////////
-
-import java.io.*; // needed only for main() method.
-
+/*
+ * $Header: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/Base64.java,v 1.2 2002/02/19 02:25:01 jon Exp $
+ * $Revision: 1.2 $
+ * $Date: 2002/02/19 02:25:01 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 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 acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", 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 apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * 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/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
/**
-* Provides encoding of raw bytes to base64-encoded characters, and
-* decoding of base64 characters to raw bytes.
-*
-* @author Kevin Kelley (kelley@ruralnet.net)
-* @version 1.3
-* @date 06 August 1998
-* @modified 14 February 2000
-* @modified 22 September 2000
-*/
-public class Base64
+ * This class provides encode/decode for RFC 2045 Base64 as defined by
+ * RFC 2045, N. Freed and N. Borenstein. <a
+ * href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>:
+ * Multipurpose Internet Mail Extensions (MIME) Part One: Format of
+ * Internet Message Bodies. Reference 1996
+ *
+ * @author Jeffrey Rodriguez
+ * @version $Id: Base64.java,v 1.2 2002/02/19 02:25:01 jon Exp $
+ */
+public final class Base64
{
+ static private final int BASELENGTH = 255;
+ static private final int LOOKUPLENGTH = 64;
+ static private final int TWENTYFOURBITGROUP = 24;
+ static private final int EIGHTBIT = 8;
+ static private final int SIXTEENBIT = 16;
+ static private final int SIXBIT = 6;
+ static private final int FOURBYTE = 4;
+ static private final int SIGN = -128;
+ static private final byte PAD = (byte) '=';
+ static private byte [] base64Alphabet = new byte[BASELENGTH];
+ static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
+ //static private final Log log = LogSource.getInstance("org.apache.commons.util.Base64");
- /**
- * returns an array of base64-encoded characters to represent the
- * passed data array.
- *
- * @param data the array of bytes to encode
- * @return base64-coded character array.
- */
- static public char[] encode(byte[] data)
+ static
{
- char[] out = new char[((data.length + 2) / 3) * 4];
-
- //
- // 3 bytes encode to 4 chars. Output is always an even
- // multiple of 4 characters.
- //
- for (int i = 0, index = 0; i < data.length; i += 3, index += 4)
- {
- boolean quad = false;
- boolean trip = false;
-
- int val = (0xFF & (int) data[i]);
- val <<= 8;
- if ((i + 1) < data.length)
- {
- val |= (0xFF & (int) data[i + 1]);
- trip = true;
- }
- val <<= 8;
- if ((i + 2) < data.length)
- {
- val |= (0xFF & (int) data[i + 2]);
- quad = true;
- }
- out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
- val >>= 6;
- out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
- val >>= 6;
- out[index + 1] = alphabet[val & 0x3F];
- val >>= 6;
- out[index + 0] = alphabet[val & 0x3F];
+ for (int i = 0; i < BASELENGTH; i++ )
+ {
+ base64Alphabet[i] = -1;
}
- return out;
- }
-
- /**
- * Decodes a BASE-64 encoded stream to recover the original
- * data. White space before and after will be trimmed away,
- * but no other manipulation of the input will be performed.
- *
- * As of version 1.2 this method will properly handle input
- * containing junk characters (newlines and the like) rather
- * than throwing an error. It does this by pre-parsing the
- * input and generating from that a count of VALID input
- * characters.
- **/
- static public byte[] decode(char[] data)
- {
- // as our input could contain non-BASE64 data (newlines,
- // whitespace of any sort, whatever) we must first adjust
- // our count of USABLE data so that...
- // (a) we don't misallocate the output array, and
- // (b) think that we miscalculated our data length
- // just because of extraneous throw-away junk
-
- int tempLen = data.length;
- for (int ix = 0; ix < data.length; ix++)
+ for (int i = 'Z'; i >= 'A'; i--)
{
- if ((data[ix] > 255) || codes[data[ix]] < 0)
- --tempLen; // ignore non-valid chars and padding
+ base64Alphabet[i] = (byte) (i - 'A');
}
- // calculate required length:
- // -- 3 bytes for every 4 valid base64 chars
- // -- plus 2 bytes if there are 3 extra base64 chars,
- // or plus 1 byte if there are 2 extra.
-
- int len = (tempLen / 4) * 3;
- if ((tempLen % 4) == 3)
- len += 2;
- if ((tempLen % 4) == 2)
- len += 1;
-
- byte[] out = new byte[len];
-
-
-
- int shift = 0; // # of excess bits stored in accum
- int accum = 0; // excess bits
- int index = 0;
-
- // we now go through the entire array (NOT using the 'tempLen' value)
- for (int ix = 0; ix < data.length; ix++)
+ for (int i = 'z'; i>= 'a'; i--)
{
- int value = (data[ix] > 255) ? -1 : codes[data[ix]];
-
- if (value >= 0)// skip over non-code
-
- {
- accum <<= 6; // bits shift up by 6 each time thru
- shift += 6; // loop, with new bits being put in
- accum |= value; // at the bottom.
- if (shift >= 8)// whenever there are 8 or more shifted in,
-
- {
- shift -= 8; // write them out (from the top, leaving any
- out[index++] = // excess at the bottom for next iteration.
- (byte)((accum >> shift) & 0xff);
- }
- }
- // we will also have skipped processing a padding null byte ('=') here;
- // these are used ONLY for padding to an even length and do not legally
- // occur as encoded data. for this reason we can ignore the fact that
- // no index++ operation occurs in that special case: the out[] array is
- // initialized to all-zero bytes to start with and that works to our
- // advantage in this combination.
+ base64Alphabet[i] = (byte) (i - 'a' + 26);
}
-
- // if there is STILL something wrong we just have to throw up now!
- if (index != out.length)
+ for (int i = '9'; i >= '0'; i--)
{
- throw new Error("Miscalculated data length (wrote " +
- index + " instead of " + out.length + ")");
+ base64Alphabet[i] = (byte) (i - '0' + 52);
}
- return out;
- }
-
+ base64Alphabet['+'] = 62;
+ base64Alphabet['/'] = 63;
- //
- // code characters for values 0..63
- //
- static private char[] alphabet =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" .toCharArray();
-
- //
- // lookup table for converting base64 characters to value in range 0..63
- //
- static private byte[] codes = new byte[256];
- static
- {
- for (int i = 0; i < 256; i++)
- codes[i] = -1;
- for (int i = 'A'; i <= 'Z'; i++)
- codes[i] = (byte)(i - 'A');
- for (int i = 'a'; i <= 'z'; i++)
- codes[i] = (byte)(26 + i - 'a');
- for (int i = '0'; i <= '9'; i++)
- codes[i] = (byte)(52 + i - '0');
- codes['+'] = 62;
- codes['/'] = 63;
- }
+ for (int i = 0; i <= 25; i++ )
+ lookUpBase64Alphabet[i] = (byte) ('A' + i);
+ for (int i = 26, j = 0; i <= 51; i++, j++ )
+ lookUpBase64Alphabet[i] = (byte) ('a'+ j);
+ for (int i = 52, j = 0; i <= 61; i++, j++ )
+ lookUpBase64Alphabet[i] = (byte) ('0' + j);
+ lookUpBase64Alphabet[62] = (byte) '+';
+ lookUpBase64Alphabet[63] = (byte) '/';
+ }
- ///////////////////////////////////////////////////
- // remainder (main method and helper functions) is
- // for testing purposes only, feel free to clip it.
- ///////////////////////////////////////////////////
+ public static boolean isBase64( String isValidString )
+ {
+ return isArrayByteBase64(isValidString.getBytes());
+ }
- public static void main(String[] args)
+ public static boolean isBase64( byte octect )
{
- boolean decode = false;
+ //shall we ignore white space? JEFF??
+ return (octect == PAD || base64Alphabet[octect] != -1);
+ }
- if (args.length == 0)
+ public static boolean isArrayByteBase64( byte[] arrayOctect )
+ {
+ int length = arrayOctect.length;
+ if (length == 0)
{
- System.out.println("usage: java Base64 [-d[ecode]] filename");
- System.exit(0);
+ // shouldn't a 0 length array be valid base64 data?
+ // return false;
+ return true;
}
- for (int i = 0; i < args.length; i++)
+ for (int i=0; i < length; i++)
{
- if ("-decode".equalsIgnoreCase(args[i]))
- decode = true;
- else if ("-d".equalsIgnoreCase(args[i]))
- decode = true;
+ if ( !Base64.isBase64(arrayOctect[i]) )
+ return false;
}
+ return true;
+ }
- String filename = args[args.length - 1];
- File file = new File(filename);
- if (!file.exists())
- {
- System.out.println("Error: file '" + filename + "' doesn't exist!");
- System.exit(0);
- }
+ /**
+ * Encodes hex octects into Base64.
+ *
+ * @param binaryData Array containing binary data to encode.
+ * @return Base64-encoded data.
+ */
+ public static byte[] encode( byte[] binaryData )
+ {
+ int lengthDataBits = binaryData.length*EIGHTBIT;
+ int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP;
+ int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP;
+ byte encodedData[] = null;
- if (decode)
+
+ if (fewerThan24bits != 0)
{
- char[] encoded = readChars(file);
- byte[] decoded = decode(encoded);
- writeBytes(file, decoded);
+ //data not divisible by 24 bit
+ encodedData = new byte[ (numberTriplets + 1 ) * 4 ];
}
else
{
- byte[] decoded = readBytes(file);
- char[] encoded = encode(decoded);
- writeChars(file, encoded);
+ // 16 or 8 bit
+ encodedData = new byte[ numberTriplets * 4 ];
}
- }
- private static byte[] readBytes(File file)
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try
- {
- InputStream fis = new FileInputStream(file);
- InputStream is = new BufferedInputStream(fis);
- int count = 0;
- byte[] buf = new byte[16384];
- while ((count = is.read(buf)) != -1)
- {
- if (count > 0)
- baos.write(buf, 0, count);
- }
- is.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
+ byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+ int encodedIndex = 0;
+ int dataIndex = 0;
+ int i = 0;
+ //log.debug("number of triplets = " + numberTriplets);
+ for ( i = 0; i<numberTriplets; i++ )
+ {
+ dataIndex = i*3;
+ b1 = binaryData[dataIndex];
+ b2 = binaryData[dataIndex + 1];
+ b3 = binaryData[dataIndex + 2];
+
+ //log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3);
+
+ l = (byte)(b2 & 0x0f);
+ k = (byte)(b1 & 0x03);
+
+ encodedIndex = i * 4;
+ byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+ byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
+ byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);
+
+ encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ];
+ //log.debug( "val2 = " + val2 );
+ //log.debug( "k4 = " + (k<<4) );
+ //log.debug( "vak = " + (val2 | (k<<4)) );
+ encodedData[encodedIndex+1] =
+ lookUpBase64Alphabet[ val2 | ( k<<4 )];
+ encodedData[encodedIndex+2] =
+ lookUpBase64Alphabet[ (l <<2 ) | val3 ];
+ encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ];
+ }
+
+ // form integral number of 6-bit groups
+ dataIndex = i*3;
+ encodedIndex = i*4;
+ if (fewerThan24bits == EIGHTBIT )
+ {
+ b1 = binaryData[dataIndex];
+ k = (byte) ( b1 &0x03 );
+ //log.debug("b1=" + b1);
+ //log.debug("b1<<2 = " + (b1>>2) );
+ byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+ encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ];
+ encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ];
+ encodedData[encodedIndex + 2] = PAD;
+ encodedData[encodedIndex + 3] = PAD;
+ }
+ else if (fewerThan24bits == SIXTEENBIT)
+ {
+
+ b1 = binaryData[dataIndex];
+ b2 = binaryData[dataIndex +1 ];
+ l = (byte) (b2 & 0x0f);
+ k = (byte) (b1 & 0x03);
+
+ byte val1 = ((b1 & SIGN) == 0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
+ byte val2 = ((b2 & SIGN) == 0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
+
+ encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ];
+ encodedData[encodedIndex + 1] =
+ lookUpBase64Alphabet[ val2 | ( k<<4 )];
+ encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ];
+ encodedData[encodedIndex + 3] = PAD;
}
- return baos.toByteArray();
+ return encodedData;
}
- private static char[] readChars(File file)
+ /**
+ * Decodes Base64 data into octects
+ *
+ * @param binaryData Byte array containing Base64 data
+ * @return Array containing decoded data.
+ */
+ public static byte[] decode( byte[] base64Data )
{
- CharArrayWriter caw = new CharArrayWriter();
- try
- {
- Reader fr = new FileReader(file);
- Reader in = new BufferedReader(fr);
- int count = 0;
- char[] buf = new char[16384];
- while ((count = in.read(buf)) != -1)
+ // handle the edge case, so we don't have to worry about it later
+ if(base64Data.length == 0) { return new byte[0]; }
+
+ int numberQuadruple = base64Data.length/FOURBYTE;
+ byte decodedData[] = null;
+ byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;
+
+ // Throw away anything not in base64Data
+
+ int encodedIndex = 0;
+ int dataIndex = 0;
+ {
+ // this sizes the output array properly - rlw
+ int lastData = base64Data.length;
+ // ignore the '=' padding
+ while (base64Data[lastData-1] == PAD)
{
- if (count > 0)
- caw.write(buf, 0, count);
+ if (--lastData == 0)
+ {
+ return new byte[0];
+ }
}
- in.close();
+ decodedData = new byte[ lastData - numberQuadruple ];
}
- catch (Exception e)
+
+ for (int i = 0; i < numberQuadruple; i++)
{
- e.printStackTrace();
- }
+ dataIndex = i * 4;
+ marker0 = base64Data[dataIndex + 2];
+ marker1 = base64Data[dataIndex + 3];
- return caw.toCharArray();
- }
+ b1 = base64Alphabet[base64Data[dataIndex]];
+ b2 = base64Alphabet[base64Data[dataIndex +1]];
- private static void writeBytes(File file, byte[] data)
- {
- try
- {
- OutputStream fos = new FileOutputStream(file);
- OutputStream os = new BufferedOutputStream(fos);
- os.write(data);
- os.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
+ if (marker0 != PAD && marker1 != PAD)
+ {
+ //No PAD e.g 3cQl
+ b3 = base64Alphabet[ marker0 ];
+ b4 = base64Alphabet[ marker1 ];
+
+ decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
+ decodedData[encodedIndex + 1] =
+ (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
+ decodedData[encodedIndex + 2] = (byte)( b3<<6 | b4 );
+ }
+ else if (marker0 == PAD)
+ {
+ //Two PAD e.g. 3c[Pad][Pad]
+ decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
+ }
+ else if (marker1 == PAD)
+ {
+ //One PAD e.g. 3cQ[Pad]
+ b3 = base64Alphabet[ marker0 ];
- private static void writeChars(File file, char[] data)
- {
- try
- {
- Writer fos = new FileWriter(file);
- Writer os = new BufferedWriter(fos);
- os.write(data);
- os.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
+ decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 );
+ decodedData[encodedIndex + 1] =
+ (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
+ }
+ encodedIndex += 3;
}
+ return decodedData;
}
- ///////////////////////////////////////////////////
- // end of test code.
- ///////////////////////////////////////////////////
+
}
1.2 +12 -9 xml-rpc/src/java/org/apache/xmlrpc/ServerInputStream.java
Index: ServerInputStream.java
===================================================================
RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/ServerInputStream.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ServerInputStream.java 20 Jul 2001 19:38:16 -0000 1.1
+++ ServerInputStream.java 19 Feb 2002 02:25:01 -0000 1.2
@@ -69,8 +69,8 @@
// This is used in order to correctly return a -1 when all the
// data POSTed was read. If this is left to -1, content length is
// assumed as unknown and the standard InputStream methods will be used
- long available = -1;
- long markedAvailable;
+ private long available = -1;
+ private long markedAvailable;
private BufferedInputStream in;
@@ -120,7 +120,9 @@
return read;
}
else if (available == -1)
- return in.read (b, off, len);
+ {
+ return in.read(b, off, len);
+ }
return -1;
}
@@ -128,25 +130,26 @@
{
long skip = in.skip(n);
if (available > 0)
+ {
available -= skip;
+ }
return skip;
}
- public void mark (int readlimit)
+ public void mark(int readlimit)
{
- in.mark (readlimit);
+ in.mark(readlimit);
markedAvailable = available;
}
- public void reset () throws IOException
+ public void reset() throws IOException
{
- in.reset ();
+ in.reset();
available = markedAvailable;
}
- public boolean markSupported ()
+ public boolean markSupported()
{
return true;
}
-
}
1.5 +166 -126 xml-rpc/src/java/org/apache/xmlrpc/WebServer.java
Index: WebServer.java
===================================================================
RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- WebServer.java 13 Feb 2002 00:51:55 -0000 1.4
+++ WebServer.java 19 Feb 2002 02:25:01 -0000 1.5
@@ -87,6 +87,9 @@
protected static final byte[] ok = " 200 OK\r\n".getBytes();
protected static final byte[] server = "Server: Apache XML-RPC 1.0\r\n".getBytes();
+ private static final String HTTP_11 = "HTTP/1.1";
+ private static final String STAR = "*";
+
/**
* This <em>can</em> be called from command line, but you'll have to edit and recompile
* to change the server port or handler objects. By default, it sets up the following responders:
@@ -113,44 +116,44 @@
XmlRpc.setKeepAlive (true);
try
{
- WebServer webserver = new WebServer (p);
+ WebServer webserver = new WebServer(p);
// webserver.setParanoid (true);
// webserver.acceptClient ("192.168.*.*");
- webserver.addHandler ("string", "Welcome to XML-RPC!");
- webserver.addHandler ("math", Math.class);
- webserver.addHandler ("auth", new AuthDemo());
- webserver.addHandler ("$default", new Echo());
+ webserver.addHandler("string", "Welcome to XML-RPC!");
+ webserver.addHandler("math", Math.class);
+ webserver.addHandler("auth", new AuthDemo());
+ webserver.addHandler("$default", new Echo());
// XmlRpcClients can be used as Proxies in XmlRpcServers which is a cool feature for applets.
- webserver.addHandler ("mttf", new XmlRpcClient ("http://www.mailtothefuture.com:80/RPC2"));
- System.err.println ("started web server on port "+p);
+ webserver.addHandler("mttf", new XmlRpcClient("http://www.mailtothefuture.com:80/RPC2"));
+ System.err.println("started web server on port "+p);
}
catch (IOException x)
{
- System.err.println ("Error creating web server: "+x);
+ System.err.println("Error creating web server: "+x);
}
}
/**
* Creates a Web server at the specified port number.
*/
- public WebServer (int port)
+ public WebServer(int port)
throws IOException
{
- this (port, null);
+ this(port, null);
}
/**
* Creates a Web server at the specified port number and IP address.
*/
- public WebServer (int port, InetAddress add)
+ public WebServer(int port, InetAddress add)
throws IOException
{
this.port = port;
- xmlrpc = new XmlRpcServer ();
- accept = new Vector ();
- deny = new Vector ();
- threadpool = new Stack ();
- runners = new ThreadGroup ("XML-RPC Runner");
+ xmlrpc = new XmlRpcServer();
+ accept = new Vector();
+ deny = new Vector();
+ threadpool = new Stack();
+ runners = new ThreadGroup("XML-RPC Runner");
try
{
@@ -193,7 +196,7 @@
public void start()
{
- listener = new Thread (this, "XML-RPC Weblistener");
+ listener = new Thread(this, "XML-RPC Weblistener");
listener.start();
}
@@ -201,17 +204,17 @@
* Register a handler object with this name. Methods of this objects will be
* callable over XML-RPC as "name.method".
*/
- public void addHandler (String name, Object target)
+ public void addHandler(String name, Object target)
{
- xmlrpc.addHandler (name, target);
+ xmlrpc.addHandler(name, target);
}
/**
* Remove a handler object that was previously registered with this server.
*/
- public void removeHandler (String name)
+ public void removeHandler(String name)
{
- xmlrpc.removeHandler (name);
+ xmlrpc.removeHandler(name);
}
/**
@@ -219,7 +222,7 @@
* @see acceptClient(java.lang.String)
* @see denyClient(java.lang.String)
*/
- public void setParanoid (boolean p)
+ public void setParanoid(boolean p)
{
paranoid = p;
}
@@ -232,17 +235,19 @@
* @see denyClient(java.lang.String)
* @see setParanoid(boolean)
*/
- public void acceptClient (String address)
- throws IllegalArgumentException
+ public void acceptClient(String address)
+ throws IllegalArgumentException
{
try
{
- AddressMatcher m = new AddressMatcher (address);
- accept.addElement (m);
+ AddressMatcher m = new AddressMatcher(address);
+ accept.addElement(m);
}
catch (Exception x)
{
- throw new IllegalArgumentException ("\""+address + "\" does not represent a valid IP address");
+ throw new IllegalArgumentException("\"" +
+ address +
+ "\" does not represent a valid IP address");
}
}
@@ -254,35 +259,41 @@
* @see acceptClient(java.lang.String)
* @see setParanoid(boolean)
*/
- public void denyClient (String address) throws IllegalArgumentException
+ public void denyClient(String address) throws IllegalArgumentException
{
try
{
- AddressMatcher m = new AddressMatcher (address);
- deny.addElement (m);
+ AddressMatcher m = new AddressMatcher(address);
+ deny.addElement(m);
}
catch (Exception x)
{
- throw new IllegalArgumentException ("\""+address + "\" does not represent a valid IP address");
+ throw new IllegalArgumentException("\"" +
+ address +
+ "\" does not represent a valid IP address");
}
}
- protected boolean checkSocket (Socket s)
+ protected boolean checkSocket(Socket s)
{
- int l = deny.size ();
- byte address[] = s.getInetAddress ().getAddress ();
+ int l = deny.size();
+ byte address[] = s.getInetAddress().getAddress();
for (int i = 0; i < l; i++)
{
- AddressMatcher match = (AddressMatcher) deny.elementAt (i);
- if (match.matches (address))
+ AddressMatcher match = (AddressMatcher)deny.elementAt(i);
+ if (match.matches(address))
+ {
return false;
+ }
}
- l = accept.size ();
+ l = accept.size();
for (int i = 0; i < l; i++)
{
- AddressMatcher match = (AddressMatcher) accept.elementAt (i);
- if (match.matches (address))
+ AddressMatcher match = (AddressMatcher)accept.elementAt(i);
+ if (match.matches(address))
+ {
return true;
+ }
}
return false;
}
@@ -299,14 +310,15 @@
try
{
Socket socket = serverSocket.accept();
- if (!paranoid || checkSocket (socket))
+ if (!paranoid || checkSocket(socket))
{
- Runner runner = getRunner ();
+ Runner runner = getRunner();
runner.handle (socket);
- // new Connection (socket);
}
else
- socket.close ();
+ {
+ socket.close();
+ }
}
catch (InterruptedIOException checkState)
{
@@ -341,14 +353,15 @@
serverSocket = null;
}
catch (IOException ignore)
- {}
+ {
+ }
}
}
/**
* Stop listening on the server port.
*/
- public void shutdown ()
+ public void shutdown()
{
if (listener != null)
{
@@ -358,19 +371,19 @@
}
}
-
-
- protected Runner getRunner ()
+ protected Runner getRunner()
{
try
{
- return (Runner) threadpool.pop ();
+ return (Runner)threadpool.pop();
}
catch (EmptyStackException empty)
{
if (runners.activeCount () > 255)
+ {
throw new RuntimeException ("System overload");
- return new Runner ();
+ }
+ return new Runner();
}
}
@@ -381,28 +394,27 @@
class Runner implements Runnable
{
-
Thread thread;
Connection con;
int count;
- public synchronized void handle (Socket socket)
+ public synchronized void handle(Socket socket)
throws IOException
{
- con = new Connection (socket);
+ con = new Connection(socket);
count = 0;
if (thread == null || !thread.isAlive())
{
- thread = new Thread (runners, this);
- thread.start ();
+ thread = new Thread(runners, this);
+ thread.start();
}
else
{
- this.notify ();
+ this.notify();
}
}
- public void run ()
+ public void run()
{
while (Thread.currentThread () == thread)
{
@@ -411,14 +423,15 @@
con = null;
if (count > 200 || threadpool.size() > 20)
+ {
return;
-
- synchronized (this)
+ }
+ synchronized(this)
{
- releaseRunner (this);
+ releaseRunner(this);
try
{
- this.wait ();
+ this.wait();
}
catch (InterruptedException ir)
{
@@ -427,19 +440,15 @@
}
}
}
-
- } // end class Runner
-
+ }
class Connection implements Runnable
{
-
private Socket socket;
private BufferedInputStream input;
private BufferedOutputStream output;
- // private Thread responder;
- private long lastRequest;
private String user, password;
+ byte[] buffer;
public Connection (Socket socket) throws IOException
{
@@ -447,13 +456,11 @@
socket.setSoTimeout (30000);
this.socket = socket;
- input = new BufferedInputStream (socket.getInputStream());
- output = new BufferedOutputStream (socket.getOutputStream());
- // responder = new Thread (this, "xmlrpc-worker");
- // responder.start();
+ input = new BufferedInputStream(socket.getInputStream());
+ output = new BufferedOutputStream(socket.getOutputStream());
}
- public void run ()
+ public void run()
{
try
{
@@ -463,43 +470,52 @@
{
// reset user authentication
user = password = null;
- String line = readLine ();
+ String line = readLine();
// Netscape sends an extra \n\r after bodypart, swallow it
- if ("".equals (line))
+ if (line != null && line.length() == 0)
+ {
line = readLine();
+ }
if (XmlRpc.debug)
+ {
System.err.println (line);
- // get time of last request
- lastRequest = System.currentTimeMillis ();
+ }
int contentLength = -1;
// tokenize first line of HTTP request
StringTokenizer tokens = new StringTokenizer(line);
String method = tokens.nextToken();
- String uri = tokens.nextToken ();
- String httpversion = tokens.nextToken ();
- keepalive = XmlRpc.getKeepAlive() && "HTTP/1.1".equals (httpversion);
+ String uri = tokens.nextToken();
+ String httpversion = tokens.nextToken();
+ keepalive = XmlRpc.getKeepAlive() && HTTP_11.equals(httpversion);
do
{
line = readLine();
if (line != null)
{
if (XmlRpc.debug)
- System.err.println (line);
- String lineLower = line.toLowerCase ();
- if (lineLower.startsWith ("content-length:"))
- contentLength = Integer.parseInt (
- line.substring (15).trim ());
- if (lineLower.startsWith ("connection:"))
+ {
+ System.err.println(line);
+ }
+ String lineLower = line.toLowerCase();
+ if (lineLower.startsWith("content-length:"))
+ {
+ contentLength = Integer.parseInt(
+ line.substring(15).trim());
+ }
+ if (lineLower.startsWith("connection:"))
+ {
keepalive = XmlRpc.getKeepAlive() &&
lineLower.indexOf ("keep-alive")
> -1;
- if (lineLower.startsWith ("authorization: basic "))
+ }
+ if (lineLower.startsWith("authorization: basic "))
+ {
parseAuth (line);
+ }
}
}
- while (line != null && ! line.equals(""))
- ;
+ while (line != null && line.length() != 0);
if ("POST".equalsIgnoreCase (method))
{
@@ -508,35 +524,38 @@
contentLength);
byte result[] =
xmlrpc.execute (sin, user, password);
- output.write (httpversion.getBytes());
- output.write (ok);
- output.write (server);
+ output.write(httpversion.getBytes());
+ output.write(ok);
+ output.write(server);
if (keepalive)
- output.write (conkeep);
+ {
+ output.write(conkeep);
+ }
else
+ {
output.write (conclose);
- output.write (ctype);
- output.write (clength);
- output.write ( Integer.toString (
+ }
+ output.write(ctype);
+ output.write(clength);
+ output.write(Integer.toString(
result.length).getBytes());
- output.write (doubleNewline);
- output.write (result);
- output.flush ();
+ output.write(doubleNewline);
+ output.write(result);
+ output.flush();
}
else
{
- output.write (httpversion.getBytes());
- output.write (" 400 Bad Request\r\n".getBytes());
- output.write (server);
- output.write ("\r\n".getBytes());
- output.write ( ("Method "+method +
- " not implemented (try POST)"). getBytes());
- output.flush ();
+ output.write(httpversion.getBytes());
+ output.write(" 400 Bad Request\r\n".getBytes());
+ output.write(server);
+ output.write("\r\n".getBytes());
+ output.write(("Method "+method +
+ " not implemented (try POST)").getBytes());
+ output.flush();
keepalive = false;
}
}
- while (keepalive)
- ;
+ while (keepalive);
}
catch (Exception exception)
{
@@ -546,16 +565,22 @@
exception.printStackTrace ();
}
}
- finally { try
+ finally
+ {
+ try
{
- socket.close();
+ if (socket != null)
+ {
+ socket.close();
+ }
}
catch (IOException ignore)
- {}
- } }
+ {
+ }
+ }
+ }
- byte[] buffer;
- private String readLine () throws IOException
+ private String readLine() throws IOException
{
if (buffer == null)
{
@@ -567,51 +592,63 @@
{
next = input.read();
if (next < 0 || next == '\n')
+ {
break;
+ }
if (next != '\r')
{
buffer[count++] = (byte) next;
}
if (count >= 512)
+ {
throw new IOException ("HTTP Header too long");
+ }
}
return new String (buffer, 0, count);
}
- private void parseAuth (String line)
+ private void parseAuth(String line)
{
try
{
byte[] c =
- Base64.decode (line.substring (21).toCharArray());
+ Base64.decode (line.substring(21).getBytes());
String str = new String (c);
- int col = str.indexOf (":");
+ int col = str.indexOf (':');
user = str.substring (0, col);
password = str.substring (col + 1);
}
catch (Throwable ignore)
- {}
+ {
+ }
}
-
}
class AddressMatcher
{
int pattern[];
-
+
public AddressMatcher (String address) throws Exception
{
pattern = new int[4];
- StringTokenizer st = new StringTokenizer (address, ".");
- if (st.countTokens () != 4)
- throw new Exception ("\""+address + "\" does not represent a valid IP address");
+ StringTokenizer st = new StringTokenizer(address, ".");
+ if (st.countTokens() != 4)
+ {
+ throw new Exception ("\"" +
+ address +
+ "\" does not represent a valid IP address");
+ }
for (int i = 0; i < 4; i++)
{
- String next = st.nextToken ();
- if ("*".equals (next))
+ String next = st.nextToken();
+ if (STAR.equals(next))
+ {
pattern[i] = 256;
+ }
else
- pattern[i] = (byte) Integer.parseInt (next);
+ {
+ pattern[i] = (byte) Integer.parseInt(next);
+ }
}
}
@@ -620,10 +657,13 @@
for (int i = 0; i < 4; i++)
{
if (pattern[i] > 255)// wildcard
-
+ {
continue;
+ }
if (pattern[i] != address[i])
+ {
return false;
+ }
}
return true;
}
1.18 +3 -2 xml-rpc/src/java/org/apache/xmlrpc/XmlRpc.java
Index: XmlRpc.java
===================================================================
RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/XmlRpc.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- XmlRpc.java 18 Feb 2002 23:22:29 -0000 1.17
+++ XmlRpc.java 19 Feb 2002 02:25:01 -0000 1.18
@@ -587,7 +587,7 @@
}
break;
case BASE64:
- value = Base64.decode (cdata.toCharArray());
+ value = Base64.decode (cdata.getBytes());
break;
case STRING:
value = cdata;
@@ -700,7 +700,8 @@
else if (obj instanceof byte[])
{
startElement("base64");
- write(Base64.encode((byte[]) obj));
+ // FIXME: Yucky! Find a better way!
+ write(new String(Base64.encode((byte[]) obj)).toCharArray());
endElement("base64");
}
else if (obj instanceof Vector)
1.7 +172 -144 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcClient.java
Index: XmlRpcClient.java
===================================================================
RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcClient.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- XmlRpcClient.java 18 Feb 2002 23:22:29 -0000 1.6
+++ XmlRpcClient.java 19 Feb 2002 02:25:01 -0000 1.7
@@ -4,7 +4,7 @@
* The Apache Software License, Version 1.1
*
*
- * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * Copyright(c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
* 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/)."
+ * 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.
*
@@ -40,11 +40,11 @@
* 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
+ * 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
+ * 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.
* ====================================================================
@@ -62,7 +62,7 @@
/**
* A multithreaded, reusable XML-RPC client object. Use this if you need a full-grown
- * HTTP client (e.g. for Proxy and Cookies support). If you don't need that, <code>XmlRpcClientLite</code>
+ * HTTP client(e.g. for Proxy and Cookies support). If you don't need that, <code>XmlRpcClientLite</code>
* may work better for you.
*
* @author <a href="mailto:hannes@apache.org">Hannes Wallnoefer</a>
@@ -70,21 +70,21 @@
public class XmlRpcClient
implements XmlRpcHandler
{
- URL url;
- String auth;
+ protected URL url;
+ private String auth;
// pool of worker instances
- Stack pool = new Stack ();
- int workers = 0;
- int asyncWorkers = 0;
+ protected Stack pool = new Stack();
+ protected int workers = 0;
+ protected int asyncWorkers = 0;
// a queue of calls to be handled asynchronously
- CallData first, last;
+ private CallData first, last;
/**
* Construct a XML-RPC client with this URL.
*/
- public XmlRpcClient (URL url)
+ public XmlRpcClient(URL url)
{
this.url = url;
}
@@ -92,24 +92,24 @@
/**
* Construct a XML-RPC client for the URL represented by this String.
*/
- public XmlRpcClient (String url) throws MalformedURLException
+ public XmlRpcClient(String url) throws MalformedURLException
{
- this.url = new URL (url);
+ this.url = new URL(url);
}
/**
* Construct a XML-RPC client for the specified hostname and port.
*/
- public XmlRpcClient (String hostname,
+ public XmlRpcClient(String hostname,
int port) throws MalformedURLException
{
- this.url = new URL ("http://" + hostname + ':' + port + "/RPC2");
+ this.url = new URL("http://" + hostname + ':' + port + "/RPC2");
}
/**
* Return the URL for this XML-RPC client.
*/
- public URL getURL ()
+ public URL getURL()
{
return url;
}
@@ -118,15 +118,17 @@
* Sets Authentication for this client. This will be sent as Basic Authentication header
* to the server as described in <a href="http://www.ietf.org/rfc/rfc2617.txt">http://www.ietf.org/rfc/rfc2617.txt</a>.
*/
- public void setBasicAuthentication (String user, String password)
+ public void setBasicAuthentication(String user, String password)
{
if (user == null || password == null)
+ {
auth = null;
+ }
else
{
- char[] basicAuth =
- Base64.encode ((user + ":"+password).getBytes());
- auth = new String (basicAuth).trim();
+ auth = new String(
+ Base64.encode((user + ':' + password)
+ .getBytes())).trim();
}
}
@@ -138,18 +140,18 @@
* @exception XmlRpcException: If the remote host returned a fault message.
* @exception IOException: If the call could not be made because of lower level problems.
*/
- public Object execute (String method,
+ public Object execute(String method,
Vector params) throws XmlRpcException, IOException
{
- Worker worker = getWorker (false);
+ Worker worker = getWorker(false);
try
{
- Object retval = worker.execute (method, params);
+ Object retval = worker.execute(method, params);
return retval;
}
finally
{
- releaseWorker (worker, false);
+ releaseWorker(worker, false);
}
}
@@ -159,78 +161,93 @@
* If the callback parameter is not null, it will be called later to handle the result or error when the call is finished.
*
*/
- public void executeAsync (String method, Vector params,
- AsyncCallback callback)
+ public void executeAsync(String method, Vector params,
+ AsyncCallback callback)
{
// if at least 4 threads are running, don't create any new ones,
- // just enqueue the request.
+ // just enqueue the request.
if (asyncWorkers >= 4)
{
- enqueue (method, params, callback);
+ enqueue(method, params, callback);
return;
}
Worker worker = null;
try
{
- worker = getWorker (true);
- worker.start (method, params, callback);
+ worker = getWorker(true);
+ worker.start(method, params, callback);
}
- catch (IOException iox)
+ catch(IOException iox)
{
// make a queued worker that doesn't run immediately
- enqueue (method, params, callback);
+ enqueue(method, params, callback);
}
}
-
- synchronized Worker getWorker (boolean async)
+ synchronized Worker getWorker(boolean async)
throws IOException
{
try
{
- Worker w = (Worker) pool.pop ();
+ Worker w =(Worker) pool.pop();
if (async)
+ {
asyncWorkers += 1;
+ }
else
+ {
workers += 1;
+ }
return w;
}
- catch (EmptyStackException x)
+ catch(EmptyStackException x)
{
if (workers < XmlRpc.getMaxThreads())
{
if (async)
+ {
asyncWorkers += 1;
+ }
else
+ {
workers += 1;
- return new Worker ();
+ }
+ return new Worker();
}
- throw new IOException ("XML-RPC System overload");
+ throw new IOException("XML-RPC System overload");
}
}
/**
* Release possibly big per-call object references to allow them to be garbage collected
*/
- synchronized void releaseWorker (Worker w, boolean async)
+ synchronized void releaseWorker(Worker w, boolean async)
{
w.result = null;
w.call = null;
if (pool.size() < 20 && !w.fault)
- pool.push (w);
+ {
+ pool.push(w);
+ }
if (async)
+ {
asyncWorkers -= 1;
+ }
else
+ {
workers -= 1;
+ }
}
- synchronized void enqueue (String method, Vector params,
+ synchronized void enqueue(String method, Vector params,
AsyncCallback callback)
{
- CallData call = new CallData (method, params, callback);
+ CallData call = new CallData(method, params, callback);
if (last == null)
+ {
first = last = call;
+ }
else
{
last.next = call;
@@ -238,15 +255,21 @@
}
}
- synchronized CallData dequeue ()
+ synchronized CallData dequeue()
{
if (first == null)
+ {
return null;
+ }
CallData call = first;
if (first == last)
+ {
first = last = null;
+ }
else
+ {
first = first.next;
+ }
return call;
}
@@ -262,52 +285,53 @@
CallData call;
- public Worker ()
+ public Worker()
{
- super ();
+ super();
}
- public void start (String method, Vector params,
+ public void start(String method, Vector params,
AsyncCallback callback)
{
- this.call = new CallData (method, params, callback);
- Thread t = new Thread (this);
- t.start ();
+ this.call = new CallData(method, params, callback);
+ Thread t = new Thread(this);
+ t.start();
}
- public void run ()
+ public void run()
{
while (call != null)
{
- executeAsync (call.method, call.params, call.callback);
- call = dequeue ();
+ executeAsync(call.method, call.params, call.callback);
+ call = dequeue();
}
- releaseWorker (this, true);
+ releaseWorker(this, true);
}
-
/**
* Execute an XML-RPC call and handle asyncronous callback.
*/
- void executeAsync (String method, Vector params, AsyncCallback callback)
+ void executeAsync(String method, Vector params, AsyncCallback callback)
{
Object res = null;
try
{
- res = execute (method, params);
+ res = execute(method, params);
// notify callback object
if (callback != null)
- callback.handleResult (res, url, method);
+ {
+ callback.handleResult(res, url, method);
+ }
}
- catch (Exception x)
+ catch(Exception x)
{
if (callback != null)
{
try
{
- callback.handleError (x, url, method);
+ callback.handleError(x, url, method);
}
- catch (Exception ignore)
+ catch(Exception ignore)
{
}
}
@@ -317,18 +341,23 @@
/**
* Execute an XML-RPC call.
*/
- Object execute (String method,
+ Object execute(String method,
Vector params) throws XmlRpcException, IOException
{
- if (debug)
+ fault = false;
+ long now = 0;
+
+ if (XmlRpc.debug)
+ {
System.err.println("Client calling procedure '" + method +
"' with parameters " + params);
- fault = false;
- long now = System.currentTimeMillis ();
+ now = System.currentTimeMillis();
+ }
+
try
{
- ByteArrayOutputStream bout = new ByteArrayOutputStream ();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
if (buffer == null)
{
@@ -339,33 +368,36 @@
buffer.reset();
}
- XmlWriter writer = new XmlWriter (buffer);
- writeRequest (writer, method, params);
+ XmlWriter writer = new XmlWriter(buffer);
+ writeRequest(writer, method, params);
writer.flush();
byte[] request = buffer.toByteArray();
- URLConnection con = url.openConnection ();
- con.setDoInput (true);
- con.setDoOutput (true);
- con.setUseCaches (false);
+ URLConnection con = url.openConnection();
+ con.setDoInput(true);
+ con.setDoOutput(true);
+ con.setUseCaches(false);
con.setAllowUserInteraction(false);
- con.setRequestProperty ("Content-Length",
- Integer.toString (request.length));
- con.setRequestProperty ("Content-Type", "text/xml");
+ con.setRequestProperty("Content-Length",
+ Integer.toString(request.length));
+ con.setRequestProperty("Content-Type", "text/xml");
if (auth != null)
- con.setRequestProperty ("Authorization", "Basic "+auth);
- // con.connect ();
- OutputStream out = con.getOutputStream ();
- out.write (request);
- out.flush ();
- InputStream in = con.getInputStream ();
- parse (in);
- }
- catch (Exception x)
- {
- if (debug)
- x.printStackTrace ();
- throw new IOException (x.getMessage ());
+ {
+ con.setRequestProperty("Authorization", "Basic " + auth);
+ }
+ OutputStream out = con.getOutputStream();
+ out.write(request);
+ out.flush();
+ InputStream in = con.getInputStream();
+ parse(in);
+ }
+ catch(Exception x)
+ {
+ if (XmlRpc.debug)
+ {
+ x.printStackTrace();
+ }
+ throw new IOException(x.getMessage());
}
if (fault)
{
@@ -373,78 +405,76 @@
XmlRpcException exception = null;
try
{
- Hashtable f = (Hashtable) result;
- String faultString = (String) f.get ("faultString");
- int faultCode = Integer.parseInt (
- f.get ("faultCode").toString ());
- exception = new XmlRpcException (faultCode,
- faultString.trim ());
+ Hashtable f =(Hashtable) result;
+ String faultString =(String) f.get("faultString");
+ int faultCode = Integer.parseInt(
+ f.get("faultCode").toString());
+ exception = new XmlRpcException(faultCode,
+ faultString.trim());
}
- catch (Exception x)
+ catch(Exception x)
{
- throw new XmlRpcException (0, "Invalid fault response");
+ throw new XmlRpcException(0, "Invalid fault response");
}
throw exception;
}
- if (debug)
- System.err.println ("Spent "+
- (System.currentTimeMillis () - now) + " in request");
+ if (XmlRpc.debug)
+ {
+ System.err.println("Spent "+
+ (System.currentTimeMillis() - now) + " in request");
+ }
return result;
}
-
/**
* Called when the return value has been parsed.
*/
- void objectParsed (Object what)
+ void objectParsed(Object what)
{
result = what;
}
-
/**
* Generate an XML-RPC request from a method name and a parameter vector.
*/
- void writeRequest (XmlWriter writer, String method,
+ void writeRequest(XmlWriter writer, String method,
Vector params) throws IOException, XmlRpcException
{
- writer.startElement ("methodCall");
-
- writer.startElement ("methodName");
- writer.write (method);
- writer.endElement ("methodName");
-
- writer.startElement ("params");
- int l = params.size ();
+ writer.startElement("methodCall");
+ writer.startElement("methodName");
+ writer.write(method);
+ writer.endElement("methodName");
+ writer.startElement("params");
+ int l = params.size();
for (int i = 0; i < l; i++)
{
- writer.startElement ("param");
- writer.writeObject (params.elementAt (i));
- writer.endElement ("param");
+ writer.startElement("param");
+ writer.writeObject(params.elementAt(i));
+ writer.endElement("param");
}
- writer.endElement ("params");
- writer.endElement ("methodCall");
+ writer.endElement("params");
+ writer.endElement("methodCall");
}
/**
* Overrides method in XmlRpc to handle fault repsonses.
*/
- public void startElement (String name,
+ public void startElement(String name,
AttributeList atts) throws SAXException
{
- if ("fault".equals (name))
+ if ("fault".equals(name))
+ {
fault = true;
+ }
else
- super.startElement (name, atts);
+ {
+ super.startElement(name, atts);
+ }
}
-
-
} // end of inner class Worker
-
class CallData
{
-
String method;
Vector params;
AsyncCallback callback;
@@ -453,7 +483,7 @@
/**
* Make a call to be queued and then executed by the next free async thread
*/
- public CallData (String method, Vector params,
+ public CallData(String method, Vector params,
AsyncCallback callback)
{
this.method = method;
@@ -461,49 +491,47 @@
this.callback = callback;
this.next = null;
}
-
}
-
/**
* Just for testing.
*/
- public static void main (String args[]) throws Exception
+ public static void main(String args[]) throws Exception
{
- // XmlRpc.setDebug (true);
- // XmlRpc.setKeepAlive (true);
+ // XmlRpc.setDebug(true);
+ // XmlRpc.setKeepAlive(true);
try
{
String url = args[0];
String method = args[1];
- Vector v = new Vector ();
+ Vector v = new Vector();
for (int i = 2; i < args.length; i++)
+ {
try
{
- v.addElement (
- new Integer (Integer.parseInt (args[i])));
+ v.addElement(
+ new Integer(Integer.parseInt(args[i])));
}
- catch (NumberFormatException nfx)
+ catch(NumberFormatException nfx)
{
- v.addElement (args[i]);
+ v.addElement(args[i]);
}
- XmlRpcClient client = new XmlRpcClientLite (url);
+ }
+ XmlRpcClient client = new XmlRpcClientLite(url);
try
{
- System.err.println (client.execute (method, v));
+ System.err.println(client.execute(method, v));
}
- catch (Exception ex)
+ catch(Exception ex)
{
- System.err.println ("Error: "+ex.getMessage());
+ System.err.println("Error: " + ex.getMessage());
}
}
- catch (Exception x)
+ catch(Exception x)
{
- System.err.println (x);
- System.err.println ("Usage: java org.apache.xmlrpc.XmlRpcClient <url> <method> <arg> ....");
- System.err.println ("Arguments are sent as integers or strings.");
+ System.err.println(x);
+ System.err.println("Usage: java org.apache.xmlrpc.XmlRpcClient <url> <method> <arg> ....");
+ System.err.println("Arguments are sent as integers or strings.");
}
}
}
-
-
Re: cvs commit: xml-rpc/src/java/org/apache/xmlrpc Base64.java ServerInputStream.java WebServer.java XmlRpc.java XmlRpcClient.java
Posted by Daniel Rall <dl...@finemaltcoding.com>.
jon@apache.org writes:
> jon 02/02/18 18:25:02
>
> Modified: src/java/org/apache/xmlrpc Base64.java
> ServerInputStream.java WebServer.java XmlRpc.java
> XmlRpcClient.java
> Log:
> I did a bunch of code cleanup and minor
> optimizations, switched to the catalina Base64 (note the one FIXME, if
> someone has a suggestion for a better way, let me know).
>
> Found a couple optimizations (such as not calling System.currentTimeMillis()
> unless debug is on...
Ugh, you mixed'em...
Re: cvs commit: xml-rpc/src/java/org/apache/xmlrpc Base64.java ServerInputStream.java WebServer.java XmlRpc.java XmlRpcClient.java
Posted by Daniel Rall <dl...@finemaltcoding.com>.
jon@apache.org writes:
> jon 02/02/18 18:25:02
>
> Modified: src/java/org/apache/xmlrpc Base64.java
> ServerInputStream.java WebServer.java XmlRpc.java
> XmlRpcClient.java
> Log:
> I did a bunch of code cleanup and minor
> optimizations, switched to the catalina Base64 (note the one FIXME, if
> someone has a suggestion for a better way, let me know).
>
> Found a couple optimizations (such as not calling System.currentTimeMillis()
> unless debug is on...
Ugh, you mixed'em...