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

Add option to return raw input stream for response #1323

Merged
merged 4 commits into from
Jun 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ public abstract class AbstractGoogleClientRequest<T> extends GenericData {
/** Whether to disable GZip compression of HTTP content. */
private boolean disableGZipContent;

/** Whether to return raw input stream in {@link HttpResponse#getContent()}. */
private boolean returnRawInputStream;

/** Response class to parse into. */
private Class<T> responseClass;

Expand Down Expand Up @@ -222,6 +225,11 @@ public final boolean getDisableGZipContent() {
return disableGZipContent;
}

/** Returns whether response should return raw input stream. */
public final boolean getReturnRawInputSteam() {
return returnRawInputStream;
}

/**
* Sets whether to disable GZip compression of HTTP content.
*
Expand All @@ -239,6 +247,25 @@ public AbstractGoogleClientRequest<T> setDisableGZipContent(boolean disableGZipC
return this;
}

/**
* Sets whether the response should return raw input stream or not.
*
* <p>
* By default it is {@code false}.
* </p>
*
* <p>
* When the response contains a known content-encoding header, the response stream is wrapped
* with an InputStream that decodes the content. This fails when we download large files in
* chunks (see <a href="https://github.com/googleapis/google-api-java-client/issues/1009">#1009
* </a>). Setting this to true will make the response return the raw input stream.
* </p>
*/
public AbstractGoogleClientRequest<T> setReturnRawInputStream(boolean returnRawInputStream) {
this.returnRawInputStream = returnRawInputStream;
return this;
}

/** Returns the HTTP method. */
public final String getRequestMethod() {
return requestMethod;
Expand Down Expand Up @@ -406,6 +433,7 @@ private HttpRequest buildHttpRequest(boolean usingHead) throws IOException {
if (!disableGZipContent) {
httpRequest.setEncoding(new GZipEncoding());
}
httpRequest.setResponseReturnRawInputStream(returnRawInputStream);
final HttpResponseInterceptor responseInterceptor = httpRequest.getResponseInterceptor();
httpRequest.setResponseInterceptor(new HttpResponseInterceptor() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.google.api.client.http.EmptyContent;
import com.google.api.client.http.HttpMethods;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.http.HttpTransport;
Expand All @@ -31,8 +32,12 @@
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
import com.google.api.client.util.StringUtils;
import com.google.common.io.BaseEncoding;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import junit.framework.TestCase;

/**
Expand Down Expand Up @@ -246,6 +251,53 @@ public void testSetsApiClientHeaderWithoutOsVersion() throws Exception {
assertFalse("Api version should not contain the os version", version.matches(".*my-os.*"));
}

public void testReturnRawInputStream_defaultFalse() throws Exception {
HttpTransport transport = new MockHttpTransport() {
@Override
public LowLevelHttpRequest buildRequest(final String method, final String url) {
return new MockLowLevelHttpRequest() {
@Override
public LowLevelHttpResponse execute() {
return new MockLowLevelHttpResponse().setContentEncoding("gzip").setContent(new ByteArrayInputStream(
BaseEncoding.base64()
.decode("H4sIAAAAAAAAAPNIzcnJV3DPz0/PSVVwzskvTVEILskvSkxPVQQA/LySchsAAAA=")));
}
};
}
};
MockGoogleClient client = new MockGoogleClient.Builder(transport, ROOT_URL, SERVICE_PATH,
JSON_OBJECT_PARSER, null).setApplicationName(
"Test Application").build();
MockGoogleClientRequest<String> request = new MockGoogleClientRequest<String>(
client, HttpMethods.GET, URI_TEMPLATE, null, String.class);
InputStream inputStream = request.executeAsInputStream();
assertTrue(inputStream instanceof GZIPInputStream);
}

public void testReturnRawInputStream_True() throws Exception {
HttpTransport transport = new MockHttpTransport() {
@Override
public LowLevelHttpRequest buildRequest(final String method, final String url) {
return new MockLowLevelHttpRequest() {
@Override
public LowLevelHttpResponse execute() {
return new MockLowLevelHttpResponse().setContentEncoding("gzip").setContent(new ByteArrayInputStream(
BaseEncoding.base64()
.decode("H4sIAAAAAAAAAPNIzcnJV3DPz0/PSVVwzskvTVEILskvSkxPVQQA/LySchsAAAA=")));
}
};
}
};
MockGoogleClient client = new MockGoogleClient.Builder(transport, ROOT_URL, SERVICE_PATH,
JSON_OBJECT_PARSER, null).setApplicationName(
"Test Application").build();
MockGoogleClientRequest<String> request = new MockGoogleClientRequest<String>(
client, HttpMethods.GET, URI_TEMPLATE, null, String.class);
request.setReturnRawInputStream(true);
InputStream inputStream = request.executeAsInputStream();
assertFalse(inputStream instanceof GZIPInputStream);
}

private class AssertHeaderTransport extends MockHttpTransport {
String expectedHeader;
String expectedHeaderValue;
Expand Down