diff --git a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java index 63df369e..35ac2530 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java +++ b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java @@ -19,11 +19,6 @@ package org.springframework.ws.transport.http; import java.io.IOException; import java.net.URI; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; -import org.springframework.ws.transport.WebServiceConnection; - import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpConnectionManager; @@ -33,6 +28,11 @@ import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.PostMethod; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; +import org.springframework.ws.transport.WebServiceConnection; + /** * WebServiceMessageSender implementation that uses Jakarta * Commons HttpClient to execute POST requests. @@ -50,6 +50,10 @@ import org.apache.commons.httpclient.methods.PostMethod; public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSender implements InitializingBean, DisposableBean { + private static final int DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS = (60 * 1000); + + private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000); + private HttpClient httpClient; private Credentials credentials; @@ -62,6 +66,8 @@ public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSende */ public CommonsHttpMessageSender() { httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); + setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS); + setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS); } /** @@ -99,6 +105,32 @@ public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSende this.credentials = credentials; } + /** + * Sets the timeout until a connection is etablished. A value of 0 means never timeout. + * + * @param timeout the timeout value in milliseconds + * @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int) + */ + public void setConnectionTimeout(int timeout) { + if (timeout < 0) { + throw new IllegalArgumentException("timeout must be a non-negative value"); + } + getHttpClient().getHttpConnectionManager().getParams().setConnectionTimeout(timeout); + } + + /** + * Set the socket read timeout for the underlying HttpClient. A value of 0 means never timeout. + * + * @param timeout the timeout value in milliseconds + * @see org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int) + */ + public void setReadTimeout(int timeout) { + if (timeout < 0) { + throw new IllegalArgumentException("timeout must be a non-negative value"); + } + getHttpClient().getHttpConnectionManager().getParams().setSoTimeout(timeout); + } + /** * Returns the authentication scope to be used. Only used when the credentials property has been set. *

diff --git a/core/src/test/java/org/springframework/ws/transport/http/CommonsHttpMessageSenderIntegrationTest.java b/core/src/test/java/org/springframework/ws/transport/http/CommonsHttpMessageSenderIntegrationTest.java index 497180b4..a2c0bc85 100644 --- a/core/src/test/java/org/springframework/ws/transport/http/CommonsHttpMessageSenderIntegrationTest.java +++ b/core/src/test/java/org/springframework/ws/transport/http/CommonsHttpMessageSenderIntegrationTest.java @@ -16,10 +16,32 @@ package org.springframework.ws.transport.http; +import java.net.URI; + +import org.apache.commons.httpclient.ConnectTimeoutException; + +import org.springframework.ws.MockWebServiceMessage; +import org.springframework.ws.WebServiceMessage; +import org.springframework.ws.transport.WebServiceConnection; + public class CommonsHttpMessageSenderIntegrationTest extends AbstractHttpWebServiceMessageSenderIntegrationTestCase { protected AbstractHttpWebServiceMessageSender createMessageSender() { return new CommonsHttpMessageSender(); } + public void testConnectionTimeout() throws Exception { + CommonsHttpMessageSender messageSender = new CommonsHttpMessageSender(); + messageSender.setConnectionTimeout(1); + WebServiceConnection connection = messageSender.createConnection(new URI("http://example.com/")); + WebServiceMessage message = new MockWebServiceMessage(); + try { + connection.send(message); + fail("ConnectTimeoutException expected"); + } + catch (ConnectTimeoutException ex) { + // expected + } + } + }