Author: jochen
Date: Fri Nov 28 13:36:58 2008
New Revision: 721564

URL: http://svn.apache.org/viewvc?rev=721564&view=rev
Log:
Improved the handling of HTTP status codes that indicate an error.
PR: XMLRPC-160
Submitted-By: Brandon DuRette <[EMAIL PROTECTED]>

Added:
    
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransportException.java
Modified:
    
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
    
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransport.java
    
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLiteHttpTransport.java
    
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcSunHttpTransport.java
    webservices/xmlrpc/trunk/pom.xml
    webservices/xmlrpc/trunk/src/changes/changes.xml

Modified: 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java?rev=721564&r1=721563&r2=721564&view=diff
==============================================================================
--- 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
 (original)
+++ 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcCommonsTransport.java
 Fri Nov 28 13:36:58 2008
@@ -28,6 +28,7 @@
 import org.apache.commons.httpclient.Header;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.HttpVersion;
 import org.apache.commons.httpclient.URI;
@@ -114,6 +115,7 @@
 
        protected InputStream getInputStream() throws XmlRpcException {
         try {
+            checkStatus(method);
             return method.getResponseBodyAsStream();
                } catch (HttpException e) {
                        throw new XmlRpcClientException("Error in HTTP 
transport: " + e.getMessage(), e);
@@ -242,4 +244,19 @@
                        throw new XmlRpcException("I/O error while 
communicating with HTTP server: " + e.getMessage(), e);
                }
        }
+    
+    /**
+     * Check the status of the HTTP request and throw an 
XmlRpcHttpTransportException if it
+     * indicates that there is an error.
+     * @param pMethod the method that has been executed
+     * @throws XmlRpcHttpTransportException if the status of the method 
indicates that there is an error.
+     */
+    private void checkStatus(HttpMethod pMethod) throws 
XmlRpcHttpTransportException {
+        final int status = pMethod.getStatusCode();
+        
+        // All status codes except SC_OK are handled as errors. Perhaps some 
should require special handling (e.g., SC_UNAUTHORIZED)
+        if (status < 200  ||  status > 299) {
+            throw new XmlRpcHttpTransportException(status, 
pMethod.getStatusText());
+        }
+    }
 }

Modified: 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransport.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransport.java?rev=721564&r1=721563&r2=721564&view=diff
==============================================================================
--- 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransport.java
 (original)
+++ 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransport.java
 Fri Nov 28 13:36:58 2008
@@ -1,137 +1,137 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.xmlrpc.client;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.xmlrpc.XmlRpcException;
-import org.apache.xmlrpc.XmlRpcRequest;
-import org.apache.xmlrpc.util.HttpUtil;
-import org.xml.sax.SAXException;
-
-
-/** Abstract base implementation of an HTTP transport. Base class for the
- * concrete implementations, like [EMAIL PROTECTED] 
org.apache.xmlrpc.client.XmlRpcSunHttpTransport},
- * or [EMAIL PROTECTED] org.apache.xmlrpc.client.XmlRpcCommonsTransport}.
- */
-public abstract class XmlRpcHttpTransport extends XmlRpcStreamTransport {
-    protected class ByteArrayReqWriter implements ReqWriter {
-        private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ByteArrayReqWriter(XmlRpcRequest pRequest)
-                throws XmlRpcException, IOException, SAXException {
-            new ReqWriterImpl(pRequest).write(baos);
-        }
-
-        protected int getContentLength() {
-            return baos.size();
-        }
-
-        public void write(OutputStream pStream) throws IOException {
-            try {
-                baos.writeTo(pStream);
-                pStream.close();
-                pStream = null;
-            } finally {
-                if (pStream != null) { try { pStream.close(); } catch 
(Throwable ignore) {} }
-            }
-        }
-    }
-
-       private String userAgent;
-
-       /** The user agent string.
-        */
-       public static final String USER_AGENT = "Apache XML RPC 3.0";
-
-       protected XmlRpcHttpTransport(XmlRpcClient pClient, String pUserAgent) {
-               super(pClient);
-               userAgent = pUserAgent;
-       }
-
-       protected String getUserAgent() { return userAgent; }
-
-       protected abstract void setRequestHeader(String pHeader, String pValue);
-
-       protected void setCredentials(XmlRpcHttpClientConfig pConfig)
-                       throws XmlRpcClientException {
-               String auth;
-               try {
-                       auth = 
HttpUtil.encodeBasicAuthentication(pConfig.getBasicUserName(),
-                                                                               
                          pConfig.getBasicPassword(),
-                                                                               
                          pConfig.getBasicEncoding());
-               } catch (UnsupportedEncodingException e) {
-                       throw new XmlRpcClientException("Unsupported encoding: 
" + pConfig.getBasicEncoding(), e);
-               }
-               if (auth != null) {
-                       setRequestHeader("Authorization", "Basic " + auth);
-               }
-       }
-
-       protected void setContentLength(int pLength) {
-               setRequestHeader("Content-Length", Integer.toString(pLength));
-       }
-
-       protected void setCompressionHeaders(XmlRpcHttpClientConfig pConfig) {
-               if (pConfig.isGzipCompressing()) {
-                       setRequestHeader("Content-Encoding", "gzip");
-               }
-               if (pConfig.isGzipRequesting()) {
-                       setRequestHeader("Accept-Encoding", "gzip");
-               }
-       }
-
-       protected void initHttpHeaders(XmlRpcRequest pRequest) throws 
XmlRpcClientException {
-               XmlRpcHttpClientConfig config = (XmlRpcHttpClientConfig) 
pRequest.getConfig();
-               setRequestHeader("Content-Type", "text/xml");
-        if(config.getUserAgent() != null)
-            setRequestHeader("User-Agent", config.getUserAgent());
-        else
-            setRequestHeader("User-Agent", getUserAgent());
-               setCredentials(config);
-               setCompressionHeaders(config);
-       }
-
-       public Object sendRequest(XmlRpcRequest pRequest) throws 
XmlRpcException {
-               initHttpHeaders(pRequest);
-               return super.sendRequest(pRequest);
-       }
-
-       protected boolean isUsingByteArrayOutput(XmlRpcHttpClientConfig 
pConfig) {
-               return !pConfig.isEnabledForExtensions()
-                       || !pConfig.isContentLengthOptional();
-       }
-
-       protected ReqWriter newReqWriter(XmlRpcRequest pRequest)
-                       throws XmlRpcException, IOException, SAXException {
-               final XmlRpcHttpClientConfig config = (XmlRpcHttpClientConfig) 
pRequest.getConfig();
-        if (isUsingByteArrayOutput(config)) {
-            ByteArrayReqWriter reqWriter = new ByteArrayReqWriter(pRequest);
-            setContentLength(reqWriter.getContentLength());
-            if (isCompressingRequest(config)) {
-                return new GzipReqWriter(reqWriter);
-            }
-            return reqWriter;
-               } else {
-                       return super.newReqWriter(pRequest);
-               }
-       }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.xmlrpc.client;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.XmlRpcRequest;
+import org.apache.xmlrpc.util.HttpUtil;
+import org.xml.sax.SAXException;
+
+
+/** Abstract base implementation of an HTTP transport. Base class for the
+ * concrete implementations, like [EMAIL PROTECTED] 
org.apache.xmlrpc.client.XmlRpcSunHttpTransport},
+ * or [EMAIL PROTECTED] org.apache.xmlrpc.client.XmlRpcCommonsTransport}.
+ */
+public abstract class XmlRpcHttpTransport extends XmlRpcStreamTransport {
+    protected class ByteArrayReqWriter implements ReqWriter {
+        private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ByteArrayReqWriter(XmlRpcRequest pRequest)
+                throws XmlRpcException, IOException, SAXException {
+            new ReqWriterImpl(pRequest).write(baos);
+        }
+
+        protected int getContentLength() {
+            return baos.size();
+        }
+
+        public void write(OutputStream pStream) throws IOException {
+            try {
+                baos.writeTo(pStream);
+                pStream.close();
+                pStream = null;
+            } finally {
+                if (pStream != null) { try { pStream.close(); } catch 
(Throwable ignore) {} }
+            }
+        }
+    }
+
+       private String userAgent;
+
+       /** The user agent string.
+        */
+       public static final String USER_AGENT = "Apache XML RPC 3.0";
+
+       protected XmlRpcHttpTransport(XmlRpcClient pClient, String pUserAgent) {
+               super(pClient);
+               userAgent = pUserAgent;
+       }
+
+       protected String getUserAgent() { return userAgent; }
+
+       protected abstract void setRequestHeader(String pHeader, String pValue);
+
+       protected void setCredentials(XmlRpcHttpClientConfig pConfig)
+                       throws XmlRpcClientException {
+               String auth;
+               try {
+                       auth = 
HttpUtil.encodeBasicAuthentication(pConfig.getBasicUserName(),
+                                                                               
                          pConfig.getBasicPassword(),
+                                                                               
                          pConfig.getBasicEncoding());
+               } catch (UnsupportedEncodingException e) {
+                       throw new XmlRpcClientException("Unsupported encoding: 
" + pConfig.getBasicEncoding(), e);
+               }
+               if (auth != null) {
+                       setRequestHeader("Authorization", "Basic " + auth);
+               }
+       }
+
+       protected void setContentLength(int pLength) {
+               setRequestHeader("Content-Length", Integer.toString(pLength));
+       }
+
+       protected void setCompressionHeaders(XmlRpcHttpClientConfig pConfig) {
+               if (pConfig.isGzipCompressing()) {
+                       setRequestHeader("Content-Encoding", "gzip");
+               }
+               if (pConfig.isGzipRequesting()) {
+                       setRequestHeader("Accept-Encoding", "gzip");
+               }
+       }
+
+       protected void initHttpHeaders(XmlRpcRequest pRequest) throws 
XmlRpcClientException {
+               XmlRpcHttpClientConfig config = (XmlRpcHttpClientConfig) 
pRequest.getConfig();
+               setRequestHeader("Content-Type", "text/xml");
+        if(config.getUserAgent() != null)
+            setRequestHeader("User-Agent", config.getUserAgent());
+        else
+            setRequestHeader("User-Agent", getUserAgent());
+               setCredentials(config);
+               setCompressionHeaders(config);
+       }
+
+       public Object sendRequest(XmlRpcRequest pRequest) throws 
XmlRpcException {
+               initHttpHeaders(pRequest);
+               return super.sendRequest(pRequest);
+       }
+
+       protected boolean isUsingByteArrayOutput(XmlRpcHttpClientConfig 
pConfig) {
+               return !pConfig.isEnabledForExtensions()
+                       || !pConfig.isContentLengthOptional();
+       }
+
+       protected ReqWriter newReqWriter(XmlRpcRequest pRequest)
+                       throws XmlRpcException, IOException, SAXException {
+               final XmlRpcHttpClientConfig config = (XmlRpcHttpClientConfig) 
pRequest.getConfig();
+        if (isUsingByteArrayOutput(config)) {
+            ByteArrayReqWriter reqWriter = new ByteArrayReqWriter(pRequest);
+            setContentLength(reqWriter.getContentLength());
+            if (isCompressingRequest(config)) {
+                return new GzipReqWriter(reqWriter);
+            }
+            return reqWriter;
+               } else {
+                       return super.newReqWriter(pRequest);
+               }
+       }
+}

Added: 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransportException.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransportException.java?rev=721564&view=auto
==============================================================================
--- 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransportException.java
 (added)
+++ 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcHttpTransportException.java
 Fri Nov 28 13:36:58 2008
@@ -0,0 +1,57 @@
+package org.apache.xmlrpc.client;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/**
+ * Exception thrown if the HTTP status code sent by the server
+ * indicates that the request could not be processed. In
+ * general, the 400 and 500 level HTTP status codes will
+ * result in an XmlRpcHttpTransportException being thrown.
+ */
+public class XmlRpcHttpTransportException extends XmlRpcException {
+    private static final long serialVersionUID = -6933992871198450027L;
+
+    private final int status;
+    private final String statusMessage;
+    
+    /**
+     * Creates a new instance with the specified HTTP status code
+     * and HTTP status message.
+     * @param pCode The HTTP status code
+     * @param pMessage The HTTP status message returned by the HTTP server
+     */
+    public XmlRpcHttpTransportException(int pCode, String pMessage) {
+        this(pCode, pMessage, "HTTP server returned unexpected status: " + 
pMessage);
+    }
+    
+    /**
+     * Construct a new XmlRpcHttpTransportException with the specified HTTP 
status code, 
+     * HTTP status message, and exception message.
+     * @param httpStatusCode the HTTP status code
+     * @param httpStatusMessage the HTTP status message returned by the HTTP 
server
+     * @param message the exception message.
+     */
+    public XmlRpcHttpTransportException(int httpStatusCode, String 
httpStatusMessage, String message) {
+        super( message );
+        this.status = httpStatusCode;
+        this.statusMessage = httpStatusMessage;
+    }
+    
+    /**
+     * Get the HTTP status code that resulted in this exception.
+     * @return the HTTP status code that resulted in this exception.
+     */
+    public int getStatusCode()
+    {
+        return status;
+    }
+    
+    /**
+     * Get the status message returned by the HTTP server.
+     * @return the status message returned by the HTTP server.
+     */
+    public String getStatusMessage()
+    {
+        return statusMessage;
+    }
+}

Modified: 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLiteHttpTransport.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLiteHttpTransport.java?rev=721564&r1=721563&r2=721564&view=diff
==============================================================================
--- 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLiteHttpTransport.java
 (original)
+++ 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLiteHttpTransport.java
 Fri Nov 28 13:36:58 2008
@@ -221,10 +221,16 @@
                        tokens.nextToken(); // Skip HTTP version
                        String statusCode = tokens.nextToken();
                        String statusMsg = tokens.nextToken("\n\r");
-                       if (!"200".equals(statusCode)) {
-                               throw new IOException("Unexpected Response from 
Server: "
-                                                                         + 
statusMsg);
+                       final int code;
+                       try {
+                           code = Integer.parseInt(statusCode);
+                       } catch (NumberFormatException e) {
+                throw new XmlRpcClientException("Server returned invalid 
status code: "
+                        + statusCode + " " + statusMsg, null);
                        }
+                       if (code < 200  ||  code > 299) {
+                       throw new XmlRpcHttpTransportException(code, statusMsg);
+                   }
                        int contentLength = -1;
                        for (;;) {
                                line = HttpUtil.readLine(input, buffer);

Modified: 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcSunHttpTransport.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcSunHttpTransport.java?rev=721564&r1=721563&r2=721564&view=diff
==============================================================================
--- 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcSunHttpTransport.java
 (original)
+++ 
webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcSunHttpTransport.java
 Fri Nov 28 13:36:58 2008
@@ -86,7 +86,15 @@
 
        protected InputStream getInputStream() throws XmlRpcException {
                try {
-                       return getURLConnection().getInputStream();
+                   URLConnection connection = getURLConnection();
+                   if ( connection instanceof HttpURLConnection ) {
+                       HttpURLConnection httpConnection = (HttpURLConnection) 
connection;
+                       int responseCode = httpConnection.getResponseCode();
+                       if (responseCode < 200  ||  responseCode > 299) {
+                           throw new 
XmlRpcHttpTransportException(responseCode, httpConnection.getResponseMessage());
+                       }
+                   }
+                       return connection.getInputStream();
                } catch (IOException e) {
                        throw new XmlRpcException("Failed to create input 
stream: " + e.getMessage(), e);
                }

Modified: webservices/xmlrpc/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/pom.xml?rev=721564&r1=721563&r2=721564&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/pom.xml (original)
+++ webservices/xmlrpc/trunk/pom.xml Fri Nov 28 13:36:58 2008
@@ -164,6 +164,10 @@
             <email>[EMAIL PROTECTED]</email>
         </contributor>
         <contributor>
+            <name>Brandon DuRette</name>
+            <email>[EMAIL PROTECTED]</email>
+        </contributor>
+        <contributor>
             <name>Landon Fuller</name>
             <email>[EMAIL PROTECTED]</email>
         </contributor>

Modified: webservices/xmlrpc/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/src/changes/changes.xml?rev=721564&r1=721563&r2=721564&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/src/changes/changes.xml (original)
+++ webservices/xmlrpc/trunk/src/changes/changes.xml Fri Nov 28 13:36:58 2008
@@ -32,6 +32,10 @@
           issue="XMLRPC-161">
         The ThreadPool could create more threads than configured.
       </action>
+      <action dev="jochen" type="fix" due-to="Brandon DuRette" 
due-to-email="[EMAIL PROTECTED]"
+          issue="XMLRPC-160">
+        Improved the handling of HTTP status codes that indicate an error.
+      </action>
     </release>
 
     <release version="3.1.1" date="2008-Aug-10">


Reply via email to