diff --git a/google-http-client/src/main/java/com/google/api/client/http/HttpResponse.java b/google-http-client/src/main/java/com/google/api/client/http/HttpResponse.java index d972ab0d4..5273300f6 100644 --- a/google-http-client/src/main/java/com/google/api/client/http/HttpResponse.java +++ b/google-http-client/src/main/java/com/google/api/client/http/HttpResponse.java @@ -26,6 +26,7 @@ import java.io.OutputStream; import java.lang.reflect.Type; import java.nio.charset.Charset; +import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.GZIPInputStream; @@ -80,6 +81,12 @@ public final class HttpResponse { /** Whether {@link #getContent()} should return raw input stream. */ private final boolean returnRawInputStream; + /** Content encoding for GZip */ + private static final String CONTENT_ENCODING_GZIP = "gzip"; + + /** Content encoding for GZip (legacy) */ + private static final String CONTENT_ENCODING_XGZIP = "x-gzip"; + /** * Determines the limit to the content size that will be logged during {@link #getContent()}. * @@ -327,12 +334,12 @@ public InputStream getContent() throws IOException { boolean contentProcessed = false; try { // gzip encoding (wrap content with GZipInputStream) - String contentEncoding = this.contentEncoding; - if (!returnRawInputStream - && contentEncoding != null - && contentEncoding.contains("gzip")) { - lowLevelResponseContent = - new ConsumingInputStream(new GZIPInputStream(lowLevelResponseContent)); + if (!returnRawInputStream && this.contentEncoding != null) { + String oontentencoding = this.contentEncoding.trim().toLowerCase(Locale.ENGLISH); + if (CONTENT_ENCODING_GZIP.equals(oontentencoding) || CONTENT_ENCODING_XGZIP.equals(oontentencoding)) { + lowLevelResponseContent = + new ConsumingInputStream(new GZIPInputStream(lowLevelResponseContent)); + } } // logging (wrap content with LoggingInputStream) Logger logger = HttpTransport.LOGGER; diff --git a/google-http-client/src/test/java/com/google/api/client/http/HttpResponseTest.java b/google-http-client/src/test/java/com/google/api/client/http/HttpResponseTest.java index a611d774a..a3efdb305 100644 --- a/google-http-client/src/test/java/com/google/api/client/http/HttpResponseTest.java +++ b/google-http-client/src/test/java/com/google/api/client/http/HttpResponseTest.java @@ -29,6 +29,7 @@ import java.nio.charset.StandardCharsets; import java.text.NumberFormat; import java.util.Arrays; +import java.util.Locale; import java.util.logging.Level; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -461,17 +462,37 @@ public LowLevelHttpResponse execute() throws IOException { } public void testGetContent_gzipEncoding_finishReading() throws IOException { + do_testGetContent_gzipEncoding_finishReading("gzip"); + } + + public void testGetContent_gzipEncoding_finishReadingWithUppercaseContentEncoding() throws IOException { + do_testGetContent_gzipEncoding_finishReading("GZIP"); + } + + public void testGetContent_gzipEncoding_finishReadingWithDifferentDefaultLocaleAndUppercaseContentEncoding() throws IOException { + Locale originalDefaultLocale = Locale.getDefault(); + try { + Locale.setDefault(Locale.forLanguageTag("tr-TR")); + do_testGetContent_gzipEncoding_finishReading("GZIP"); + } finally { + Locale.setDefault(originalDefaultLocale); + } + } + + private void do_testGetContent_gzipEncoding_finishReading(String contentEncoding) throws IOException { byte[] dataToCompress = "abcd".getBytes(StandardCharsets.UTF_8); byte[] mockBytes; - try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream(dataToCompress.length)) { - GZIPOutputStream zipStream = new GZIPOutputStream((byteStream)); + try ( + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(dataToCompress.length); + GZIPOutputStream zipStream = new GZIPOutputStream((byteStream)) + ) { zipStream.write(dataToCompress); zipStream.close(); mockBytes = byteStream.toByteArray(); } final MockLowLevelHttpResponse mockResponse = new MockLowLevelHttpResponse(); mockResponse.setContent(mockBytes); - mockResponse.setContentEncoding("gzip"); + mockResponse.setContentEncoding(contentEncoding); mockResponse.setContentType("text/plain"); HttpTransport transport = @@ -490,9 +511,35 @@ public LowLevelHttpResponse execute() throws IOException { HttpRequest request = transport.createRequestFactory().buildHeadRequest(HttpTesting.SIMPLE_GENERIC_URL); HttpResponse response = request.execute(); - TestableByteArrayInputStream output = (TestableByteArrayInputStream) mockResponse.getContent(); - assertFalse(output.isClosed()); + try (TestableByteArrayInputStream output = (TestableByteArrayInputStream) mockResponse.getContent()) { + assertFalse(output.isClosed()); + assertEquals("abcd", response.parseAsString()); + assertTrue(output.isClosed()); + } + } + + public void testGetContent_otherEncodingWithgzipInItsName_GzipIsNotUsed() throws IOException { + final MockLowLevelHttpResponse mockResponse = new MockLowLevelHttpResponse(); + mockResponse.setContent("abcd"); + mockResponse.setContentEncoding("otherEncodingWithgzipInItsName"); + mockResponse.setContentType("text/plain"); + + HttpTransport transport = + new MockHttpTransport() { + @Override + public LowLevelHttpRequest buildRequest(String method, final String url) + throws IOException { + return new MockLowLevelHttpRequest() { + @Override + public LowLevelHttpResponse execute() throws IOException { + return mockResponse; + } + }; + } + }; + HttpRequest request = transport.createRequestFactory().buildHeadRequest(HttpTesting.SIMPLE_GENERIC_URL); + // If gzip was used on this response, an exception would be thrown + HttpResponse response = request.execute(); assertEquals("abcd", response.parseAsString()); - assertTrue(output.isClosed()); } }