package org.schabi.newpipe; import android.os.Build; import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.downloader.Request; import org.schabi.newpipe.extractor.downloader.Response; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.util.TLSSocketFactoryCompat; import java.io.IOException; import java.io.InputStream; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import okhttp3.CipherSuite; import okhttp3.ConnectionSpec; import okhttp3.OkHttpClient; import okhttp3.RequestBody; import okhttp3.ResponseBody; import static org.schabi.newpipe.MainActivity.DEBUG; public final class DownloaderImpl extends Downloader { public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0"; private static DownloaderImpl instance; private String mCookies; private OkHttpClient client; private DownloaderImpl(final OkHttpClient.Builder builder) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { enableModernTLS(builder); } this.client = builder .readTimeout(30, TimeUnit.SECONDS) // .cache(new Cache(new File(context.getExternalCacheDir(), "okhttp"), // 16 * 1024 * 1024)) .build(); } /** * It's recommended to call exactly once in the entire lifetime of the application. * * @param builder if null, default builder will be used * @return a new instance of {@link DownloaderImpl} */ public static DownloaderImpl init(@Nullable final OkHttpClient.Builder builder) { instance = new DownloaderImpl( builder != null ? builder : new OkHttpClient.Builder()); return instance; } public static DownloaderImpl getInstance() { return instance; } /** * Enable TLS 1.2 and 1.1 on Android Kitkat. This function is mostly taken * from the documentation of OkHttpClient.Builder.sslSocketFactory(_,_). *
* If there is an error, the function will safely fall back to doing nothing * and printing the error to the console. *
* * @param builder The HTTPClient Builder on which TLS is enabled on (will be modified in-place) */ private static void enableModernTLS(final OkHttpClient.Builder builder) { try { // get the default TrustManager TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init((KeyStore) null); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); } X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; // insert our own TLSSocketFactory SSLSocketFactory sslSocketFactory = TLSSocketFactoryCompat.getInstance(); builder.sslSocketFactory(sslSocketFactory, trustManager); // This will try to enable all modern CipherSuites(+2 more) // that are supported on the device. // Necessary because some servers (e.g. Framatube.org) // don't support the old cipher suites. // https://github.com/square/okhttp/issues/4053#issuecomment-402579554 List