Author: jochen
Date: Wed Sep 20 00:33:14 2006
New Revision: 448107

URL: http://svn.apache.org/viewvc?view=rev&rev=448107
Log:
The WebServer is now returning an HTTP error 401 (Not Implemented),

if the client is using chunked encoding.

PR: XMLRPC-114


Modified:
    webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/pom.xml
    
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
    webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/pom.xml
    
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/src/main/java/org/apache/xmlrpc/util/HttpUtil.java
    webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/pom.xml
    webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/pom.xml
    
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/Connection.java
    
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/ConnectionServer.java
    webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/src/changes/changes.xml
    webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/tests/pom.xml

Modified: webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/pom.xml?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/pom.xml (original)
+++ webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/pom.xml Wed Sep 20 
00:33:14 2006
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.apache.xmlrpc</groupId>
     <artifactId>xmlrpc</artifactId>
-    <version>3.0</version>
+    <version>3.0.1-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>xmlrpc-client</artifactId>

Modified: 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
 (original)
+++ 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
 Wed Sep 20 00:33:14 2006
@@ -93,8 +93,8 @@
        }
 
        protected InputStream getInputStream() throws XmlRpcException {
-               try {
-                       return method.getResponseBodyAsStream();
+        try {
+            return method.getResponseBodyAsStream();
                } catch (HttpException e) {
                        throw new XmlRpcClientException("Error in HTTP 
transport: " + e.getMessage(), e);
                } catch (IOException e) {

Modified: webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/pom.xml?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/pom.xml (original)
+++ webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/pom.xml Wed Sep 20 
00:33:14 2006
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.apache.xmlrpc</groupId>
     <artifactId>xmlrpc</artifactId>
-    <version>3.0</version>
+    <version>3.0.1-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>xmlrpc-common</artifactId>

Modified: 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/src/main/java/org/apache/xmlrpc/util/HttpUtil.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/src/main/java/org/apache/xmlrpc/util/HttpUtil.java?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/src/main/java/org/apache/xmlrpc/util/HttpUtil.java
 (original)
+++ 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/common/src/main/java/org/apache/xmlrpc/util/HttpUtil.java
 Wed Sep 20 00:33:14 2006
@@ -72,6 +72,30 @@
         return false;
     }
 
+    /**
+     * Returns, whether the HTTP header value <code>pHeaderValue</code>
+     * indicates, that another encoding than "identity" is used.
+     * This is typically the value of "Transfer-Encoding", or "TE".
+     * @return Null, if the transfer encoding in use is "identity".
+     *   Otherwise, another transfer encoding. 
+     */
+    public static String getNonIdentityTransferEncoding(String pHeaderValue) {
+        if (pHeaderValue == null) {
+            return null;
+        }
+        for (StringTokenizer st = new StringTokenizer(pHeaderValue, ",");  
st.hasMoreTokens();  ) {
+            String encoding = st.nextToken();
+            int offset = encoding.indexOf(';');
+            if (offset >= 0) {
+                encoding = encoding.substring(0, offset);
+            }
+            if (!"identity".equalsIgnoreCase(encoding.trim())) {
+                return encoding.trim();
+            }
+        }
+        return null;
+    }
+
        /** 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

Modified: webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/pom.xml?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/pom.xml (original)
+++ webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/pom.xml Wed Sep 20 00:33:14 
2006
@@ -9,7 +9,7 @@
     <groupId>org.apache.xmlrpc</groupId>
     <artifactId>xmlrpc</artifactId>
     <name>Apache XML-RPC</name>
-    <version>3.0</version>
+    <version>3.0.1-SNAPSHOT</version>
     <description>
         Apache XML-RPC is a Java implementation of XML-RPC, a popular protocol
         that uses XML over HTTP to implement remote procedure calls.

Modified: webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/pom.xml?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/pom.xml (original)
+++ webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/pom.xml Wed Sep 20 
00:33:14 2006
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.apache.xmlrpc</groupId>
     <artifactId>xmlrpc</artifactId>
-    <version>3.0</version>
+    <version>3.0.1-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>xmlrpc-server</artifactId>

Modified: 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/Connection.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/Connection.java?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/Connection.java
 (original)
+++ 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/Connection.java
 Wed Sep 20 00:33:14 2006
@@ -54,10 +54,26 @@
     private static final byte[] serverName = toHTTPBytes("Server: Apache 
XML-RPC 1.0\r\n");
     private static final byte[] wwwAuthenticate = 
toHTTPBytes("WWW-Authenticate: Basic realm=XML-RPC\r\n");
 
-    private static class BadRequestException extends IOException {
+    private static abstract class RequestException extends IOException {
+        private final RequestData requestData;
+        RequestException(RequestData pData, String pMessage) {
+            super(pMessage);
+            requestData = pData;
+        }
+        RequestData getRequestData() { return requestData; }
+    }
+
+    private static class BadEncodingException extends RequestException {
+        private static final long serialVersionUID = -2674424938251521248L;
+        BadEncodingException(RequestData pData, String pTransferEncoding) {
+            super(pData, pTransferEncoding);
+        }
+    }
+
+    private static class BadRequestException extends RequestException {
         private static final long serialVersionUID = 3257848779234554934L;
-        BadRequestException(String pMethod) {
-            super(pMethod);
+        BadRequestException(RequestData pData, String pTransferEncoding) {
+            super(pData, pTransferEncoding);
         }
     }
 
@@ -136,7 +152,7 @@
         StringTokenizer tokens = new StringTokenizer(line);
         String method = tokens.nextToken();
         if (!"POST".equalsIgnoreCase(method)) {
-            throw new BadRequestException(method);
+            throw new BadRequestException(requestData, method);
         }
         requestData.setMethod(method);
         tokens.nextToken(); // Skip URI
@@ -157,6 +173,12 @@
                 } else if (lineLower.startsWith("authorization:")) {
                     String credentials = 
line.substring("authorization:".length());
                     HttpUtil.parseAuthorization(requestData, credentials);
+                } else if (lineLower.startsWith("transfer-encoding:")) {
+                    String transferEncoding = 
line.substring("transfer-encoding:".length());
+                    String nonIdentityEncoding = 
HttpUtil.getNonIdentityTransferEncoding(transferEncoding);
+                    if (nonIdentityEncoding != null) {
+                        throw new BadEncodingException(requestData, 
nonIdentityEncoding);
+                    }
                 }
             }
         }
@@ -178,6 +200,13 @@
                     break;
                 }
             }
+        } catch (RequestException e) {
+            webServer.log(e.getClass().getName() + ": " + e.getMessage());
+            try {
+                writeErrorHeader(e.requestData, e, -1);
+            } catch (IOException e1) {
+                /* Ignore me */
+            }
         } catch (Throwable t) {
             webServer.log(t);
         } finally {
@@ -255,11 +284,10 @@
      * @param pStream The [EMAIL PROTECTED] ByteArrayOutputStream} with the 
error response.
      * @throws IOException Writing the response failed.
      */
-    public void writeError(RequestData pData, Throwable pError, OutputStream 
pStream)
+    public void writeError(RequestData pData, Throwable pError, 
ByteArrayOutputStream pStream)
             throws IOException {
-        ByteArrayOutputStream errorResponse = (ByteArrayOutputStream) pStream;
-        writeErrorHeader(pData, pError, errorResponse.size());
-        errorResponse.writeTo(output);
+        writeErrorHeader(pData, pError, pStream.size());
+        pStream.writeTo(output);
     }
 
     /** Writes an error responses headers to the output stream.
@@ -271,37 +299,59 @@
     public void writeErrorHeader(RequestData pData, Throwable pError, int 
pContentLength)
             throws IOException {
         if (pError instanceof BadRequestException) {
+            final byte[] content = toHTTPBytes("Method " + pData.getMethod()
+                    + " not implemented (try POST)\r\n");
             output.write(toHTTPBytes(pData.getHttpVersion()));
             output.write(toHTTPBytes(" 400 Bad Request"));
             output.write(newline);
             output.write(serverName);
-            output.write(doubleNewline);
-            output.write(toHTTPBytes("Method " + pData.getMethod() +
-            " not implemented (try POST)"));
+            writeContentLengthHeader(content.length);
+            output.write(newline);
+            output.write(content);
+        } else if (pError instanceof BadEncodingException) {
+            final byte[] content = toHTTPBytes("The Transfer-Encoding " + 
pError.getMessage()
+                    + " is not implemented.\r\n");
+            output.write(toHTTPBytes(pData.getHttpVersion()));
+            output.write(toHTTPBytes(" 501 Not Implemented"));
+            output.write(newline);
+            output.write(serverName);
+            writeContentLengthHeader(content.length);
+            output.write(newline);
+            output.write(content);
         } else if (pError instanceof XmlRpcNotAuthorizedException) {
+            final byte[] content = toHTTPBytes("Method " + pData.getMethod()
+                    + " requires a " + "valid user name and password");
             output.write(toHTTPBytes(pData.getHttpVersion()));
             output.write(toHTTPBytes(" 401 Unauthorized"));
             output.write(newline);
             output.write(serverName);
+            writeContentLengthHeader(content.length);
             output.write(wwwAuthenticate);
-            output.write(doubleNewline);
-            output.write(toHTTPBytes("Method " + pData.getMethod() + " 
requires a " +
-            "valid user name and password"));
+            output.write(newline);
+            output.write(content);
         } else {
             output.write(toHTTPBytes(pData.getHttpVersion()));
             output.write(ok);
             output.write(serverName);
             output.write(conclose);
             output.write(ctype);
-            if (pContentLength != -1) {
-                output.write(clength);
-                output.write(toHTTPBytes(Integer.toString(pContentLength)));
-                output.write(newline);
-            }
+            writeContentLengthHeader(pContentLength);
             output.write(newline);
         }
+        output.flush();
+    }
+
+    private void writeContentLengthHeader(int pContentLength)
+            throws IOException {
+        if (pContentLength == -1) {
+            return;
+        }
+        output.write(clength);
+        output.write(toHTTPBytes(Integer.toString(pContentLength)));
+        output.write(newline);
     }
 
+    
     /** Sets a response header value.
      */
     public void setResponseHeader(String pHeader, String pValue) {

Modified: 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/ConnectionServer.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/ConnectionServer.java?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/ConnectionServer.java
 (original)
+++ 
webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/server/src/main/java/org/apache/xmlrpc/webserver/ConnectionServer.java
 Wed Sep 20 00:33:14 2006
@@ -15,8 +15,8 @@
  */
 package org.apache.xmlrpc.webserver;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 
 import org.apache.xmlrpc.XmlRpcException;
@@ -32,7 +32,7 @@
                try {
                        if (data.isByteArrayRequired()) {
                                super.writeError(pConfig, pStream, pError);
-                               data.getConnection().writeError(data, pError, 
pStream);
+                               data.getConnection().writeError(data, pError, 
(ByteArrayOutputStream) pStream);
                        } else {
                                data.getConnection().writeErrorHeader(data, 
pError, -1);
                                super.writeError(pConfig, pStream, pError);

Modified: webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/src/changes/changes.xml?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/src/changes/changes.xml 
(original)
+++ webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/src/changes/changes.xml Wed 
Sep 20 00:33:14 2006
@@ -18,6 +18,10 @@
         If the server was throwing an XmlRpcException, then the fault code and 
fault
         string weren't given to the client.
       </action>
+      <action dev="jochen" type="fix" issue="XMLRPC-114">
+        The WebServer replies with an HTTP error 401 now, if the
+        client uses chunked encoding.
+      </action>
     </release>
     <release version="3.0" date="30-Aug-2006">
       <action dev="jochen" type="fix" due-to="Matt Preston"

Modified: webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/tests/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/tests/pom.xml?view=diff&rev=448107&r1=448106&r2=448107
==============================================================================
--- webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/tests/pom.xml (original)
+++ webservices/xmlrpc/branches/XMLRPC_3_0_BRANCH/tests/pom.xml Wed Sep 20 
00:33:14 2006
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.apache.xmlrpc</groupId>
     <artifactId>xmlrpc</artifactId>
-    <version>3.0</version>
+    <version>3.0.1-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>xmlrpc-tests</artifactId>


Reply via email to