diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java index 9810afe0e9..59101d4881 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java @@ -22,7 +22,7 @@ import java.net.URI; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.Configurable; -import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpOptions; @@ -273,4 +273,25 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest this.httpClient.close(); } + + /** + * An alternative to {@link org.apache.http.client.methods.HttpDelete} that + * extends {@link org.apache.http.client.methods.HttpEntityEnclosingRequestBase} + * rather than {@link org.apache.http.client.methods.HttpRequestBase} and + * hence allows HTTP delete with a request body. For use with the RestTemplate + * exchange methods which allow the combination of HTTP DELETE with entity. + * @since 4.1.2 + */ + private static class HttpDelete extends HttpEntityEnclosingRequestBase { + + public HttpDelete(URI uri) { + super(); + setURI(uri); + } + + @Override + public String getMethod() { + return "DELETE"; + } + } } diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index 6f14c1b220..e2dcb02563 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -199,7 +199,8 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory, else { connection.setInstanceFollowRedirects(false); } - if ("PUT".equals(httpMethod) || "POST".equals(httpMethod) || "PATCH".equals(httpMethod)) { + if ("PUT".equals(httpMethod) || "POST".equals(httpMethod) || + "PATCH".equals(httpMethod) || "DELETE".equals(httpMethod)) { connection.setDoOutput(true); } else { diff --git a/spring-web/src/test/java/org/springframework/http/client/BufferedSimpleHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/BufferedSimpleHttpRequestFactoryTests.java index c05fb85aeb..0bb1c30b03 100644 --- a/spring-web/src/test/java/org/springframework/http/client/BufferedSimpleHttpRequestFactoryTests.java +++ b/spring-web/src/test/java/org/springframework/http/client/BufferedSimpleHttpRequestFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,14 @@ package org.springframework.http.client; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.net.HttpURLConnection; import java.net.ProtocolException; +import java.net.URL; import org.junit.Test; - import org.springframework.http.HttpMethod; public class BufferedSimpleHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase { @@ -40,4 +44,42 @@ public class BufferedSimpleHttpRequestFactoryTests extends AbstractHttpRequestFa } } + @Test + public void prepareConnectionWithRequestBody() throws Exception { + URL uri = new URL("http://example.com"); + testRequestBodyAllowed(uri, "GET", false); + testRequestBodyAllowed(uri, "HEAD", false); + testRequestBodyAllowed(uri, "OPTIONS", false); + testRequestBodyAllowed(uri, "TRACE", false); + testRequestBodyAllowed(uri, "PUT", true); + testRequestBodyAllowed(uri, "POST", true); + testRequestBodyAllowed(uri, "DELETE", true); + } + + private void testRequestBodyAllowed(URL uri, String httpMethod, boolean allowed) throws IOException { + HttpURLConnection connection = new TestHttpURLConnection(uri); + ((SimpleClientHttpRequestFactory) this.factory).prepareConnection(connection, httpMethod); + assertEquals(allowed, connection.getDoOutput()); + } + + + private static class TestHttpURLConnection extends HttpURLConnection { + + public TestHttpURLConnection(URL uri) { + super(uri); + } + + @Override + public void connect() throws IOException { + } + + @Override + public void disconnect() { + } + + @Override + public boolean usingProxy() { + return false; + } + } } diff --git a/spring-web/src/test/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactoryTests.java index fe0a9934b8..2e5fd6a9a8 100644 --- a/spring-web/src/test/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactoryTests.java +++ b/spring-web/src/test/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactoryTests.java @@ -16,20 +16,23 @@ package org.springframework.http.client; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.net.URI; +import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.params.CoreConnectionPNames; import org.junit.Test; - import org.springframework.http.HttpMethod; -import static org.junit.Assert.*; - public class HttpComponentsClientHttpRequestFactoryTests extends AbstractHttpRequestFactoryTestCase { @Override @@ -73,6 +76,25 @@ public class HttpComponentsClientHttpRequestFactoryTests extends AbstractHttpReq RequestConfig requestConfig = (RequestConfig) config; assertEquals("Wrong custom connection timeout", 1234, requestConfig.getConnectTimeout()); assertEquals("Wrong custom socket timeout", 4567, requestConfig.getSocketTimeout()); + } + + @Test + public void createHttpUriRequest() throws Exception { + URI uri = new URI("http://example.com"); + testRequestBodyAllowed(uri, HttpMethod.GET, false); + testRequestBodyAllowed(uri, HttpMethod.HEAD, false); + testRequestBodyAllowed(uri, HttpMethod.OPTIONS, false); + testRequestBodyAllowed(uri, HttpMethod.TRACE, false); + testRequestBodyAllowed(uri, HttpMethod.PUT, true); + testRequestBodyAllowed(uri, HttpMethod.POST, true); + testRequestBodyAllowed(uri, HttpMethod.PATCH, true); + testRequestBodyAllowed(uri, HttpMethod.DELETE, true); } + + private void testRequestBodyAllowed(URI uri, HttpMethod method, boolean allowed) { + HttpUriRequest request = ((HttpComponentsClientHttpRequestFactory) this.factory).createHttpUriRequest(method, uri); + assertEquals(allowed, request instanceof HttpEntityEnclosingRequest); + } + }