package com.danikula.videocache; import android.text.TextUtils; import androidx.annotation.NonNull; import com.alipay.sdk.cons.b; import com.alipay.sdk.util.i; import com.danikula.videocache.headers.EmptyHeadersInjector; import com.danikula.videocache.headers.HeaderInjector; import com.danikula.videocache.sourcestorage.SourceInfoStorage; import com.danikula.videocache.sourcestorage.SourceInfoStorageFactory; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.net.HttpURLConnection; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; public class HttpUrlSource implements Source { private static final int MAX_REDIRECTS = 5; private HttpURLConnection connection; private final HeaderInjector headerInjector; private InputStream inputStream; private SourceInfo sourceInfo; private final SourceInfoStorage sourceInfoStorage; private final TrustManager[] trustAllCerts; private final HostnameVerifier v; public HttpUrlSource(String str, HostnameVerifier hostnameVerifier, TrustManager[] trustManagerArr) { this(str, SourceInfoStorageFactory.newEmptySourceInfoStorage(), hostnameVerifier, trustManagerArr); } public HttpUrlSource(String str, SourceInfoStorage sourceInfoStorage2, HostnameVerifier hostnameVerifier, TrustManager[] trustManagerArr) { this(str, sourceInfoStorage2, new EmptyHeadersInjector(), hostnameVerifier, trustManagerArr); } public HttpUrlSource(String str, SourceInfoStorage sourceInfoStorage2, HeaderInjector headerInjector2, HostnameVerifier hostnameVerifier, TrustManager[] trustManagerArr) { this.sourceInfoStorage = (SourceInfoStorage) Preconditions.checkNotNull(sourceInfoStorage2); this.headerInjector = (HeaderInjector) Preconditions.checkNotNull(headerInjector2); this.v = hostnameVerifier; this.trustAllCerts = trustManagerArr; SourceInfo sourceInfo2 = sourceInfoStorage2.get(str); this.sourceInfo = sourceInfo2 == null ? new SourceInfo(str, -2147483648L, ProxyCacheUtils.getSupposablyMime(str)) : sourceInfo2; } public HttpUrlSource(HttpUrlSource httpUrlSource) { this.sourceInfo = httpUrlSource.sourceInfo; this.sourceInfoStorage = httpUrlSource.sourceInfoStorage; this.headerInjector = httpUrlSource.headerInjector; this.trustAllCerts = httpUrlSource.trustAllCerts; this.v = httpUrlSource.v; } @Override // com.danikula.videocache.Source public synchronized long length() throws ProxyCacheException { if (this.sourceInfo.length == -2147483648L) { fetchContentInfo(); } return this.sourceInfo.length; } @Override // com.danikula.videocache.Source public void open(long j) throws ProxyCacheException { try { HttpURLConnection openConnection = openConnection(j, -1); this.connection = openConnection; String contentType = openConnection.getContentType(); this.inputStream = new BufferedInputStream(this.connection.getInputStream(), 8192); HttpURLConnection httpURLConnection = this.connection; SourceInfo sourceInfo2 = new SourceInfo(this.sourceInfo.url, readSourceAvailableBytes(httpURLConnection, j, httpURLConnection.getResponseCode()), contentType); this.sourceInfo = sourceInfo2; this.sourceInfoStorage.put(sourceInfo2.url, sourceInfo2); } catch (IOException e) { throw new ProxyCacheException("Error opening connection for " + this.sourceInfo.url + " with offset " + j, e); } } private long readSourceAvailableBytes(HttpURLConnection httpURLConnection, long j, int i) throws IOException { long contentLength = getContentLength(httpURLConnection); if (i == 200) { return contentLength; } if (i == 206) { return contentLength + j; } return this.sourceInfo.length; } private long getContentLength(HttpURLConnection httpURLConnection) { String headerField = httpURLConnection.getHeaderField("Content-Length"); if (headerField == null) { return -1; } return Long.parseLong(headerField); } @Override // com.danikula.videocache.Source public void close() throws ProxyCacheException { HttpURLConnection httpURLConnection = this.connection; if (httpURLConnection != null) { try { httpURLConnection.disconnect(); } catch (IllegalArgumentException | NullPointerException e) { throw new RuntimeException("Wait... but why? WTF!? Really shouldn't happen any more after fixing https://github.com/danikula/AndroidVideoCache/issues/43. If you read it on your device log, please, notify me danikula@gmail.com or create issue here https://github.com/danikula/AndroidVideoCache/issues.", e); } catch (ArrayIndexOutOfBoundsException e2) { HttpProxyCacheDebuger.printfError("Error closing connection correctly. Should happen only on Android L. If anybody know how to fix it, please visit https://github.com/danikula/AndroidVideoCache/issues/88. Until good solution is not know, just ignore this issue :(", e2); } } } @Override // com.danikula.videocache.Source public int read(byte[] bArr) throws ProxyCacheException { InputStream inputStream2 = this.inputStream; if (inputStream2 != null) { try { return inputStream2.read(bArr, 0, bArr.length); } catch (InterruptedIOException e) { throw new InterruptedProxyCacheException("Reading source " + this.sourceInfo.url + " is interrupted", e); } catch (IOException e2) { throw new ProxyCacheException("Error reading data from " + this.sourceInfo.url, e2); } } else { throw new ProxyCacheException("Error reading data from " + this.sourceInfo.url + ": connection is absent!"); } } /* JADX WARNING: Removed duplicated region for block: B:20:0x005c */ /* JADX WARNING: Removed duplicated region for block: B:24:? A[RETURN, SYNTHETIC] */ private void fetchContentInfo() throws ProxyCacheException { Throwable th; HttpURLConnection httpURLConnection; IOException e; InputStream inputStream2 = null; try { httpURLConnection = openConnection(0, 10000); try { long contentLength = getContentLength(httpURLConnection); String contentType = httpURLConnection.getContentType(); inputStream2 = httpURLConnection.getInputStream(); SourceInfo sourceInfo2 = new SourceInfo(this.sourceInfo.url, contentLength, contentType); this.sourceInfo = sourceInfo2; this.sourceInfoStorage.put(sourceInfo2.url, sourceInfo2); ProxyCacheUtils.close(inputStream2); if (httpURLConnection == null) { return; } } catch (IOException e2) { e = e2; try { HttpProxyCacheDebuger.printfError("Error fetching info from " + this.sourceInfo.url, e); ProxyCacheUtils.close(inputStream2); if (httpURLConnection == null) { return; } httpURLConnection.disconnect(); } catch (Throwable th2) { th = th2; ProxyCacheUtils.close(inputStream2); if (httpURLConnection != null) { httpURLConnection.disconnect(); } throw th; } } } catch (IOException e3) { e = e3; httpURLConnection = null; HttpProxyCacheDebuger.printfError("Error fetching info from " + this.sourceInfo.url, e); ProxyCacheUtils.close(inputStream2); if (httpURLConnection == null) { } httpURLConnection.disconnect(); } catch (Throwable th3) { th = th3; httpURLConnection = null; ProxyCacheUtils.close(inputStream2); if (httpURLConnection != null) { } throw th; } httpURLConnection.disconnect(); } private HttpURLConnection openConnection(long j, int i) throws IOException, ProxyCacheException { HttpURLConnection httpURLConnection; boolean z; String str = this.sourceInfo.url; int i2 = 0; do { if (!str.startsWith(b.a) || this.v == null || this.trustAllCerts == null) { httpURLConnection = (HttpURLConnection) new URL(str).openConnection(); } else { httpURLConnection = (HttpURLConnection) new URL(str).openConnection(); ((HttpsURLConnection) httpURLConnection).setHostnameVerifier(this.v); try { SSLContext instance = SSLContext.getInstance("SSL"); instance.init(null, this.trustAllCerts, new SecureRandom()); ((HttpsURLConnection) httpURLConnection).setSSLSocketFactory(instance.getSocketFactory()); ((HttpsURLConnection) httpURLConnection).setHostnameVerifier(this.v); } catch (KeyManagementException | NoSuchAlgorithmException e) { e.printStackTrace(); } } injectCustomHeaders(httpURLConnection, str); if (j > 0) { httpURLConnection.setRequestProperty("Range", "bytes=" + j + "-"); } if (i > 0) { httpURLConnection.setConnectTimeout(i); httpURLConnection.setReadTimeout(i); } int responseCode = httpURLConnection.getResponseCode(); z = responseCode == 301 || responseCode == 302 || responseCode == 303; if (z) { str = httpURLConnection.getHeaderField("Location"); i2++; httpURLConnection.disconnect(); } if (i2 > 5) { throw new ProxyCacheException("Too many redirects: " + i2); } } while (z); return httpURLConnection; } private void injectCustomHeaders(HttpURLConnection httpURLConnection, String str) { Map<String, String> addHeaders = this.headerInjector.addHeaders(str); if (addHeaders != null) { HttpProxyCacheDebuger.printfError("****** injectCustomHeaders ****** :" + addHeaders.size()); for (Map.Entry<String, String> entry : addHeaders.entrySet()) { httpURLConnection.setRequestProperty(entry.getKey(), entry.getValue()); } } } public synchronized String getMime() throws ProxyCacheException { if (TextUtils.isEmpty(this.sourceInfo.mime)) { fetchContentInfo(); } return this.sourceInfo.mime; } public String getUrl() { return this.sourceInfo.url; } @NonNull public String toString() { return "HttpUrlSource{sourceInfo='" + this.sourceInfo + i.d; } }