From 1f498677465a6d933ecd44553bb7c618f0bc7d9f Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 16 Nov 2020 16:13:33 +0000 Subject: [PATCH] Fix CronetDataSource handling of 200 response for range request Issue: #8090 #minor-release PiperOrigin-RevId: 342638922 --- RELEASENOTES.md | 3 ++ .../ext/cronet/CronetDataSource.java | 4 ++- .../ext/cronet/CronetDataSourceTest.java | 30 ++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e37f2fe1f2..476b6b0e26 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -34,6 +34,9 @@ * Fix a bug that caused multiple ads in an ad pod to be skipped when one ad in the ad pod was skipped. * Fix passing an ads response to the `ImaAdsLoader` builder. +* Cronet extension: + * Fix handling of HTTP status code 200 when making unbounded length range + requests ([#8090](https://github.com/google/ExoPlayer/issues/8090)). * Text * Allow tx3g subtitles with `styl` boxes with start and/or end offsets that lie outside the length of the cue text. diff --git a/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java b/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java index 26a60d3332..461d18fd26 100644 --- a/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java +++ b/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java @@ -506,7 +506,9 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource { if (dataSpec.length != C.LENGTH_UNSET) { bytesRemaining = dataSpec.length; } else { - bytesRemaining = getContentLength(responseInfo); + long contentLength = getContentLength(responseInfo); + bytesRemaining = + contentLength != C.LENGTH_UNSET ? (contentLength - bytesToSkip) : C.LENGTH_UNSET; } } else { // If the response is compressed then the content length will be that of the compressed data diff --git a/extensions/cronet/src/test/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java b/extensions/cronet/src/test/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java index ac19c8548d..b0b80a8e12 100644 --- a/extensions/cronet/src/test/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java +++ b/extensions/cronet/src/test/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java @@ -534,7 +534,8 @@ public final class CronetDataSourceTest { testUrlResponseInfo = createUrlResponseInfo(206); // Server supports range requests. testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000); - dataSourceUnderTest.open(testDataSpec); + long length = dataSourceUnderTest.open(testDataSpec); + assertThat(length).isEqualTo(5000); byte[] returnedBuffer = new byte[16]; int bytesRead = dataSourceUnderTest.read(returnedBuffer, 0, 16); @@ -551,7 +552,26 @@ public final class CronetDataSourceTest { testUrlResponseInfo = createUrlResponseInfo(200); // Server does not support range requests. testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000); - dataSourceUnderTest.open(testDataSpec); + long length = dataSourceUnderTest.open(testDataSpec); + assertThat(length).isEqualTo(5000); + + byte[] returnedBuffer = new byte[16]; + int bytesRead = dataSourceUnderTest.read(returnedBuffer, 0, 16); + assertThat(bytesRead).isEqualTo(16); + assertThat(returnedBuffer).isEqualTo(buildTestDataArray(1000, 16)); + verify(mockTransferListener) + .onBytesTransferred(dataSourceUnderTest, testDataSpec, /* isNetwork= */ true, 16); + } + + @Test + public void unboundedRangeRequestWith200Response() throws HttpDataSourceException { + mockResponseStartSuccess(); + mockReadSuccess(0, (int) TEST_CONTENT_LENGTH); + testUrlResponseInfo = createUrlResponseInfo(200); // Server does not support range requests. + testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, C.LENGTH_UNSET); + + long length = dataSourceUnderTest.open(testDataSpec); + assertThat(length).isEqualTo(TEST_CONTENT_LENGTH - 1000); byte[] returnedBuffer = new byte[16]; int bytesRead = dataSourceUnderTest.read(returnedBuffer, 0, 16); @@ -777,7 +797,8 @@ public final class CronetDataSourceTest { testUrlResponseInfo = createUrlResponseInfo(206); // Server supports range requests. testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000); - dataSourceUnderTest.open(testDataSpec); + long length = dataSourceUnderTest.open(testDataSpec); + assertThat(length).isEqualTo(5000); ByteBuffer returnedBuffer = ByteBuffer.allocateDirect(16); int bytesRead = dataSourceUnderTest.read(returnedBuffer); @@ -796,7 +817,8 @@ public final class CronetDataSourceTest { testUrlResponseInfo = createUrlResponseInfo(200); // Server does not support range requests. testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000); - dataSourceUnderTest.open(testDataSpec); + long length = dataSourceUnderTest.open(testDataSpec); + assertThat(length).isEqualTo(5000); ByteBuffer returnedBuffer = ByteBuffer.allocateDirect(16); int bytesRead = dataSourceUnderTest.read(returnedBuffer);