Skip to content

Commit

Permalink
Proof that clients support gzip and deflate compression (OpenFeign#1713)
Browse files Browse the repository at this point in the history
* Proof that clients support gzip and deflate compression

* Remove unused private methods
  • Loading branch information
vitalijr2 committed Aug 7, 2022
1 parent 4cf4cab commit f07c484
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 77 deletions.
80 changes: 79 additions & 1 deletion core/src/test/java/feign/client/AbstractClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
package feign.client;

import static feign.Util.UTF_8;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.junit.Assert.assertEquals;
import feign.Client;
import feign.CollectionFormat;
Expand All @@ -28,13 +29,18 @@
import feign.Util;
import feign.assertj.MockWebServerAssertions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPOutputStream;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import okio.Buffer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
Expand Down Expand Up @@ -386,6 +392,60 @@ public void testAlternativeCollectionFormat() throws Exception {
.hasOneOfPath("/?foo=bar,baz", "/?foo=bar%2Cbaz");
}

@Test
public void canSupportGzip() throws Exception {
/* enqueue a zipped response */
final String responseData = "Compressed Data";
server.enqueue(new MockResponse()
.addHeader("Content-Encoding", "gzip")
.setBody(new Buffer().write(compress(responseData))));

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

String result = api.get();

/* verify that the response is unzipped */
assertThat(result).isNotNull()
.isEqualToIgnoringCase(responseData);
}

@Test
public void canSupportDeflate() throws Exception {
/* enqueue a zipped response */
final String responseData = "Compressed Data";
server.enqueue(new MockResponse()
.addHeader("Content-Encoding", "deflate")
.setBody(new Buffer().write(deflate(responseData))));

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

String result = api.get();

/* verify that the response is unzipped */
assertThat(result).isNotNull()
.isEqualToIgnoringCase(responseData);
}

@Test
public void canExceptCaseInsensitiveHeader() throws Exception {
/* enqueue a zipped response */
final String responseData = "Compressed Data";
server.enqueue(new MockResponse()
.addHeader("content-encoding", "gzip")
.setBody(new Buffer().write(compress(responseData))));

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

String result = api.get();

/* verify that the response is unzipped */
assertThat(result).isNotNull()
.isEqualToIgnoringCase(responseData);
}

@SuppressWarnings("UnusedReturnValue")
public interface TestInterface {

Expand Down Expand Up @@ -435,4 +495,22 @@ public interface TestInterface {
Response postWithContentType(String body, @Param("contentType") String contentType);
}

private byte[] compress(String data) throws Exception {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length())) {
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(bos);
gzipOutputStream.write(data.getBytes(StandardCharsets.UTF_8), 0, data.length());
gzipOutputStream.close();
return bos.toByteArray();
}
}

private byte[] deflate(String data) throws Exception {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length())) {
DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(bos);
deflaterOutputStream.write(data.getBytes(StandardCharsets.UTF_8), 0, data.length());
deflaterOutputStream.close();
return bos.toByteArray();
}
}

}
75 changes: 0 additions & 75 deletions core/src/test/java/feign/client/DefaultClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,79 +150,4 @@ public void canCreateWithExplicitCredentials() throws Exception {
assertThat(connection).isNotNull().isInstanceOf(HttpURLConnection.class);
}


@Test
public void canSupportGzip() throws Exception {
/* enqueue a zipped response */
final String responseData = "Compressed Data";
server.enqueue(new MockResponse()
.addHeader("Content-Encoding", "gzip")
.setBody(new Buffer().write(compress(responseData))));

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

String result = api.get();

/* verify that the response is unzipped */
assertThat(result).isNotNull()
.isEqualToIgnoringCase(responseData);

}

@Test
public void canExeptCaseInsensitiveHeader() throws Exception {
/* enqueue a zipped response */
final String responseData = "Compressed Data";
server.enqueue(new MockResponse()
.addHeader("content-encoding", "gzip")
.setBody(new Buffer().write(compress(responseData))));

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

String result = api.get();

/* verify that the response is unzipped */
assertThat(result).isNotNull()
.isEqualToIgnoringCase(responseData);

}

