Commit b8ec05ae by tonihei Committed by Toni

Handle gzip in DefaultHttpDataSource.

Setting the requested encoding in all cases ensures we receive the relevant
response headers indicating whether gzip was used. Doing that allows to
detect the content length in cases where gzip was requested, but the server
replied with uncompressed content.

PiperOrigin-RevId: 250660890
parent 00b26a51
...@@ -466,7 +466,7 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource { ...@@ -466,7 +466,7 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0; bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0;
// Calculate the content length. // Calculate the content length.
if (!getIsCompressed(responseInfo)) { if (!isCompressed(responseInfo)) {
if (dataSpec.length != C.LENGTH_UNSET) { if (dataSpec.length != C.LENGTH_UNSET) {
bytesRemaining = dataSpec.length; bytesRemaining = dataSpec.length;
} else { } else {
...@@ -626,7 +626,7 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource { ...@@ -626,7 +626,7 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
} }
requestBuilder.addHeader("Range", rangeValue.toString()); requestBuilder.addHeader("Range", rangeValue.toString());
} }
// TODO: Uncomment when https://bugs.chromium.org/p/chromium/issues/detail?id=767025 is fixed // TODO: Uncomment when https://bugs.chromium.org/p/chromium/issues/detail?id=711810 is fixed
// (adjusting the code as necessary). // (adjusting the code as necessary).
// Force identity encoding unless gzip is allowed. // Force identity encoding unless gzip is allowed.
// if (!dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP)) { // if (!dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP)) {
...@@ -655,7 +655,7 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource { ...@@ -655,7 +655,7 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
currentConnectTimeoutMs = clock.elapsedRealtime() + connectTimeoutMs; currentConnectTimeoutMs = clock.elapsedRealtime() + connectTimeoutMs;
} }
private static boolean getIsCompressed(UrlResponseInfo info) { private static boolean isCompressed(UrlResponseInfo info) {
for (Map.Entry<String, String> entry : info.getAllHeadersAsList()) { for (Map.Entry<String, String> entry : info.getAllHeadersAsList()) {
if (entry.getKey().equalsIgnoreCase("Content-Encoding")) { if (entry.getKey().equalsIgnoreCase("Content-Encoding")) {
return !entry.getValue().equalsIgnoreCase("identity"); return !entry.getValue().equalsIgnoreCase("identity");
......
...@@ -41,6 +41,7 @@ import java.util.Map; ...@@ -41,6 +41,7 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
/** /**
* An {@link HttpDataSource} that uses Android's {@link HttpURLConnection}. * An {@link HttpDataSource} that uses Android's {@link HttpURLConnection}.
...@@ -305,7 +306,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou ...@@ -305,7 +306,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0; bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0;
// Determine the length of the data to be read, after skipping. // Determine the length of the data to be read, after skipping.
if (!dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP)) { boolean isCompressed = isCompressed(connection);
if (!isCompressed) {
if (dataSpec.length != C.LENGTH_UNSET) { if (dataSpec.length != C.LENGTH_UNSET) {
bytesToRead = dataSpec.length; bytesToRead = dataSpec.length;
} else { } else {
...@@ -315,14 +317,16 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou ...@@ -315,14 +317,16 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
} }
} else { } else {
// Gzip is enabled. If the server opts to use gzip then the content length in the response // Gzip is enabled. If the server opts to use gzip then the content length in the response
// will be that of the compressed data, which isn't what we want. Furthermore, there isn't a // will be that of the compressed data, which isn't what we want. Always use the dataSpec
// reliable way to determine whether the gzip was used or not. Always use the dataSpec length // length in this case.
// in this case.
bytesToRead = dataSpec.length; bytesToRead = dataSpec.length;
} }
try { try {
inputStream = connection.getInputStream(); inputStream = connection.getInputStream();
if (isCompressed) {
inputStream = new GZIPInputStream(inputStream);
}
} catch (IOException e) { } catch (IOException e) {
closeConnectionQuietly(); closeConnectionQuietly();
throw new HttpDataSourceException(e, dataSpec, HttpDataSourceException.TYPE_OPEN); throw new HttpDataSourceException(e, dataSpec, HttpDataSourceException.TYPE_OPEN);
...@@ -516,9 +520,7 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou ...@@ -516,9 +520,7 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
connection.setRequestProperty("Range", rangeRequest); connection.setRequestProperty("Range", rangeRequest);
} }
connection.setRequestProperty("User-Agent", userAgent); connection.setRequestProperty("User-Agent", userAgent);
if (!allowGzip) { connection.setRequestProperty("Accept-Encoding", allowGzip ? "gzip" : "identity");
connection.setRequestProperty("Accept-Encoding", "identity");
}
if (allowIcyMetadata) { if (allowIcyMetadata) {
connection.setRequestProperty( connection.setRequestProperty(
IcyHeaders.REQUEST_HEADER_ENABLE_METADATA_NAME, IcyHeaders.REQUEST_HEADER_ENABLE_METADATA_NAME,
...@@ -747,4 +749,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou ...@@ -747,4 +749,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
} }
} }
private static boolean isCompressed(HttpURLConnection connection) {
String contentEncoding = connection.getHeaderField("Content-Encoding");
return "gzip".equalsIgnoreCase(contentEncoding);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment