Search in sources :

Example 1 with HttpDataSourceException

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);
}
Also used : HttpURLConnection(java.net.HttpURLConnection) NoRouteToHostException(java.net.NoRouteToHostException) URL(java.net.URL) HttpMethod(androidx.media3.datasource.DataSpec.HttpMethod) Nullable(androidx.annotation.Nullable)

Example 2 with HttpDataSourceException

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();
}
Also used : DataSpec(androidx.media3.datasource.DataSpec) Test(org.junit.Test)

Example 3 with HttpDataSourceException

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);
}
Also used : ConditionVariable(android.os.ConditionVariable) HttpDataSourceException(androidx.media3.datasource.HttpDataSource.HttpDataSourceException) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 4 with HttpDataSourceException

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");
}
Also used : MockResponse(okhttp3.mockwebserver.MockResponse) Headers(okhttp3.Headers) MockWebServer(okhttp3.mockwebserver.MockWebServer) DataSpec(androidx.media3.datasource.DataSpec) DefaultHttpDataSource(androidx.media3.datasource.DefaultHttpDataSource) HttpDataSource(androidx.media3.datasource.HttpDataSource) DefaultHttpDataSource(androidx.media3.datasource.DefaultHttpDataSource) Test(org.junit.Test)

Example 5 with HttpDataSourceException

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);
}
Also used : DataSpec(androidx.media3.datasource.DataSpec) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)22 DataSpec (androidx.media3.datasource.DataSpec)15 HttpDataSourceException (androidx.media3.datasource.HttpDataSource.HttpDataSourceException)7 ConditionVariable (android.os.ConditionVariable)6 InterruptedIOException (java.io.InterruptedIOException)6 CountDownLatch (java.util.concurrent.CountDownLatch)6 ByteBuffer (java.nio.ByteBuffer)5 DefaultHttpDataSource (androidx.media3.datasource.DefaultHttpDataSource)4 HttpDataSource (androidx.media3.datasource.HttpDataSource)4 MockResponse (okhttp3.mockwebserver.MockResponse)4 MockWebServer (okhttp3.mockwebserver.MockWebServer)4 Nullable (androidx.annotation.Nullable)3 IOException (java.io.IOException)3 Headers (okhttp3.Headers)3 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)3 DataSourceException (androidx.media3.datasource.DataSourceException)2 SocketTimeoutException (java.net.SocketTimeoutException)2 UnknownHostException (java.net.UnknownHostException)2 HashMap (java.util.HashMap)2 List (java.util.List)2