328 lines
13 KiB
Java
328 lines
13 KiB
Java
|
package okhttp3.repackaged.internal.io;
|
||
|
|
||
|
import com.airbnb.deeplinkdispatch.UrlTreeKt;
|
||
|
import com.google.common.net.HttpHeaders;
|
||
|
import java.io.IOException;
|
||
|
import java.lang.ref.Reference;
|
||
|
import java.net.ConnectException;
|
||
|
import java.net.Proxy;
|
||
|
import java.net.Socket;
|
||
|
import java.net.SocketTimeoutException;
|
||
|
import java.net.UnknownServiceException;
|
||
|
import java.security.cert.X509Certificate;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
import java.util.concurrent.TimeUnit;
|
||
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
||
|
import javax.net.ssl.SSLSocket;
|
||
|
import o.C15145giV;
|
||
|
import o.InterfaceC15142giR;
|
||
|
import o.giO;
|
||
|
import o.giZ;
|
||
|
import okhttp3.repackaged.Address;
|
||
|
import okhttp3.repackaged.CertificatePinner;
|
||
|
import okhttp3.repackaged.Connection;
|
||
|
import okhttp3.repackaged.ConnectionSpec;
|
||
|
import okhttp3.repackaged.Handshake;
|
||
|
import okhttp3.repackaged.HttpUrl;
|
||
|
import okhttp3.repackaged.Protocol;
|
||
|
import okhttp3.repackaged.Request;
|
||
|
import okhttp3.repackaged.Response;
|
||
|
import okhttp3.repackaged.Route;
|
||
|
import okhttp3.repackaged.internal.ConnectionSpecSelector;
|
||
|
import okhttp3.repackaged.internal.Platform;
|
||
|
import okhttp3.repackaged.internal.Util;
|
||
|
import okhttp3.repackaged.internal.Version;
|
||
|
import okhttp3.repackaged.internal.framed.ErrorCode;
|
||
|
import okhttp3.repackaged.internal.framed.FramedConnection;
|
||
|
import okhttp3.repackaged.internal.framed.FramedStream;
|
||
|
import okhttp3.repackaged.internal.http.Http1xStream;
|
||
|
import okhttp3.repackaged.internal.http.OkHeaders;
|
||
|
import okhttp3.repackaged.internal.http.RouteException;
|
||
|
import okhttp3.repackaged.internal.http.StreamAllocation;
|
||
|
import okhttp3.repackaged.internal.tls.OkHostnameVerifier;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public final class RealConnection extends FramedConnection.Listener implements Connection {
|
||
|
private Handshake agZ;
|
||
|
public int allocationLimit;
|
||
|
private final Route amD;
|
||
|
private Socket amP;
|
||
|
public volatile FramedConnection framedConnection;
|
||
|
public boolean noNewStreams;
|
||
|
private Protocol protocol;
|
||
|
public giO sink;
|
||
|
public Socket socket;
|
||
|
public InterfaceC15142giR source;
|
||
|
public int successCount;
|
||
|
public final List<Reference<StreamAllocation>> allocations = new ArrayList();
|
||
|
public long idleAtNanos = Long.MAX_VALUE;
|
||
|
|
||
|
public RealConnection(Route route) {
|
||
|
this.amD = route;
|
||
|
}
|
||
|
|
||
|
public final void connect(int i, int i2, int i3, List<ConnectionSpec> list, boolean z) throws RouteException {
|
||
|
Socket createSocket;
|
||
|
if (this.protocol != null) {
|
||
|
throw new IllegalStateException("already connected");
|
||
|
}
|
||
|
ConnectionSpecSelector connectionSpecSelector = new ConnectionSpecSelector(list);
|
||
|
Proxy proxy = this.amD.proxy();
|
||
|
Address address = this.amD.address();
|
||
|
if (this.amD.address().sslSocketFactory() == null && !list.contains(ConnectionSpec.CLEARTEXT)) {
|
||
|
throw new RouteException(new UnknownServiceException("CLEARTEXT communication not supported: ".concat(String.valueOf(list))));
|
||
|
}
|
||
|
RouteException routeException = null;
|
||
|
while (this.protocol == null) {
|
||
|
try {
|
||
|
} catch (IOException e) {
|
||
|
Util.closeQuietly(this.socket);
|
||
|
Util.closeQuietly(this.amP);
|
||
|
this.socket = null;
|
||
|
this.amP = null;
|
||
|
this.source = null;
|
||
|
this.sink = null;
|
||
|
this.agZ = null;
|
||
|
this.protocol = null;
|
||
|
if (routeException == null) {
|
||
|
routeException = new RouteException(e);
|
||
|
} else {
|
||
|
routeException.addConnectException(e);
|
||
|
}
|
||
|
if (z) {
|
||
|
if (!connectionSpecSelector.connectionFailed(e)) {
|
||
|
throw routeException;
|
||
|
}
|
||
|
} else {
|
||
|
throw routeException;
|
||
|
}
|
||
|
}
|
||
|
if (proxy.type() != Proxy.Type.DIRECT && proxy.type() != Proxy.Type.HTTP) {
|
||
|
createSocket = new Socket(proxy);
|
||
|
this.amP = createSocket;
|
||
|
a(i, i2, i3, connectionSpecSelector);
|
||
|
}
|
||
|
createSocket = address.socketFactory().createSocket();
|
||
|
this.amP = createSocket;
|
||
|
a(i, i2, i3, connectionSpecSelector);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void a(int i, int i2, int i3, ConnectionSpecSelector connectionSpecSelector) throws IOException {
|
||
|
this.amP.setSoTimeout(i2);
|
||
|
try {
|
||
|
Platform.get().connectSocket(this.amP, this.amD.socketAddress(), i);
|
||
|
this.source = C15145giV.a(C15145giV.e(this.amP));
|
||
|
this.sink = C15145giV.e(C15145giV.c(this.amP));
|
||
|
if (this.amD.address().sslSocketFactory() != null) {
|
||
|
a(i2, i3, connectionSpecSelector);
|
||
|
} else {
|
||
|
this.protocol = Protocol.HTTP_1_1;
|
||
|
this.socket = this.amP;
|
||
|
}
|
||
|
if (this.protocol != Protocol.SPDY_3 && this.protocol != Protocol.HTTP_2) {
|
||
|
this.allocationLimit = 1;
|
||
|
return;
|
||
|
}
|
||
|
this.socket.setSoTimeout(0);
|
||
|
FramedConnection build = new FramedConnection.Builder(true).socket(this.socket, this.amD.address().url().host(), this.source, this.sink).protocol(this.protocol).listener(this).build();
|
||
|
build.sendConnectionPreface();
|
||
|
this.allocationLimit = build.maxConcurrentStreams();
|
||
|
this.framedConnection = build;
|
||
|
} catch (ConnectException unused) {
|
||
|
StringBuilder sb = new StringBuilder("Failed to connect to ");
|
||
|
sb.append(this.amD.socketAddress());
|
||
|
throw new ConnectException(sb.toString());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void a(int i, int i2, ConnectionSpecSelector connectionSpecSelector) throws IOException {
|
||
|
SSLSocket sSLSocket;
|
||
|
if (this.amD.requiresTunnel()) {
|
||
|
o(i, i2);
|
||
|
}
|
||
|
Address address = this.amD.address();
|
||
|
try {
|
||
|
try {
|
||
|
sSLSocket = (SSLSocket) address.sslSocketFactory().createSocket(this.amP, address.url().host(), address.url().port(), true);
|
||
|
} catch (Throwable th) {
|
||
|
th = th;
|
||
|
sSLSocket = null;
|
||
|
}
|
||
|
} catch (AssertionError e) {
|
||
|
e = e;
|
||
|
}
|
||
|
try {
|
||
|
ConnectionSpec configureSecureSocket = connectionSpecSelector.configureSecureSocket(sSLSocket);
|
||
|
if (configureSecureSocket.supportsTlsExtensions()) {
|
||
|
Platform.get().configureTlsExtensions(sSLSocket, address.url().host(), address.protocols());
|
||
|
}
|
||
|
sSLSocket.startHandshake();
|
||
|
Handshake handshake = Handshake.get(sSLSocket.getSession());
|
||
|
if (!address.hostnameVerifier().verify(address.url().host(), sSLSocket.getSession())) {
|
||
|
X509Certificate x509Certificate = (X509Certificate) handshake.peerCertificates().get(0);
|
||
|
StringBuilder sb = new StringBuilder("Hostname ");
|
||
|
sb.append(address.url().host());
|
||
|
sb.append(" not verified:\n certificate: ");
|
||
|
sb.append(CertificatePinner.pin(x509Certificate));
|
||
|
sb.append("\n DN: ");
|
||
|
sb.append(x509Certificate.getSubjectDN().getName());
|
||
|
sb.append("\n subjectAltNames: ");
|
||
|
sb.append(OkHostnameVerifier.allSubjectAltNames(x509Certificate));
|
||
|
throw new SSLPeerUnverifiedException(sb.toString());
|
||
|
}
|
||
|
address.certificatePinner().check(address.url().host(), handshake.peerCertificates());
|
||
|
String selectedProtocol = configureSecureSocket.supportsTlsExtensions() ? Platform.get().getSelectedProtocol(sSLSocket) : null;
|
||
|
this.socket = sSLSocket;
|
||
|
this.source = C15145giV.a(C15145giV.e(sSLSocket));
|
||
|
this.sink = C15145giV.e(C15145giV.c(this.socket));
|
||
|
this.agZ = handshake;
|
||
|
this.protocol = selectedProtocol != null ? Protocol.get(selectedProtocol) : Protocol.HTTP_1_1;
|
||
|
if (sSLSocket != null) {
|
||
|
Platform.get().afterHandshake(sSLSocket);
|
||
|
}
|
||
|
} catch (AssertionError e2) {
|
||
|
e = e2;
|
||
|
if (!Util.isAndroidGetsocknameError(e)) {
|
||
|
throw e;
|
||
|
}
|
||
|
throw new IOException(e);
|
||
|
} catch (Throwable th2) {
|
||
|
th = th2;
|
||
|
if (sSLSocket != null) {
|
||
|
Platform.get().afterHandshake(sSLSocket);
|
||
|
}
|
||
|
Util.closeQuietly((Socket) sSLSocket);
|
||
|
throw th;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void o(int i, int i2) throws IOException {
|
||
|
Request vn = vn();
|
||
|
HttpUrl url = vn.url();
|
||
|
StringBuilder sb = new StringBuilder("CONNECT ");
|
||
|
sb.append(Util.hostHeader(url, true));
|
||
|
sb.append(" HTTP/1.1");
|
||
|
String obj = sb.toString();
|
||
|
do {
|
||
|
Http1xStream http1xStream = new Http1xStream(null, this.source, this.sink);
|
||
|
this.source.timeout().timeout(i, TimeUnit.MILLISECONDS);
|
||
|
this.sink.timeout().timeout(i2, TimeUnit.MILLISECONDS);
|
||
|
http1xStream.writeRequest(vn.headers(), obj);
|
||
|
http1xStream.finishRequest();
|
||
|
Response build = http1xStream.readResponse().request(vn).build();
|
||
|
long contentLength = OkHeaders.contentLength(build);
|
||
|
if (contentLength == -1) {
|
||
|
contentLength = 0;
|
||
|
}
|
||
|
giZ newFixedLengthSource = http1xStream.newFixedLengthSource(contentLength);
|
||
|
Util.skipAll(newFixedLengthSource, Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||
|
newFixedLengthSource.close();
|
||
|
int code = build.code();
|
||
|
if (code == 200) {
|
||
|
if (this.source.b().a != 0 || this.sink.b().a != 0) {
|
||
|
throw new IOException("TLS tunnel buffered too many bytes!");
|
||
|
}
|
||
|
return;
|
||
|
} else if (code == 407) {
|
||
|
vn = this.amD.address().proxyAuthenticator().authenticate(this.amD, build);
|
||
|
} else {
|
||
|
StringBuilder sb2 = new StringBuilder("Unexpected response code for CONNECT: ");
|
||
|
sb2.append(build.code());
|
||
|
throw new IOException(sb2.toString());
|
||
|
}
|
||
|
} while (vn != null);
|
||
|
throw new IOException("Failed to authenticate with proxy");
|
||
|
}
|
||
|
|
||
|
private Request vn() throws IOException {
|
||
|
return new Request.Builder().url(this.amD.address().url()).header(HttpHeaders.HOST, Util.hostHeader(this.amD.address().url(), true)).header("Proxy-Connection", "Keep-Alive").header("User-Agent", Version.userAgent()).build();
|
||
|
}
|
||
|
|
||
|
public final void cancel() {
|
||
|
Util.closeQuietly(this.amP);
|
||
|
}
|
||
|
|
||
|
public final boolean isHealthy(boolean z) {
|
||
|
if (this.socket.isClosed() || this.socket.isInputShutdown() || this.socket.isOutputShutdown()) {
|
||
|
return false;
|
||
|
}
|
||
|
if (this.framedConnection == null && z) {
|
||
|
try {
|
||
|
int soTimeout = this.socket.getSoTimeout();
|
||
|
try {
|
||
|
this.socket.setSoTimeout(1);
|
||
|
return !this.source.a();
|
||
|
} finally {
|
||
|
this.socket.setSoTimeout(soTimeout);
|
||
|
}
|
||
|
} catch (SocketTimeoutException unused) {
|
||
|
} catch (IOException unused2) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.repackaged.internal.framed.FramedConnection.Listener
|
||
|
public final void onStream(FramedStream framedStream) throws IOException {
|
||
|
framedStream.close(ErrorCode.REFUSED_STREAM);
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.repackaged.internal.framed.FramedConnection.Listener
|
||
|
public final void onSettings(FramedConnection framedConnection) {
|
||
|
this.allocationLimit = framedConnection.maxConcurrentStreams();
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.repackaged.Connection
|
||
|
public final Protocol protocol() {
|
||
|
if (this.framedConnection != null) {
|
||
|
return this.framedConnection.getProtocol();
|
||
|
}
|
||
|
Protocol protocol = this.protocol;
|
||
|
return protocol == null ? Protocol.HTTP_1_1 : protocol;
|
||
|
}
|
||
|
|
||
|
public final String toString() {
|
||
|
StringBuilder sb = new StringBuilder("Connection{");
|
||
|
sb.append(this.amD.address().url().host());
|
||
|
sb.append(":");
|
||
|
sb.append(this.amD.address().url().port());
|
||
|
sb.append(", proxy=");
|
||
|
sb.append(this.amD.proxy());
|
||
|
sb.append(" hostAddress=");
|
||
|
sb.append(this.amD.socketAddress());
|
||
|
sb.append(" cipherSuite=");
|
||
|
Handshake handshake = this.agZ;
|
||
|
sb.append(handshake != null ? handshake.cipherSuite() : "none");
|
||
|
sb.append(" protocol=");
|
||
|
sb.append(this.protocol);
|
||
|
sb.append(UrlTreeKt.componentParamSuffixChar);
|
||
|
return sb.toString();
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.repackaged.Connection
|
||
|
public final Socket socket() {
|
||
|
return this.socket;
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.repackaged.Connection
|
||
|
public final Route route() {
|
||
|
return this.amD;
|
||
|
}
|
||
|
|
||
|
public final boolean isMultiplexed() {
|
||
|
return this.framedConnection != null;
|
||
|
}
|
||
|
|
||
|
final boolean isConnected() {
|
||
|
return this.protocol != null;
|
||
|
}
|
||
|
|
||
|
@Override // okhttp3.repackaged.Connection
|
||
|
public final Handshake handshake() {
|
||
|
return this.agZ;
|
||
|
}
|
||
|
}
|