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">