Fix HttpUrlConnection DELETE without body

The following commit allowed HTTP DELETE with body:
584b831bb9

However it broke buffered requests even without a body since JDK 1.6
and 1.7 do not support calls to getOutputStream with HTTP DELETE.

This commit set the doOutput flag back to false if the actual buffered
body is 0 length.

Issue: SPR-12361
master
Rossen Stoyanchev 10 years ago
parent 18033486ae
commit 53eec48ffd
  1. 4
      spring-web/src/main/java/org/springframework/http/client/SimpleBufferingAsyncClientHttpRequest.java
  2. 6
      spring-web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java
  3. 11
      spring-web/src/test/java/org/springframework/http/client/BufferedSimpleHttpRequestFactoryTests.java

@ -78,6 +78,10 @@ final class SimpleBufferingAsyncClientHttpRequest extends AbstractBufferingAsync
@Override @Override
public ClientHttpResponse call() throws Exception { public ClientHttpResponse call() throws Exception {
SimpleBufferingClientHttpRequest.addHeaders(connection, headers); SimpleBufferingClientHttpRequest.addHeaders(connection, headers);
// JDK < 1.8 doesn't support getOutputStream with HTTP DELETE
if (HttpMethod.DELETE.equals(getMethod()) && bufferedOutput.length == 0) {
connection.setDoOutput(false);
}
if (connection.getDoOutput() && outputStreaming) { if (connection.getDoOutput() && outputStreaming) {
connection.setFixedLengthStreamingMode(bufferedOutput.length); connection.setFixedLengthStreamingMode(bufferedOutput.length);
} }

@ -26,6 +26,7 @@ import java.util.Map;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -69,6 +70,11 @@ final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttp
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException { protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
addHeaders(this.connection, headers); addHeaders(this.connection, headers);
// JDK < 1.8 doesn't support getOutputStream with HTTP DELETE
if (HttpMethod.DELETE.equals(getMethod()) && bufferedOutput.length == 0) {
this.connection.setDoOutput(false);
}
if (this.connection.getDoOutput() && this.outputStreaming) { if (this.connection.getDoOutput() && this.outputStreaming) {
this.connection.setFixedLengthStreamingMode(bufferedOutput.length); this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
} }

@ -18,9 +18,12 @@ package org.springframework.http.client;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.ProtocolException; import java.net.ProtocolException;
import java.net.URI;
import java.net.URL; import java.net.URL;
import org.junit.Test; import org.junit.Test;
@ -56,6 +59,14 @@ public class BufferedSimpleHttpRequestFactoryTests extends AbstractHttpRequestFa
testRequestBodyAllowed(uri, "DELETE", true); testRequestBodyAllowed(uri, "DELETE", true);
} }
@Test
public void deleteWithoutBodyDoesNotRaiseException() throws Exception {
HttpURLConnection connection = new TestHttpURLConnection(new URL("http://example.com"));
((SimpleClientHttpRequestFactory) this.factory).prepareConnection(connection, "DELETE");
SimpleBufferingClientHttpRequest request = new SimpleBufferingClientHttpRequest(connection, false);
request.execute();
}
private void testRequestBodyAllowed(URL uri, String httpMethod, boolean allowed) throws IOException { private void testRequestBodyAllowed(URL uri, String httpMethod, boolean allowed) throws IOException {
HttpURLConnection connection = new TestHttpURLConnection(uri); HttpURLConnection connection = new TestHttpURLConnection(uri);
((SimpleClientHttpRequestFactory) this.factory).prepareConnection(connection, httpMethod); ((SimpleClientHttpRequestFactory) this.factory).prepareConnection(connection, httpMethod);

Loading…
Cancel
Save