mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Follow 307/308 POST redirects for license requests
I was considering putting this directly in DefaultHttpDataSource, however: - We'd need to modify at least OkHttpDataSource as well. I'm not sure whether Cronet follows this type of redirect automatically or not. - HttpDataSource instances don't know how they're going to be used, so it's probably correct that they behave like the underlying network stack. Issue: #4108 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=192745408
This commit is contained in:
parent
22b8ab5c09
commit
0ee3963789
2 changed files with 47 additions and 9 deletions
|
|
@ -51,13 +51,15 @@
|
||||||
* Add release method to Cache interface.
|
* Add release method to Cache interface.
|
||||||
* Prevent multiple instances of SimpleCache in the same folder.
|
* Prevent multiple instances of SimpleCache in the same folder.
|
||||||
Previous instance must be released.
|
Previous instance must be released.
|
||||||
* Store redirected URI
|
* Cache redirect URLs
|
||||||
([#2360](https://github.com/google/ExoPlayer/issues/2360)).
|
([#2360](https://github.com/google/ExoPlayer/issues/2360)).
|
||||||
* DRM:
|
* DRM:
|
||||||
* Allow multiple listeners for `DefaultDrmSessionManager`.
|
* Allow multiple listeners for `DefaultDrmSessionManager`.
|
||||||
* Pass `DrmSessionManager` to `ExoPlayerFactory` instead of `RendererFactory`.
|
* Pass `DrmSessionManager` to `ExoPlayerFactory` instead of `RendererFactory`.
|
||||||
* Change minimum API requirement for CBC and pattern encryption from 24 to 25
|
* Change minimum API requirement for CBC and pattern encryption from 24 to 25
|
||||||
([#4022][https://github.com/google/ExoPlayer/issues/4022]).
|
([#4022][https://github.com/google/ExoPlayer/issues/4022]).
|
||||||
|
* Fix handling of 307/308 redirects when making license requests
|
||||||
|
([#4108](https://github.com/google/ExoPlayer/issues/4108)).
|
||||||
* Removed default renderer time offset of 60000000 from internal player. The
|
* Removed default renderer time offset of 60000000 from internal player. The
|
||||||
actual renderer timestamp offset can be obtained by listening to
|
actual renderer timestamp offset can be obtained by listening to
|
||||||
`BaseRenderer.onStreamChanged`.
|
`BaseRenderer.onStreamChanged`.
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,12 @@ import com.google.android.exoplayer2.drm.ExoMediaDrm.ProvisionRequest;
|
||||||
import com.google.android.exoplayer2.upstream.DataSourceInputStream;
|
import com.google.android.exoplayer2.upstream.DataSourceInputStream;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||||
|
import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -37,6 +39,8 @@ import java.util.UUID;
|
||||||
@TargetApi(18)
|
@TargetApi(18)
|
||||||
public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
||||||
|
|
||||||
|
private static final int MAX_MANUAL_REDIRECTS = 5;
|
||||||
|
|
||||||
private final HttpDataSource.Factory dataSourceFactory;
|
private final HttpDataSource.Factory dataSourceFactory;
|
||||||
private final String defaultLicenseUrl;
|
private final String defaultLicenseUrl;
|
||||||
private final boolean forceDefaultLicenseUrl;
|
private final boolean forceDefaultLicenseUrl;
|
||||||
|
|
@ -138,14 +142,46 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
||||||
dataSource.setRequestProperty(requestProperty.getKey(), requestProperty.getValue());
|
dataSource.setRequestProperty(requestProperty.getKey(), requestProperty.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataSpec dataSpec = new DataSpec(Uri.parse(url), data, 0, 0, C.LENGTH_UNSET, null,
|
|
||||||
DataSpec.FLAG_ALLOW_GZIP);
|
int manualRedirectCount = 0;
|
||||||
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
|
while (true) {
|
||||||
try {
|
DataSpec dataSpec =
|
||||||
return Util.toByteArray(inputStream);
|
new DataSpec(
|
||||||
} finally {
|
Uri.parse(url),
|
||||||
Util.closeQuietly(inputStream);
|
data,
|
||||||
|
/* absoluteStreamPosition= */ 0,
|
||||||
|
/* position= */ 0,
|
||||||
|
/* length= */ C.LENGTH_UNSET,
|
||||||
|
/* key= */ null,
|
||||||
|
DataSpec.FLAG_ALLOW_GZIP);
|
||||||
|
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
|
||||||
|
try {
|
||||||
|
return Util.toByteArray(inputStream);
|
||||||
|
} catch (InvalidResponseCodeException e) {
|
||||||
|
// For POST requests, the underlying network stack will not normally follow 307 or 308
|
||||||
|
// redirects automatically. Do so manually here.
|
||||||
|
boolean manuallyRedirect =
|
||||||
|
(e.responseCode == 307 || e.responseCode == 308)
|
||||||
|
&& manualRedirectCount++ < MAX_MANUAL_REDIRECTS;
|
||||||
|
url = manuallyRedirect ? getRedirectUrl(e) : null;
|
||||||
|
if (url == null) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Util.closeQuietly(inputStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getRedirectUrl(InvalidResponseCodeException exception) {
|
||||||
|
Map<String, List<String>> headerFields = exception.headerFields;
|
||||||
|
if (headerFields != null) {
|
||||||
|
List<String> locationHeaders = headerFields.get("Location");
|
||||||
|
if (locationHeaders != null && !locationHeaders.isEmpty()) {
|
||||||
|
return locationHeaders.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue