jochen 2005/05/24 14:05:39
Modified: src/java/org/apache/xmlrpc/util Tag: b20050512_streaming HttpUtil.java src/java/org/apache/xmlrpc/client Tag: b20050512_streaming XmlRpcLocalStreamTransport.java . Tag: b20050512_streaming .classpath src/java/org/apache/xmlrpc/webserver Tag: b20050512_streaming ConnectionServer.java Connection.java src/java/org/apache/xmlrpc Tag: b20050512_streaming XmlRpcException.java src/test/org/apache/xmlrpc/test Tag: b20050512_streaming BaseTest.java src/java/org/apache/xmlrpc/server Tag: b20050512_streaming XmlRpcStreamServer.java Added: src/java/org/apache/xmlrpc/webserver Tag: b20050512_streaming XmlRpcServletServer.java XmlRpcServlet.java Log: Created the (yet untested) XmlRpcServlet. Revision Changes Path No revision No revision 1.4.2.4 +55 -1 ws-xmlrpc/src/java/org/apache/xmlrpc/util/HttpUtil.java Index: HttpUtil.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/util/HttpUtil.java,v retrieving revision 1.4.2.3 retrieving revision 1.4.2.4 diff -u -r1.4.2.3 -r1.4.2.4 --- HttpUtil.java 22 May 2005 20:52:27 -0000 1.4.2.3 +++ HttpUtil.java 24 May 2005 21:05:38 -0000 1.4.2.4 @@ -18,9 +18,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.util.Enumeration; import java.util.StringTokenizer; import org.apache.ws.commons.util.Base64; +import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl; import org.apache.xmlrpc.common.XmlRpcStreamConfig; @@ -47,7 +49,7 @@ /** Returns, whether the HTTP header value <code>pHeaderValue</code> * indicates, that GZIP encoding is used or may be used. - * @param pHeaderValue The HTTP header value being parser. This is typically + * @param pHeaderValue The HTTP header value being parsed. This is typically * the value of "Content-Encoding", or "Accept-Encoding". * @return True, if the header value suggests that GZIP encoding is or may * be used. @@ -69,6 +71,24 @@ return false; } + /** Returns, whether the HTTP header values in <code>pValues</code> + * indicate, that GZIP encoding is used or may be used. + * @param pValues The HTTP header values being parsed. These are typically + * the values of "Content-Encoding", or "Accept-Encoding". + * @return True, if the header values suggests that GZIP encoding is or may + * be used. + */ + public static boolean isUsingGzipEncoding(Enumeration pValues) { + if (pValues != null) { + while (pValues.hasMoreElements()) { + if (isUsingGzipEncoding((String) pValues.nextElement())) { + return true; + } + } + } + return false; + } + /** Reads a header line from the input stream <code>pIn</code> * and converts it into a string. * @param pIn The input stream being read. @@ -95,4 +115,38 @@ } return new String(pBuffer, 0, count); } + + /** Parses an "Authorization" header and adds the username and password + * to <code>pConfig</code>. + * @param pConfig The request configuration being created. + * @param pLine The header being parsed, including the "basic" part. + */ + public static void parseAuthorization(XmlRpcHttpRequestConfigImpl pConfig, String pLine) { + if (pLine == null) { + return; + } + pLine = pLine.trim(); + StringTokenizer st = new StringTokenizer(pLine); + if (!st.hasMoreTokens()) { + return; + } + String type = st.nextToken(); + if (!"basic".equalsIgnoreCase(type)) { + return; + } + if (!st.hasMoreTokens()) { + return; + } + String auth = st.nextToken(); + try { + byte[] c = Base64.decode(auth.toCharArray(), 0, auth.length()); + String str = new String(c, pConfig.getBasicEncoding()); + int col = str.indexOf(':'); + if (col >= 0) { + pConfig.setBasicUserName(str.substring(0, col)); + pConfig.setBasicPassword(str.substring(col+1)); + } + } catch (Throwable ignore) { + } + } } No revision No revision 1.1.2.3 +2 -2 ws-xmlrpc/src/java/org/apache/xmlrpc/client/Attic/XmlRpcLocalStreamTransport.java Index: XmlRpcLocalStreamTransport.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/client/Attic/XmlRpcLocalStreamTransport.java,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -r1.1.2.2 -r1.1.2.3 --- XmlRpcLocalStreamTransport.java 21 May 2005 02:37:08 -0000 1.1.2.2 +++ XmlRpcLocalStreamTransport.java 24 May 2005 21:05:38 -0000 1.1.2.3 @@ -43,11 +43,11 @@ XmlRpcServer server = ((XmlRpcLocalClientConfig) pRequest.getConfig()).getXmlRpcServer(); return server.execute(pRequest); } - protected InputStream getInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { + protected InputStream newInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { LocalStreamConnection lsc = (LocalStreamConnection) pConnection; return new ByteArrayInputStream(lsc.ostream.toByteArray()); } - protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { + protected OutputStream newOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { LocalStreamConnection lsc = (LocalStreamConnection) pConnection; lsc.istream = new ByteArrayOutputStream(); return lsc.istream; No revision No revision 1.4.2.4 +1 -0 ws-xmlrpc/.classpath Index: .classpath =================================================================== RCS file: /home/cvs/ws-xmlrpc/.classpath,v retrieving revision 1.4.2.3 retrieving revision 1.4.2.4 diff -u -r1.4.2.3 -r1.4.2.4 --- .classpath 21 May 2005 22:01:24 -0000 1.4.2.3 +++ .classpath 24 May 2005 21:05:38 -0000 1.4.2.4 @@ -9,5 +9,6 @@ <classpathentry kind="lib" path="lib/commons-httpclient-2.0.2.jar"/> <classpathentry kind="lib" path="lib/commons-logging.jar"/> <classpathentry kind="lib" path="lib/jaxmeapi-0.4.jar"/> + <classpathentry kind="lib" path="lib/servletapi-2.2.jar"/> <classpathentry kind="output" path="bin"/> </classpath> No revision No revision 1.1.2.2 +2 -2 ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/ConnectionServer.java Index: ConnectionServer.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/ConnectionServer.java,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- ConnectionServer.java 12 May 2005 01:58:53 -0000 1.1.2.1 +++ ConnectionServer.java 24 May 2005 21:05:38 -0000 1.1.2.2 @@ -58,11 +58,11 @@ } } - protected InputStream getInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { + protected InputStream newInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { return ((Connection) pConnection).getInputStream((RequestData) pConfig); } - protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { + protected OutputStream newOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException { return ((Connection) pConnection).getOutputStream(pConfig); } 1.1.2.5 +7 -23 ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java Index: Connection.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- Connection.java 22 May 2005 20:52:27 -0000 1.1.2.4 +++ Connection.java 24 May 2005 21:05:38 -0000 1.1.2.5 @@ -25,13 +25,14 @@ import java.net.Socket; import java.util.StringTokenizer; -import org.apache.ws.commons.util.Base64; +import javax.servlet.http.HttpUtils; + import org.apache.xmlrpc.common.XmlRpcHttpRequestConfig; -import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl; import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException; import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig; import org.apache.xmlrpc.server.XmlRpcHttpServerConfig; import org.apache.xmlrpc.server.XmlRpcStreamServer; +import org.apache.xmlrpc.util.HttpUtil; import org.apache.xmlrpc.util.LimitedInputStream; import org.apache.xmlrpc.util.ThreadPool; @@ -148,9 +149,9 @@ } else if (lineLower.startsWith("connection:")) { result.setKeepAlive(serverConfig.isKeepAliveEnabled() && lineLower.indexOf("keep-alive") > -1); - } else if (lineLower.startsWith("authorization: basic ")) { - String credentials = line.substring("authorization: basic ".length()); - parseAuth(result, credentials); + } else if (lineLower.startsWith("authorization:")) { + String credentials = line.substring("authorization:".length()); + HttpUtil.parseAuthorization(result, credentials); } } } @@ -200,24 +201,7 @@ return new String(buffer, 0, count, US_ASCII); } - /** - * - * @param line - */ - private void parseAuth(XmlRpcHttpRequestConfigImpl pConfig, String pLine) { - try { - byte[] c = Base64.decode(pLine.toCharArray(), 0, pLine.length()); - String str = new String(c, pConfig.getBasicEncoding()); - int col = str.indexOf(':'); - if (col >= 0) { - pConfig.setBasicUserName(str.substring(0, col)); - pConfig.setBasicPassword(str.substring(col+1)); - } - } catch (Throwable ignore) { - } - } - - /** Returns the contents input stream. + /** Returns the contents input stream. * @param pData The request data * @return The contents input stream. */ No revision Index: Connection.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- Connection.java 22 May 2005 20:52:27 -0000 1.1.2.4 +++ Connection.java 24 May 2005 21:05:38 -0000 1.1.2.5 @@ -25,13 +25,14 @@ import java.net.Socket; import java.util.StringTokenizer; -import org.apache.ws.commons.util.Base64; +import javax.servlet.http.HttpUtils; + import org.apache.xmlrpc.common.XmlRpcHttpRequestConfig; -import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl; import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException; import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig; import org.apache.xmlrpc.server.XmlRpcHttpServerConfig; import org.apache.xmlrpc.server.XmlRpcStreamServer; +import org.apache.xmlrpc.util.HttpUtil; import org.apache.xmlrpc.util.LimitedInputStream; import org.apache.xmlrpc.util.ThreadPool; @@ -148,9 +149,9 @@ } else if (lineLower.startsWith("connection:")) { result.setKeepAlive(serverConfig.isKeepAliveEnabled() && lineLower.indexOf("keep-alive") > -1); - } else if (lineLower.startsWith("authorization: basic ")) { - String credentials = line.substring("authorization: basic ".length()); - parseAuth(result, credentials); + } else if (lineLower.startsWith("authorization:")) { + String credentials = line.substring("authorization:".length()); + HttpUtil.parseAuthorization(result, credentials); } } } @@ -200,24 +201,7 @@ return new String(buffer, 0, count, US_ASCII); } - /** - * - * @param line - */ - private void parseAuth(XmlRpcHttpRequestConfigImpl pConfig, String pLine) { - try { - byte[] c = Base64.decode(pLine.toCharArray(), 0, pLine.length()); - String str = new String(c, pConfig.getBasicEncoding()); - int col = str.indexOf(':'); - if (col >= 0) { - pConfig.setBasicUserName(str.substring(0, col)); - pConfig.setBasicPassword(str.substring(col+1)); - } - } catch (Throwable ignore) { - } - } - - /** Returns the contents input stream. + /** Returns the contents input stream. * @param pData The request data * @return The contents input stream. */ No revision Index: Connection.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/Connection.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- Connection.java 22 May 2005 20:52:27 -0000 1.1.2.4 +++ Connection.java 24 May 2005 21:05:38 -0000 1.1.2.5 @@ -25,13 +25,14 @@ import java.net.Socket; import java.util.StringTokenizer; -import org.apache.ws.commons.util.Base64; +import javax.servlet.http.HttpUtils; + import org.apache.xmlrpc.common.XmlRpcHttpRequestConfig; -import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl; import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException; import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig; import org.apache.xmlrpc.server.XmlRpcHttpServerConfig; import org.apache.xmlrpc.server.XmlRpcStreamServer; +import org.apache.xmlrpc.util.HttpUtil; import org.apache.xmlrpc.util.LimitedInputStream; import org.apache.xmlrpc.util.ThreadPool; @@ -148,9 +149,9 @@ } else if (lineLower.startsWith("connection:")) { result.setKeepAlive(serverConfig.isKeepAliveEnabled() && lineLower.indexOf("keep-alive") > -1); - } else if (lineLower.startsWith("authorization: basic ")) { - String credentials = line.substring("authorization: basic ".length()); - parseAuth(result, credentials); + } else if (lineLower.startsWith("authorization:")) { + String credentials = line.substring("authorization:".length()); + HttpUtil.parseAuthorization(result, credentials); } } } @@ -200,24 +201,7 @@ return new String(buffer, 0, count, US_ASCII); } - /** - * - * @param line - */ - private void parseAuth(XmlRpcHttpRequestConfigImpl pConfig, String pLine) { - try { - byte[] c = Base64.decode(pLine.toCharArray(), 0, pLine.length()); - String str = new String(c, pConfig.getBasicEncoding()); - int col = str.indexOf(':'); - if (col >= 0) { - pConfig.setBasicUserName(str.substring(0, col)); - pConfig.setBasicPassword(str.substring(col+1)); - } - } catch (Throwable ignore) { - } - } - - /** Returns the contents input stream. + /** Returns the contents input stream. * @param pData The request data * @return The contents input stream. */ 1.1.2.1 +128 -0 ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/XmlRpcServletServer.java 1.1.2.1 +82 -0 ws-xmlrpc/src/java/org/apache/xmlrpc/webserver/Attic/XmlRpcServlet.java No revision No revision 1.3.2.2 +8 -0 ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcException.java Index: XmlRpcException.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/XmlRpcException.java,v retrieving revision 1.3.2.1 retrieving revision 1.3.2.2 diff -u -r1.3.2.1 -r1.3.2.2 --- XmlRpcException.java 12 May 2005 01:58:52 -0000 1.3.2.1 +++ XmlRpcException.java 24 May 2005 21:05:38 -0000 1.3.2.2 @@ -58,6 +58,14 @@ this(0, pMessage, pLinkedException); } + /** Creates a new instance with the given error message + * and error code 0. + * @param pMessage Detail message. + */ + public XmlRpcException(String pMessage) { + this(0, pMessage, null); + } + /** Creates a new instance with the given error code, error message * and cause. * @param pCode Error code. No revision No revision 1.1.2.5 +0 -1 ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTest.java Index: BaseTest.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/test/org/apache/xmlrpc/test/Attic/BaseTest.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- BaseTest.java 23 May 2005 06:11:14 -0000 1.1.2.4 +++ BaseTest.java 24 May 2005 21:05:39 -0000 1.1.2.5 @@ -17,7 +17,6 @@ import java.io.IOException; import java.io.StringReader; -import java.text.DateFormat; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Arrays; No revision No revision 1.1.2.5 +79 -8 ws-xmlrpc/src/java/org/apache/xmlrpc/server/Attic/XmlRpcStreamServer.java Index: XmlRpcStreamServer.java =================================================================== RCS file: /home/cvs/ws-xmlrpc/src/java/org/apache/xmlrpc/server/Attic/XmlRpcStreamServer.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- XmlRpcStreamServer.java 14 May 2005 21:17:49 -0000 1.1.2.4 +++ XmlRpcStreamServer.java 24 May 2005 21:05:39 -0000 1.1.2.5 @@ -15,10 +15,13 @@ */ package org.apache.xmlrpc.server; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; @@ -133,18 +136,55 @@ /** Returns the connections input stream. */ - protected abstract InputStream getInputStream(XmlRpcStreamRequestConfig pConfig, + protected abstract InputStream newInputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException; - /** Returns the connections output stream. + protected InputStream getInputStream(XmlRpcStreamRequestConfig pConfig, + Object pConnection) throws IOException { + InputStream istream = newInputStream(pConfig, pConnection); + if (pConfig.isEnabledForExtensions() && pConfig.isGzipCompressing()) { + istream = new GZIPInputStream(istream); + } + return istream; + } + + /** Creates the connections output stream. */ - protected abstract OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, + protected abstract OutputStream newOutputStream(XmlRpcStreamRequestConfig pConfig, Object pConnection) throws IOException; + /** Called to prepare the output stream. Typically used for enabling + * compression, or similar filters. + */ + protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, + OutputStream pStream) throws IOException { + if (pConfig.isEnabledForExtensions() && pConfig.isGzipRequesting()) { + return new GZIPOutputStream(pStream); + } else { + return pStream; + } + } + + /** Called to prepare the output stream, if content length is + * required. + */ + protected OutputStream getOutputStream(XmlRpcStreamRequestConfig pConfig, + Object pConnection, + int pSize) throws IOException { + return newOutputStream(pConfig, pConnection); + } + + /** Returns, whether the requests content length is required. + */ + protected boolean isContentLengthRequired(XmlRpcStreamRequestConfig pConfig) { + return false; + } + /** Closes the connection, releasing all resources. */ protected abstract void closeConnection(Object pConnection) throws IOException; + /** Returns, whether the /** Processes a "connection". The "connection" is an opaque object, which is * being handled by the subclasses. * @param pConfig The request configuration. @@ -158,20 +198,51 @@ try { Object result; Throwable error; + InputStream istream = null; try { - InputStream istream = getInputStream(pConfig, pConnection); + istream = getInputStream(pConfig, pConnection); XmlRpcRequest request = getRequest(pConfig, istream); result = execute(request); + istream.close(); + istream = null; error = null; } catch (Throwable t) { result = null; error = t; + } finally { + if (istream != null) { try { istream.close(); } catch (Throwable ignore) {} } } - OutputStream ostream = getOutputStream(pConfig, pConnection); - if (error == null) { - writeResponse(pConfig, ostream, result); + boolean contentLengthRequired = isContentLengthRequired(pConfig); + ByteArrayOutputStream baos; + OutputStream ostream; + if (contentLengthRequired) { + baos = new ByteArrayOutputStream(); + ostream = baos; } else { - writeError(pConfig, ostream, error); + baos = null; + ostream = newOutputStream(pConfig, pConnection); + } + ostream = getOutputStream(pConfig, ostream); + try { + if (error == null) { + writeResponse(pConfig, ostream, result); + } else { + writeError(pConfig, ostream, error); + } + ostream.close(); + ostream = null; + } finally { + if (ostream != null) { try { ostream.close(); } catch (Throwable ignore) {} } + } + if (baos != null) { + OutputStream dest = getOutputStream(pConfig, pConnection, baos.size()); + try { + baos.writeTo(dest); + dest.close(); + dest = null; + } finally { + if (dest != null) { try { dest.close(); } catch (Throwable ignore) {} } + } } closeConnection(pConnection); pConnection = null;