mirror of
https://github.com/samsonjs/media.git
synced 2026-03-26 09:35:47 +00:00
Updating DefaultHttpDataSource to allow for http methods other than GET and POST,
as specified by DataSpec.httpMethod. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=207769779
This commit is contained in:
parent
ca473c86c7
commit
d3686cf8a2
8 changed files with 209 additions and 57 deletions
|
|
@ -92,6 +92,8 @@
|
|||
([#273](https://github.com/google/ExoPlayer/issues/273)).
|
||||
* Fix where transitions to clipped media sources happened too early
|
||||
([#4583](https://github.com/google/ExoPlayer/issues/4583)).
|
||||
* Add `DataSpec.httpMethod` and update `HttpDataSource` implemenations to support
|
||||
http HEAD method. Previously, only GET and POST were supported.
|
||||
|
||||
### 2.8.3 ###
|
||||
|
||||
|
|
|
|||
|
|
@ -473,8 +473,8 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
isContentTypeHeaderSet = isContentTypeHeaderSet || CONTENT_TYPE.equals(key);
|
||||
requestBuilder.addHeader(key, headerEntry.getValue());
|
||||
}
|
||||
if (dataSpec.postBody != null && dataSpec.postBody.length != 0 && !isContentTypeHeaderSet) {
|
||||
throw new IOException("POST request with non-empty body must set Content-Type");
|
||||
if (dataSpec.httpBody != null && !isContentTypeHeaderSet) {
|
||||
throw new IOException("HTTP request with non-empty body must set Content-Type");
|
||||
}
|
||||
// Set the Range header.
|
||||
if (dataSpec.position != 0 || dataSpec.length != C.LENGTH_UNSET) {
|
||||
|
|
@ -494,12 +494,10 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
// requestBuilder.addHeader("Accept-Encoding", "identity");
|
||||
// }
|
||||
// Set the method and (if non-empty) the body.
|
||||
if (dataSpec.postBody != null) {
|
||||
requestBuilder.setHttpMethod("POST");
|
||||
if (dataSpec.postBody.length != 0) {
|
||||
requestBuilder.setUploadDataProvider(new ByteArrayUploadDataProvider(dataSpec.postBody),
|
||||
executor);
|
||||
}
|
||||
requestBuilder.setHttpMethod(dataSpec.getHttpMethodString());
|
||||
if (dataSpec.httpBody != null) {
|
||||
requestBuilder.setUploadDataProvider(
|
||||
new ByteArrayUploadDataProvider(dataSpec.httpBody), executor);
|
||||
}
|
||||
return requestBuilder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public final class CronetDataSourceTest {
|
|||
|
||||
private DataSpec testDataSpec;
|
||||
private DataSpec testPostDataSpec;
|
||||
private DataSpec testHeadDataSpec;
|
||||
private Map<String, String> testResponseHeader;
|
||||
private UrlResponseInfo testUrlResponseInfo;
|
||||
|
||||
|
|
@ -120,6 +121,9 @@ public final class CronetDataSourceTest {
|
|||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, C.LENGTH_UNSET, null);
|
||||
testPostDataSpec =
|
||||
new DataSpec(Uri.parse(TEST_URL), TEST_POST_BODY, 0, 0, C.LENGTH_UNSET, null, 0);
|
||||
testHeadDataSpec =
|
||||
new DataSpec(
|
||||
Uri.parse(TEST_URL), DataSpec.HTTP_METHOD_HEAD, null, 0, 0, C.LENGTH_UNSET, null, 0);
|
||||
testResponseHeader = new HashMap<>();
|
||||
testResponseHeader.put("Content-Type", TEST_CONTENT_TYPE);
|
||||
// This value can be anything since the DataSpec is unset.
|
||||
|
|
@ -332,6 +336,15 @@ public final class CronetDataSourceTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadRequestOpen() throws HttpDataSourceException {
|
||||
mockResponseStartSuccess();
|
||||
dataSourceUnderTest.open(testHeadDataSpec);
|
||||
verify(mockTransferListener)
|
||||
.onTransferStart(dataSourceUnderTest, testHeadDataSpec, /* isNetwork= */ true);
|
||||
dataSourceUnderTest.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestReadTwice() throws HttpDataSourceException {
|
||||
mockResponseStartSuccess();
|
||||
|
|
|
|||
|
|
@ -296,9 +296,14 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
|
|||
if (!allowGzip) {
|
||||
builder.addHeader("Accept-Encoding", "identity");
|
||||
}
|
||||
if (dataSpec.postBody != null) {
|
||||
builder.post(RequestBody.create(null, dataSpec.postBody));
|
||||
RequestBody requestBody = null;
|
||||
if (dataSpec.httpBody != null) {
|
||||
requestBody = RequestBody.create(null, dataSpec.httpBody);
|
||||
} else if (dataSpec.httpMethod == DataSpec.HTTP_METHOD_POST) {
|
||||
// OkHttp requires a non-null body for POST requests.
|
||||
requestBody = RequestBody.create(null, new byte[0]);
|
||||
}
|
||||
builder.method(dataSpec.getHttpMethodString(), requestBody);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,14 +54,33 @@ public final class DataSpec {
|
|||
*/
|
||||
public static final int FLAG_ALLOW_CACHING_UNKNOWN_LENGTH = 1 << 1; // 2
|
||||
|
||||
/** The set of HTTP methods that are supported by ExoPlayer {@link HttpDataSource}s. */
|
||||
@IntDef({HTTP_METHOD_GET, HTTP_METHOD_POST, HTTP_METHOD_HEAD})
|
||||
public @interface HttpMethod {}
|
||||
|
||||
public static final int HTTP_METHOD_GET = 1;
|
||||
public static final int HTTP_METHOD_POST = 2;
|
||||
public static final int HTTP_METHOD_HEAD = 3;
|
||||
|
||||
/**
|
||||
* The source from which data should be read.
|
||||
*/
|
||||
public final Uri uri;
|
||||
|
||||
/**
|
||||
* Body for a POST request, null otherwise.
|
||||
* The HTTP method, which will be used by {@link HttpDataSource} when requesting this DataSpec.
|
||||
* This value will be ignored by non-http {@link DataSource}s.
|
||||
*/
|
||||
public final @Nullable byte[] postBody;
|
||||
public final @HttpMethod int httpMethod;
|
||||
|
||||
/**
|
||||
* The HTTP body, null otherwise. If the body is non-null, then httpBody.length will be non-zero.
|
||||
*/
|
||||
public final @Nullable byte[] httpBody;
|
||||
|
||||
/** @deprecated Use {@link #httpBody} instead. */
|
||||
@Deprecated public final @Nullable byte[] postBody;
|
||||
|
||||
/**
|
||||
* The absolute position of the data in the full stream.
|
||||
*/
|
||||
|
|
@ -155,11 +174,13 @@ public final class DataSpec {
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a {@link DataSpec} where {@link #position} may differ from {@link
|
||||
* #absoluteStreamPosition}.
|
||||
* Construct a {@link DataSpec} by inferring the {@link #httpMethod} based on the {@code postBody}
|
||||
* parameter. If postBody is non-null, then httpMethod is set to {@link #HTTP_METHOD_POST}. If
|
||||
* postBody is null, then httpMethod is set to {@link #HTTP_METHOD_GET}.
|
||||
*
|
||||
* @param uri {@link #uri}.
|
||||
* @param postBody {@link #postBody}.
|
||||
* @param postBody {@link #httpBody} The body of the HTTP request, which is also used to infer the
|
||||
* {@link #httpMethod}.
|
||||
* @param absoluteStreamPosition {@link #absoluteStreamPosition}.
|
||||
* @param position {@link #position}.
|
||||
* @param length {@link #length}.
|
||||
|
|
@ -174,11 +195,46 @@ public final class DataSpec {
|
|||
long length,
|
||||
@Nullable String key,
|
||||
@Flags int flags) {
|
||||
this(
|
||||
uri,
|
||||
/* httpMethod= */ postBody != null ? HTTP_METHOD_POST : HTTP_METHOD_GET,
|
||||
/* httpBody= */ postBody,
|
||||
absoluteStreamPosition,
|
||||
position,
|
||||
length,
|
||||
key,
|
||||
flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@link DataSpec} where {@link #position} may differ from {@link
|
||||
* #absoluteStreamPosition}.
|
||||
*
|
||||
* @param uri {@link #uri}.
|
||||
* @param httpMethod {@link #httpMethod}.
|
||||
* @param httpBody {@link #httpBody}.
|
||||
* @param absoluteStreamPosition {@link #absoluteStreamPosition}.
|
||||
* @param position {@link #position}.
|
||||
* @param length {@link #length}.
|
||||
* @param key {@link #key}.
|
||||
* @param flags {@link #flags}.
|
||||
*/
|
||||
public DataSpec(
|
||||
Uri uri,
|
||||
@HttpMethod int httpMethod,
|
||||
@Nullable byte[] httpBody,
|
||||
long absoluteStreamPosition,
|
||||
long position,
|
||||
long length,
|
||||
@Nullable String key,
|
||||
@Flags int flags) {
|
||||
Assertions.checkArgument(absoluteStreamPosition >= 0);
|
||||
Assertions.checkArgument(position >= 0);
|
||||
Assertions.checkArgument(length > 0 || length == C.LENGTH_UNSET);
|
||||
this.uri = uri;
|
||||
this.postBody = postBody;
|
||||
this.httpMethod = httpMethod;
|
||||
this.httpBody = (httpBody != null && httpBody.length != 0) ? httpBody : null;
|
||||
this.postBody = this.httpBody;
|
||||
this.absoluteStreamPosition = absoluteStreamPosition;
|
||||
this.position = position;
|
||||
this.length = length;
|
||||
|
|
@ -197,8 +253,48 @@ public final class DataSpec {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DataSpec[" + uri + ", " + Arrays.toString(postBody) + ", " + absoluteStreamPosition
|
||||
+ ", " + position + ", " + length + ", " + key + ", " + flags + "]";
|
||||
return "DataSpec["
|
||||
+ getHttpMethodString()
|
||||
+ " "
|
||||
+ uri
|
||||
+ ", "
|
||||
+ Arrays.toString(httpBody)
|
||||
+ ", "
|
||||
+ absoluteStreamPosition
|
||||
+ ", "
|
||||
+ position
|
||||
+ ", "
|
||||
+ length
|
||||
+ ", "
|
||||
+ key
|
||||
+ ", "
|
||||
+ flags
|
||||
+ "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an uppercase HTTP method name (e.g., "GET", "POST", "HEAD") corresponding to the {@link
|
||||
* #httpMethod}.
|
||||
*/
|
||||
public final String getHttpMethodString() {
|
||||
return getStringForHttpMethod(httpMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an uppercase HTTP method name (e.g., "GET", "POST", "HEAD") corresponding to the {@code
|
||||
* httpMethod}.
|
||||
*/
|
||||
public static String getStringForHttpMethod(@HttpMethod int httpMethod) {
|
||||
switch (httpMethod) {
|
||||
case HTTP_METHOD_GET:
|
||||
return "GET";
|
||||
case HTTP_METHOD_POST:
|
||||
return "POST";
|
||||
case HTTP_METHOD_HEAD:
|
||||
return "HEAD";
|
||||
default:
|
||||
throw new AssertionError(httpMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -223,8 +319,15 @@ public final class DataSpec {
|
|||
if (offset == 0 && this.length == length) {
|
||||
return this;
|
||||
} else {
|
||||
return new DataSpec(uri, postBody, absoluteStreamPosition + offset, position + offset, length,
|
||||
key, flags);
|
||||
return new DataSpec(
|
||||
uri,
|
||||
httpMethod,
|
||||
httpBody,
|
||||
absoluteStreamPosition + offset,
|
||||
position + offset,
|
||||
length,
|
||||
key,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -235,6 +338,7 @@ public final class DataSpec {
|
|||
* @return The copied {@link DataSpec} with the specified Uri.
|
||||
*/
|
||||
public DataSpec withUri(Uri uri) {
|
||||
return new DataSpec(uri, postBody, absoluteStreamPosition, position, length, key, flags);
|
||||
return new DataSpec(
|
||||
uri, httpMethod, httpBody, absoluteStreamPosition, position, length, key, flags);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import android.support.annotation.Nullable;
|
|||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec.HttpMethod;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Predicate;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -61,6 +62,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
|||
|
||||
private static final String TAG = "DefaultHttpDataSource";
|
||||
private static final int MAX_REDIRECTS = 20; // Same limit as okhttp.
|
||||
private static final int HTTP_STATUS_TEMPORARY_REDIRECT = 307;
|
||||
private static final int HTTP_STATUS_PERMANENT_REDIRECT = 308;
|
||||
private static final long MAX_BYTES_TO_DRAIN = 2048;
|
||||
private static final Pattern CONTENT_RANGE_HEADER =
|
||||
Pattern.compile("^bytes (\\d+)-(\\d+)/(\\d+)$");
|
||||
|
|
@ -417,7 +420,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
|||
*/
|
||||
private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException {
|
||||
URL url = new URL(dataSpec.uri.toString());
|
||||
byte[] postBody = dataSpec.postBody;
|
||||
@HttpMethod int httpMethod = dataSpec.httpMethod;
|
||||
byte[] httpBody = dataSpec.httpBody;
|
||||
long position = dataSpec.position;
|
||||
long length = dataSpec.length;
|
||||
boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP);
|
||||
|
|
@ -425,28 +429,37 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
|||
if (!allowCrossProtocolRedirects) {
|
||||
// HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection
|
||||
// automatically. This is the behavior we want, so use it.
|
||||
return makeConnection(url, postBody, position, length, allowGzip, true /* followRedirects */);
|
||||
return makeConnection(
|
||||
url, httpMethod, httpBody, position, length, allowGzip, true /* followRedirects */);
|
||||
}
|
||||
|
||||
// We need to handle redirects ourselves to allow cross-protocol redirects.
|
||||
int redirectCount = 0;
|
||||
while (redirectCount++ <= MAX_REDIRECTS) {
|
||||
HttpURLConnection connection = makeConnection(
|
||||
url, postBody, position, length, allowGzip, false /* followRedirects */);
|
||||
HttpURLConnection connection =
|
||||
makeConnection(
|
||||
url, httpMethod, httpBody, position, length, allowGzip, false /* followRedirects */);
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|
||||
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|
||||
|| (postBody == null
|
||||
&& (responseCode == 307 /* HTTP_TEMP_REDIRECT */
|
||||
|| responseCode == 308 /* HTTP_PERM_REDIRECT */))) {
|
||||
// For 300, 301, 302, and 303 POST requests follow the redirect and are transformed into
|
||||
// GET requests. For 307 and 308 POST requests are not redirected.
|
||||
postBody = null;
|
||||
String location = connection.getHeaderField("Location");
|
||||
String location = connection.getHeaderField("Location");
|
||||
if ((httpMethod == DataSpec.HTTP_METHOD_GET || httpMethod == DataSpec.HTTP_METHOD_HEAD)
|
||||
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|
||||
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|
||||
|| responseCode == HTTP_STATUS_TEMPORARY_REDIRECT
|
||||
|| responseCode == HTTP_STATUS_PERMANENT_REDIRECT)) {
|
||||
connection.disconnect();
|
||||
url = handleRedirect(url, location);
|
||||
} else if (httpMethod == DataSpec.HTTP_METHOD_POST
|
||||
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|
||||
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER)) {
|
||||
// POST request follows the redirect and is transformed into a GET request.
|
||||
connection.disconnect();
|
||||
httpMethod = DataSpec.HTTP_METHOD_GET;
|
||||
httpBody = null;
|
||||
url = handleRedirect(url, location);
|
||||
} else {
|
||||
return connection;
|
||||
}
|
||||
|
|
@ -460,14 +473,22 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
|||
* Configures a connection and opens it.
|
||||
*
|
||||
* @param url The url to connect to.
|
||||
* @param postBody The body data for a POST request.
|
||||
* @param httpMethod The http method.
|
||||
* @param httpBody The body data.
|
||||
* @param position The byte offset of the requested data.
|
||||
* @param length The length of the requested data, or {@link C#LENGTH_UNSET}.
|
||||
* @param allowGzip Whether to allow the use of gzip.
|
||||
* @param followRedirects Whether to follow redirects.
|
||||
*/
|
||||
private HttpURLConnection makeConnection(URL url, byte[] postBody, long position,
|
||||
long length, boolean allowGzip, boolean followRedirects) throws IOException {
|
||||
private HttpURLConnection makeConnection(
|
||||
URL url,
|
||||
@HttpMethod int httpMethod,
|
||||
byte[] httpBody,
|
||||
long position,
|
||||
long length,
|
||||
boolean allowGzip,
|
||||
boolean followRedirects)
|
||||
throws IOException {
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setConnectTimeout(connectTimeoutMillis);
|
||||
connection.setReadTimeout(readTimeoutMillis);
|
||||
|
|
@ -491,18 +512,14 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
|||
connection.setRequestProperty("Accept-Encoding", "identity");
|
||||
}
|
||||
connection.setInstanceFollowRedirects(followRedirects);
|
||||
connection.setDoOutput(postBody != null);
|
||||
if (postBody != null) {
|
||||
connection.setRequestMethod("POST");
|
||||
if (postBody.length == 0) {
|
||||
connection.connect();
|
||||
} else {
|
||||
connection.setFixedLengthStreamingMode(postBody.length);
|
||||
connection.connect();
|
||||
OutputStream os = connection.getOutputStream();
|
||||
os.write(postBody);
|
||||
os.close();
|
||||
}
|
||||
connection.setDoOutput(httpBody != null);
|
||||
connection.setRequestMethod(DataSpec.getStringForHttpMethod(httpMethod));
|
||||
if (httpBody != null) {
|
||||
connection.setFixedLengthStreamingMode(httpBody.length);
|
||||
connection.connect();
|
||||
OutputStream os = connection.getOutputStream();
|
||||
os.write(httpBody);
|
||||
os.close();
|
||||
} else {
|
||||
connection.connect();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.google.android.exoplayer2.upstream.DataSink;
|
|||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSourceException;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec.HttpMethod;
|
||||
import com.google.android.exoplayer2.upstream.FileDataSource;
|
||||
import com.google.android.exoplayer2.upstream.TeeDataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
|
@ -133,6 +134,7 @@ public final class CacheDataSource implements DataSource {
|
|||
private boolean currentDataSpecLengthUnset;
|
||||
private @Nullable Uri uri;
|
||||
private @Nullable Uri actualUri;
|
||||
private @HttpMethod int httpMethod;
|
||||
private int flags;
|
||||
private @Nullable String key;
|
||||
private long readPosition;
|
||||
|
|
@ -269,6 +271,7 @@ public final class CacheDataSource implements DataSource {
|
|||
key = cacheKeyFactory.buildCacheKey(dataSpec);
|
||||
uri = dataSpec.uri;
|
||||
actualUri = getRedirectedUriOrDefault(cache, key, /* defaultUri= */ uri);
|
||||
httpMethod = dataSpec.httpMethod;
|
||||
flags = dataSpec.flags;
|
||||
readPosition = dataSpec.position;
|
||||
|
||||
|
|
@ -353,6 +356,7 @@ public final class CacheDataSource implements DataSource {
|
|||
public void close() throws IOException {
|
||||
uri = null;
|
||||
actualUri = null;
|
||||
httpMethod = DataSpec.HTTP_METHOD_GET;
|
||||
notifyBytesRead();
|
||||
try {
|
||||
closeCurrentSource();
|
||||
|
|
@ -397,7 +401,9 @@ public final class CacheDataSource implements DataSource {
|
|||
// The data is locked in the cache, or we're ignoring the cache. Bypass the cache and read
|
||||
// from upstream.
|
||||
nextDataSource = upstreamDataSource;
|
||||
nextDataSpec = new DataSpec(uri, readPosition, bytesRemaining, key, flags);
|
||||
nextDataSpec =
|
||||
new DataSpec(
|
||||
uri, httpMethod, null, readPosition, readPosition, bytesRemaining, key, flags);
|
||||
} else if (nextSpan.isCached) {
|
||||
// Data is cached, read from cache.
|
||||
Uri fileUri = Uri.fromFile(nextSpan.file);
|
||||
|
|
@ -419,7 +425,8 @@ public final class CacheDataSource implements DataSource {
|
|||
length = Math.min(length, bytesRemaining);
|
||||
}
|
||||
}
|
||||
nextDataSpec = new DataSpec(uri, readPosition, length, key, flags);
|
||||
nextDataSpec =
|
||||
new DataSpec(uri, httpMethod, null, readPosition, readPosition, length, key, flags);
|
||||
if (cacheWriteDataSource != null) {
|
||||
nextDataSource = cacheWriteDataSource;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -264,10 +264,16 @@ public final class CacheUtil {
|
|||
throwExceptionIfInterruptedOrCancelled(isCanceled);
|
||||
// Create a new dataSpec setting length to C.LENGTH_UNSET to prevent getting an error in
|
||||
// case the given length exceeds the end of input.
|
||||
dataSpec = new DataSpec(dataSpec.uri, dataSpec.postBody, absoluteStreamPosition,
|
||||
dataSpec.position + absoluteStreamPosition - dataSpec.absoluteStreamPosition,
|
||||
C.LENGTH_UNSET, dataSpec.key,
|
||||
dataSpec.flags | DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH);
|
||||
dataSpec =
|
||||
new DataSpec(
|
||||
dataSpec.uri,
|
||||
dataSpec.httpMethod,
|
||||
dataSpec.httpBody,
|
||||
absoluteStreamPosition,
|
||||
dataSpec.position + absoluteStreamPosition - dataSpec.absoluteStreamPosition,
|
||||
C.LENGTH_UNSET,
|
||||
dataSpec.key,
|
||||
dataSpec.flags | DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH);
|
||||
long resolvedLength = dataSource.open(dataSpec);
|
||||
if (counters.contentLength == C.LENGTH_UNSET && resolvedLength != C.LENGTH_UNSET) {
|
||||
counters.contentLength = dataSpec.absoluteStreamPosition + resolvedLength;
|
||||
|
|
|
|||
Loading…
Reference in a new issue