Allow HTTP delete with request entity

Issue: SPR-12361
This commit is contained in:
Rossen Stoyanchev
2014-10-27 16:48:03 -04:00
parent 03fc9e89a0
commit 584b831bb9
4 changed files with 93 additions and 7 deletions

View File

@@ -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";
}
}
}

View File

@@ -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 {

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}