use of androidx.media3.datasource.HttpDataSource.HttpDataSourceException in project media by androidx.
the class DefaultHttpDataSource method makeConnection.
/**
* Establishes a connection, following redirects to do so where permitted.
*/
private HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException {
URL url = new URL(dataSpec.uri.toString());
@HttpMethod int httpMethod = dataSpec.httpMethod;
@Nullable byte[] httpBody = dataSpec.httpBody;
long position = dataSpec.position;
long length = dataSpec.length;
boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP);
if (!allowCrossProtocolRedirects && !keepPostFor302Redirects) {
// automatically. This is the behavior we want, so use it.
return makeConnection(url, httpMethod, httpBody, position, length, allowGzip, /* followRedirects= */
true, dataSpec.httpRequestHeaders);
}
// We need to handle redirects ourselves to allow cross-protocol redirects or to keep the POST
// request method for 302.
int redirectCount = 0;
while (redirectCount++ <= MAX_REDIRECTS) {
HttpURLConnection connection = makeConnection(url, httpMethod, httpBody, position, length, allowGzip, /* followRedirects= */
false, dataSpec.httpRequestHeaders);
int responseCode = connection.getResponseCode();
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, dataSpec);
} 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)) {
connection.disconnect();
boolean shouldKeepPost = keepPostFor302Redirects && responseCode == HttpURLConnection.HTTP_MOVED_TEMP;
if (!shouldKeepPost) {
// POST request follows the redirect and is transformed into a GET request.
httpMethod = DataSpec.HTTP_METHOD_GET;
httpBody = null;
}
url = handleRedirect(url, location, dataSpec);
} else {
return connection;
}
}
// If we get here we've been redirected more times than are permitted.
throw new HttpDataSourceException(new NoRouteToHostException("Too many redirects: " + redirectCount), dataSpec, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED, HttpDataSourceException.TYPE_OPEN);
}
use of androidx.media3.datasource.HttpDataSource.HttpDataSourceException in project media by androidx.
the class CronetDataSourceTest method allowDirectExecutor.
@Test
public void allowDirectExecutor() throws HttpDataSourceException {
testDataSpec = new DataSpec(Uri.parse(TEST_URL));
mockResponseStartSuccess();
dataSourceUnderTest.open(testDataSpec);
verify(mockUrlRequestBuilder).allowDirectExecutor();
}
use of androidx.media3.datasource.HttpDataSource.HttpDataSourceException in project media by androidx.
the class CronetDataSourceTest method connectTimeout.
@Test
public void connectTimeout() throws InterruptedException {
long startTimeMs = SystemClock.elapsedRealtime();
final ConditionVariable startCondition = buildUrlRequestStartedCondition();
final CountDownLatch timedOutLatch = new CountDownLatch(1);
new Thread() {
@Override
public void run() {
try {
dataSourceUnderTest.open(testDataSpec);
fail();
} catch (HttpDataSourceException e) {
// Expected.
assertThat(e).isInstanceOf(CronetDataSource.OpenException.class);
assertThat(e).hasCauseThat().isInstanceOf(SocketTimeoutException.class);
assertThat(((CronetDataSource.OpenException) e).cronetConnectionStatus).isEqualTo(TEST_CONNECTION_STATUS);
timedOutLatch.countDown();
}
}
}.start();
startCondition.block();
// We should still be trying to open.
assertNotCountedDown(timedOutLatch);
// We should still be trying to open as we approach the timeout.
setSystemClockInMsAndTriggerPendingMessages(/* nowMs= */
startTimeMs + TEST_CONNECT_TIMEOUT_MS - 1);
assertNotCountedDown(timedOutLatch);
// Now we timeout.
setSystemClockInMsAndTriggerPendingMessages(/* nowMs= */
startTimeMs + TEST_CONNECT_TIMEOUT_MS + 10);
timedOutLatch.await();
verify(mockTransferListener, never()).onTransferStart(dataSourceUnderTest, testDataSpec, /* isNetwork= */
true);
}
use of androidx.media3.datasource.HttpDataSource.HttpDataSourceException in project media by androidx.
the class CronetDataSourceTest method factorySetFallbackHttpDataSourceFactory_cronetNotAvailable_usesFallbackFactory.
// Tests deprecated fallback functionality.
@SuppressWarnings("deprecation")
@Test
public void factorySetFallbackHttpDataSourceFactory_cronetNotAvailable_usesFallbackFactory() throws HttpDataSourceException, InterruptedException {
MockWebServer mockWebServer = new MockWebServer();
mockWebServer.enqueue(new MockResponse());
CronetEngineWrapper cronetEngineWrapper = new CronetEngineWrapper((CronetEngine) null);
DefaultHttpDataSource.Factory fallbackFactory = new DefaultHttpDataSource.Factory().setUserAgent("customFallbackFactoryUserAgent");
HttpDataSource dataSourceUnderTest = new CronetDataSource.Factory(cronetEngineWrapper, executorService).setFallbackFactory(fallbackFactory).createDataSource();
dataSourceUnderTest.open(new DataSpec.Builder().setUri(mockWebServer.url("/test-path").toString()).build());
Headers headers = mockWebServer.takeRequest(10, SECONDS).getHeaders();
assertThat(headers.get("user-agent")).isEqualTo("customFallbackFactoryUserAgent");
}
use of androidx.media3.datasource.HttpDataSource.HttpDataSourceException in project media by androidx.
the class CronetDataSourceTest method requestOpenGzippedCompressedReturnsDataSpecLength.
@Test
public void requestOpenGzippedCompressedReturnsDataSpecLength() throws HttpDataSourceException {
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, 5000);
testResponseHeader.put("Content-Encoding", "gzip");
testResponseHeader.put("Content-Length", Long.toString(50L));
mockResponseStartSuccess();
assertThat(dataSourceUnderTest.open(testDataSpec)).isEqualTo(5000);
verify(mockTransferListener).onTransferStart(dataSourceUnderTest, testDataSpec, /* isNetwork= */
true);
}
Aggregations