@Test
public void canSupportDeflate() throws Exception {
/* enqueue a zipped response */
final String responseData = "Compressed Data";
server.enqueue(new MockResponse()
.addHeader("Content-Encoding", "deflate")
.setBody(new Buffer().write(deflate(responseData))));

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

String result = api.get();

/* verify that the response is unzipped */
assertThat(result).isNotNull()
.isEqualToIgnoringCase(responseData);

}

private byte[] compress(String data) throws Exception {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length())) {
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(bos);
gzipOutputStream.write(data.getBytes(StandardCharsets.UTF_8), 0, data.length());
gzipOutputStream.close();
return bos.toByteArray();
}
}

private byte[] deflate(String data) throws Exception {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length())) {
DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(bos);
deflaterOutputStream.write(data.getBytes(StandardCharsets.UTF_8), 0, data.length());
deflaterOutputStream.close();
return bos.toByteArray();
}
}
}
2 changes: 1 addition & 1 deletion googlehttpclient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This module is a feign [Client](https://github.com/OpenFeign/feign/blob/master/core/src/main/java/feign/Client.java) to use the java [Google Http Client](https://github.com/googleapis/google-http-java-client).

To use this, add to your classpath (via maven, or otherwise). Then cofigure Feign to use the GoogleHttpClient:
To use this, add to your classpath (via maven, or otherwise). Then configure Feign to use the GoogleHttpClient:

```java
GitHub github = Feign.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import feign.Feign;
import feign.Feign.Builder;
import feign.client.AbstractClientTest;
import static org.junit.Assume.assumeFalse;

public class GoogleHttpClientTest extends AbstractClientTest {
@Override
Expand All @@ -34,4 +35,24 @@ public void testPatch() {}

@Override
public void parsesUnauthorizedResponseBody() {}

/*
* Google HTTP client with NetHttpTransport does not support gzip and deflate compression
* out-of-the-box. You can replace the transport with Apache HTTP Client.
*/
@Override
public void canSupportGzip() throws Exception {
assumeFalse("Google HTTP client client do not support gzip compression", false);
}

@Override
public void canSupportDeflate() throws Exception {
assumeFalse("Google HTTP client client do not support deflate compression", false);
}

@Override
public void canExceptCaseInsensitiveHeader() throws Exception {
assumeFalse("Google HTTP client client do not support gzip compression", false);
}

}
19 changes: 19 additions & 0 deletions jaxrs2/src/test/java/feign/jaxrs2/JAXRSClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static feign.Util.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeFalse;

/**
* Tests client-specific behavior, such as ensuring Content-Length is sent when specified.
Expand Down Expand Up @@ -143,6 +144,24 @@ public void testConsumesMultipleWithContentTypeHeaderAndBody() throws Exception
.hasMethod("POST");
}

/*
* JaxRS does not support gzip and deflate compression out-of-the-box.
*/
@Override
public void canSupportGzip() throws Exception {
assumeFalse("JaxRS client do not support gzip compression", false);
}

@Override
public void canSupportDeflate() throws Exception {
assumeFalse("JaxRS client do not support deflate compression", false);
}

@Override
public void canExceptCaseInsensitiveHeader() throws Exception {
assumeFalse("JaxRS client do not support gzip compression", false);
}

public interface JaxRSClientTestInterface {

@RequestLine("GET /")
Expand Down
21 changes: 21 additions & 0 deletions okhttp/src/test/java/feign/okhttp/OkHttpClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.assertj.core.data.MapEntry;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeFalse;

/** Tests client-specific behavior, such as ensuring Content-Length is sent when specified. */
public class OkHttpClientTest extends AbstractClientTest {
Expand Down Expand Up @@ -103,6 +104,26 @@ public void testFollowRedirect() throws Exception {

}

/*
* OkHTTP does not support gzip and deflate compression out-of-the-box. But you can add an
* interceptor that implies it, see
* https://stackoverflow.com/questions/51901333/okhttp-3-how-to-decompress-gzip-deflate-response-
* manually-using-java-android
*/
@Override
public void canSupportGzip() throws Exception {
assumeFalse("OkHTTP client do not support gzip compression", false);
}

@Override
public void canSupportDeflate() throws Exception {
assumeFalse("OkHTTP client do not support deflate compression", false);
}

@Override
public void canExceptCaseInsensitiveHeader() throws Exception {
assumeFalse("OkHTTP client do not support gzip compression", false);
}

public interface OkHttpClientTestInterface {

Expand Down

0 comments on commit f07c484

Please sign in to comment.