Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable to disable streaming mode for Default client #1182

Merged
merged 5 commits into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 40 additions & 5 deletions core/src/main/java/feign/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import static feign.Util.ENCODING_GZIP;
import static feign.Util.checkArgument;
import static feign.Util.checkNotNull;
import static feign.Util.isBlank;
import static feign.Util.isNotBlank;
import static java.lang.String.format;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand All @@ -35,9 +37,11 @@
import java.util.Map;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPOutputStream;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

import feign.Request.Options;

/**
Expand All @@ -61,11 +65,40 @@ class Default implements Client {
private final HostnameVerifier hostnameVerifier;

/**
* Null parameters imply platform defaults.
* Disable the request body internal buffering for {@code HttpURLConnection}.
*
* @see HttpURLConnection#setFixedLengthStreamingMode(int)
* @see HttpURLConnection#setFixedLengthStreamingMode(long)
* @see HttpURLConnection#setChunkedStreamingMode(int)
*/
private final boolean disableRequestBuffering;

/**
* Create a new client, which disable request buffering by default.
*
* @param sslContextFactory SSLSocketFactory for secure https URL connections.
* @param hostnameVerifier the host name verifier.
*/
public Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier) {
this.sslContextFactory = sslContextFactory;
this.hostnameVerifier = hostnameVerifier;
this.disableRequestBuffering = true;
}

/**
* Create a new client.
*
* @param sslContextFactory SSLSocketFactory for secure https URL connections.
* @param hostnameVerifier the host name verifier.
* @param disableRequestBuffering Disable the request body internal buffering for
* {@code HttpURLConnection}.
*/
public Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier,
boolean disableRequestBuffering) {
super();
this.sslContextFactory = sslContextFactory;
this.hostnameVerifier = hostnameVerifier;
this.disableRequestBuffering = disableRequestBuffering;
}

@Override
Expand Down Expand Up @@ -161,10 +194,12 @@ HttpURLConnection convertAndSend(Request request, Options options) throws IOExce
}

if (request.body() != null) {
if (contentLength != null) {
connection.setFixedLengthStreamingMode(contentLength);
} else {
connection.setChunkedStreamingMode(8196);
if (disableRequestBuffering) {
if (contentLength != null) {
connection.setFixedLengthStreamingMode(contentLength);
} else {
connection.setChunkedStreamingMode(8196);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe make this configurable?!

}
}
connection.setDoOutput(true);
OutputStream out = connection.getOutputStream();
Expand Down
20 changes: 20 additions & 0 deletions core/src/test/java/feign/client/AbstractClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ public void parsesErrorResponseBody() {
}
}

@Test
public void parsesUnauthorizedResponseBody() {
String expectedResponseBody = "ARGHH";

server.enqueue(new MockResponse().setResponseCode(401).setBody("ARGHH"));

TestInterface api = newBuilder()
.target(TestInterface.class, "http://localhost:" + server.getPort());

try {
api.postForString("HELLO");
} catch (FeignException e) {
assertThat(e.contentUTF8()).isEqualTo(expectedResponseBody);
velo marked this conversation as resolved.
Show resolved Hide resolved
}
}

@Test
public void safeRebuffering() {
server.enqueue(new MockResponse().setBody("foo"));
Expand Down Expand Up @@ -378,6 +394,10 @@ public interface TestInterface {
@Headers("Accept: text/plain")
Response post(@Param("to") String to, String body);

@RequestLine("POST /?foo=bar&foo=baz&qux=")
@Headers({"Foo: Bar", "Foo: Baz", "Qux: ", "Content-Type: text/plain"})
String postForString(String body);

@RequestLine("GET /")
@Headers("Accept: text/plain")
String get();
Expand Down
4 changes: 2 additions & 2 deletions core/src/test/java/feign/client/DefaultClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.core.Is.isA;
import static org.junit.Assert.assertEquals;
import feign.Client.Proxied;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
Expand All @@ -29,6 +28,7 @@
import javax.net.ssl.SSLSession;
import org.junit.Test;
import feign.Client;
import feign.Client.Proxied;
import feign.Feign;
import feign.Feign.Builder;
import feign.RetryableException;
Expand All @@ -50,7 +50,7 @@ public boolean verify(String s, SSLSession sslSession) {

@Override
public Builder newBuilder() {
return Feign.builder().client(new Client.Default(TrustingSSLSocketFactory.get(), null));
return Feign.builder().client(new Client.Default(TrustingSSLSocketFactory.get(), null, false));
}

@Test
Expand Down