Initial commit
This commit is contained in:
25
sources/okhttp3/internal/connection/ConnectInterceptor.java
Normal file
25
sources/okhttp3/internal/connection/ConnectInterceptor.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package okhttp3.internal.connection;
|
||||
|
||||
import java.io.IOException;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.internal.http.RealInterceptorChain;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class ConnectInterceptor implements Interceptor {
|
||||
public final OkHttpClient client;
|
||||
|
||||
public ConnectInterceptor(OkHttpClient okHttpClient) {
|
||||
this.client = okHttpClient;
|
||||
}
|
||||
|
||||
@Override // okhttp3.Interceptor
|
||||
public Response intercept(Interceptor.Chain chain) throws IOException {
|
||||
RealInterceptorChain realInterceptorChain = (RealInterceptorChain) chain;
|
||||
Request request = realInterceptorChain.request();
|
||||
StreamAllocation streamAllocation = realInterceptorChain.streamAllocation();
|
||||
return realInterceptorChain.proceed(request, streamAllocation, streamAllocation.newStream(this.client, chain, !request.method().equals("GET")), streamAllocation.connection());
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
package okhttp3.internal.connection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.UnknownServiceException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import javax.net.ssl.SSLProtocolException;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import okhttp3.ConnectionSpec;
|
||||
import okhttp3.internal.Internal;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class ConnectionSpecSelector {
|
||||
private final List<ConnectionSpec> connectionSpecs;
|
||||
private boolean isFallback;
|
||||
private boolean isFallbackPossible;
|
||||
private int nextModeIndex = 0;
|
||||
|
||||
public ConnectionSpecSelector(List<ConnectionSpec> list) {
|
||||
this.connectionSpecs = list;
|
||||
}
|
||||
|
||||
private boolean isFallbackPossible(SSLSocket sSLSocket) {
|
||||
for (int i = this.nextModeIndex; i < this.connectionSpecs.size(); i++) {
|
||||
if (this.connectionSpecs.get(i).isCompatible(sSLSocket)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ConnectionSpec configureSecureSocket(SSLSocket sSLSocket) throws IOException {
|
||||
ConnectionSpec connectionSpec;
|
||||
int i = this.nextModeIndex;
|
||||
int size = this.connectionSpecs.size();
|
||||
while (true) {
|
||||
if (i >= size) {
|
||||
connectionSpec = null;
|
||||
break;
|
||||
}
|
||||
connectionSpec = this.connectionSpecs.get(i);
|
||||
if (connectionSpec.isCompatible(sSLSocket)) {
|
||||
this.nextModeIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (connectionSpec != null) {
|
||||
this.isFallbackPossible = isFallbackPossible(sSLSocket);
|
||||
Internal.instance.apply(connectionSpec, sSLSocket, this.isFallback);
|
||||
return connectionSpec;
|
||||
}
|
||||
throw new UnknownServiceException("Unable to find acceptable protocols. isFallback=" + this.isFallback + ", modes=" + this.connectionSpecs + ", supported protocols=" + Arrays.toString(sSLSocket.getEnabledProtocols()));
|
||||
}
|
||||
|
||||
public boolean connectionFailed(IOException iOException) {
|
||||
this.isFallback = true;
|
||||
if (!this.isFallbackPossible || (iOException instanceof ProtocolException) || (iOException instanceof InterruptedIOException)) {
|
||||
return false;
|
||||
}
|
||||
boolean z = iOException instanceof SSLHandshakeException;
|
||||
if ((z && (iOException.getCause() instanceof CertificateException)) || (iOException instanceof SSLPeerUnverifiedException)) {
|
||||
return false;
|
||||
}
|
||||
return z || (iOException instanceof SSLProtocolException);
|
||||
}
|
||||
}
|
391
sources/okhttp3/internal/connection/RealConnection.java
Normal file
391
sources/okhttp3/internal/connection/RealConnection.java
Normal file
@@ -0,0 +1,391 @@
|
||||
package okhttp3.internal.connection;
|
||||
|
||||
import com.ubt.jimu.transport.model.TransportFile;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.Reference;
|
||||
import java.net.ConnectException;
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
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.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import okhttp3.Address;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.CertificatePinner;
|
||||
import okhttp3.Connection;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.ConnectionSpec;
|
||||
import okhttp3.EventListener;
|
||||
import okhttp3.Handshake;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.Route;
|
||||
import okhttp3.internal.Internal;
|
||||
import okhttp3.internal.Util;
|
||||
import okhttp3.internal.Version;
|
||||
import okhttp3.internal.http.HttpCodec;
|
||||
import okhttp3.internal.http.HttpHeaders;
|
||||
import okhttp3.internal.http1.Http1Codec;
|
||||
import okhttp3.internal.http2.ErrorCode;
|
||||
import okhttp3.internal.http2.Http2Codec;
|
||||
import okhttp3.internal.http2.Http2Connection;
|
||||
import okhttp3.internal.http2.Http2Stream;
|
||||
import okhttp3.internal.platform.Platform;
|
||||
import okhttp3.internal.tls.OkHostnameVerifier;
|
||||
import okhttp3.internal.ws.RealWebSocket;
|
||||
import okio.BufferedSink;
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class RealConnection extends Http2Connection.Listener implements Connection {
|
||||
private static final int MAX_TUNNEL_ATTEMPTS = 21;
|
||||
private static final String NPE_THROW_WITH_NULL = "throw with null exception";
|
||||
private final ConnectionPool connectionPool;
|
||||
private Handshake handshake;
|
||||
private Http2Connection http2Connection;
|
||||
public boolean noNewStreams;
|
||||
private Protocol protocol;
|
||||
private Socket rawSocket;
|
||||
private final Route route;
|
||||
private BufferedSink sink;
|
||||
private Socket socket;
|
||||
private BufferedSource source;
|
||||
public int successCount;
|
||||
public int allocationLimit = 1;
|
||||
public final List<Reference<StreamAllocation>> allocations = new ArrayList();
|
||||
public long idleAtNanos = Long.MAX_VALUE;
|
||||
|
||||
public RealConnection(ConnectionPool connectionPool, Route route) {
|
||||
this.connectionPool = connectionPool;
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
private void connectSocket(int i, int i2, Call call, EventListener eventListener) throws IOException {
|
||||
Proxy proxy = this.route.proxy();
|
||||
this.rawSocket = (proxy.type() == Proxy.Type.DIRECT || proxy.type() == Proxy.Type.HTTP) ? this.route.address().socketFactory().createSocket() : new Socket(proxy);
|
||||
eventListener.connectStart(call, this.route.socketAddress(), proxy);
|
||||
this.rawSocket.setSoTimeout(i2);
|
||||
try {
|
||||
Platform.get().connectSocket(this.rawSocket, this.route.socketAddress(), i);
|
||||
try {
|
||||
this.source = Okio.buffer(Okio.source(this.rawSocket));
|
||||
this.sink = Okio.buffer(Okio.sink(this.rawSocket));
|
||||
} catch (NullPointerException e) {
|
||||
if (NPE_THROW_WITH_NULL.equals(e.getMessage())) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
} catch (ConnectException e2) {
|
||||
ConnectException connectException = new ConnectException("Failed to connect to " + this.route.socketAddress());
|
||||
connectException.initCause(e2);
|
||||
throw connectException;
|
||||
}
|
||||
}
|
||||
|
||||
private void connectTls(ConnectionSpecSelector connectionSpecSelector) throws IOException {
|
||||
SSLSocket sSLSocket;
|
||||
Address address = this.route.address();
|
||||
try {
|
||||
try {
|
||||
sSLSocket = (SSLSocket) address.sslSocketFactory().createSocket(this.rawSocket, address.url().host(), address.url().port(), true);
|
||||
try {
|
||||
ConnectionSpec configureSecureSocket = connectionSpecSelector.configureSecureSocket(sSLSocket);
|
||||
if (configureSecureSocket.supportsTlsExtensions()) {
|
||||
Platform.get().configureTlsExtensions(sSLSocket, address.url().host(), address.protocols());
|
||||
}
|
||||
sSLSocket.startHandshake();
|
||||
SSLSession session = sSLSocket.getSession();
|
||||
Handshake handshake = Handshake.get(session);
|
||||
if (address.hostnameVerifier().verify(address.url().host(), session)) {
|
||||
address.certificatePinner().check(address.url().host(), handshake.peerCertificates());
|
||||
String selectedProtocol = configureSecureSocket.supportsTlsExtensions() ? Platform.get().getSelectedProtocol(sSLSocket) : null;
|
||||
this.socket = sSLSocket;
|
||||
this.source = Okio.buffer(Okio.source(this.socket));
|
||||
this.sink = Okio.buffer(Okio.sink(this.socket));
|
||||
this.handshake = handshake;
|
||||
this.protocol = selectedProtocol != null ? Protocol.get(selectedProtocol) : Protocol.HTTP_1_1;
|
||||
if (sSLSocket != null) {
|
||||
Platform.get().afterHandshake(sSLSocket);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
X509Certificate x509Certificate = (X509Certificate) handshake.peerCertificates().get(0);
|
||||
throw new SSLPeerUnverifiedException("Hostname " + address.url().host() + " not verified:\n certificate: " + CertificatePinner.pin(x509Certificate) + "\n DN: " + x509Certificate.getSubjectDN().getName() + "\n subjectAltNames: " + OkHostnameVerifier.allSubjectAltNames(x509Certificate));
|
||||
} catch (AssertionError e) {
|
||||
e = e;
|
||||
if (!Util.isAndroidGetsocknameError(e)) {
|
||||
throw e;
|
||||
}
|
||||
throw new IOException(e);
|
||||
} catch (Throwable th) {
|
||||
th = th;
|
||||
if (sSLSocket != null) {
|
||||
Platform.get().afterHandshake(sSLSocket);
|
||||
}
|
||||
Util.closeQuietly((Socket) sSLSocket);
|
||||
throw th;
|
||||
}
|
||||
} catch (Throwable th2) {
|
||||
th = th2;
|
||||
sSLSocket = null;
|
||||
}
|
||||
} catch (AssertionError e2) {
|
||||
e = e2;
|
||||
}
|
||||
}
|
||||
|
||||
private void connectTunnel(int i, int i2, int i3, Call call, EventListener eventListener) throws IOException {
|
||||
Request createTunnelRequest = createTunnelRequest();
|
||||
HttpUrl url = createTunnelRequest.url();
|
||||
for (int i4 = 0; i4 < 21; i4++) {
|
||||
connectSocket(i, i2, call, eventListener);
|
||||
createTunnelRequest = createTunnel(i2, i3, createTunnelRequest, url);
|
||||
if (createTunnelRequest == null) {
|
||||
return;
|
||||
}
|
||||
Util.closeQuietly(this.rawSocket);
|
||||
this.rawSocket = null;
|
||||
this.sink = null;
|
||||
this.source = null;
|
||||
eventListener.connectEnd(call, this.route.socketAddress(), this.route.proxy(), null);
|
||||
}
|
||||
}
|
||||
|
||||
private Request createTunnel(int i, int i2, Request request, HttpUrl httpUrl) throws IOException {
|
||||
String str = "CONNECT " + Util.hostHeader(httpUrl, true) + " HTTP/1.1";
|
||||
while (true) {
|
||||
Http1Codec http1Codec = new Http1Codec(null, null, this.source, this.sink);
|
||||
this.source.timeout().timeout(i, TimeUnit.MILLISECONDS);
|
||||
this.sink.timeout().timeout(i2, TimeUnit.MILLISECONDS);
|
||||
http1Codec.writeRequest(request.headers(), str);
|
||||
http1Codec.finishRequest();
|
||||
Response build = http1Codec.readResponseHeaders(false).request(request).build();
|
||||
long contentLength = HttpHeaders.contentLength(build);
|
||||
if (contentLength == -1) {
|
||||
contentLength = 0;
|
||||
}
|
||||
Source newFixedLengthSource = http1Codec.newFixedLengthSource(contentLength);
|
||||
Util.skipAll(newFixedLengthSource, Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
newFixedLengthSource.close();
|
||||
int code = build.code();
|
||||
if (code == 200) {
|
||||
if (this.source.buffer().exhausted() && this.sink.buffer().exhausted()) {
|
||||
return null;
|
||||
}
|
||||
throw new IOException("TLS tunnel buffered too many bytes!");
|
||||
}
|
||||
if (code != 407) {
|
||||
throw new IOException("Unexpected response code for CONNECT: " + build.code());
|
||||
}
|
||||
Request authenticate = this.route.address().proxyAuthenticator().authenticate(this.route, build);
|
||||
if (authenticate == null) {
|
||||
throw new IOException("Failed to authenticate with proxy");
|
||||
}
|
||||
if ("close".equalsIgnoreCase(build.header("Connection"))) {
|
||||
return authenticate;
|
||||
}
|
||||
request = authenticate;
|
||||
}
|
||||
}
|
||||
|
||||
private Request createTunnelRequest() {
|
||||
return new Request.Builder().url(this.route.address().url()).header("Host", Util.hostHeader(this.route.address().url(), true)).header("Proxy-Connection", "Keep-Alive").header("User-Agent", Version.userAgent()).build();
|
||||
}
|
||||
|
||||
private void establishProtocol(ConnectionSpecSelector connectionSpecSelector, int i, Call call, EventListener eventListener) throws IOException {
|
||||
if (this.route.address().sslSocketFactory() != null) {
|
||||
eventListener.secureConnectStart(call);
|
||||
connectTls(connectionSpecSelector);
|
||||
eventListener.secureConnectEnd(call, this.handshake);
|
||||
if (this.protocol == Protocol.HTTP_2) {
|
||||
startHttp2(i);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!this.route.address().protocols().contains(Protocol.H2_PRIOR_KNOWLEDGE)) {
|
||||
this.socket = this.rawSocket;
|
||||
this.protocol = Protocol.HTTP_1_1;
|
||||
} else {
|
||||
this.socket = this.rawSocket;
|
||||
this.protocol = Protocol.H2_PRIOR_KNOWLEDGE;
|
||||
startHttp2(i);
|
||||
}
|
||||
}
|
||||
|
||||
private void startHttp2(int i) throws IOException {
|
||||
this.socket.setSoTimeout(0);
|
||||
this.http2Connection = new Http2Connection.Builder(true).socket(this.socket, this.route.address().url().host(), this.source, this.sink).listener(this).pingIntervalMillis(i).build();
|
||||
this.http2Connection.start();
|
||||
}
|
||||
|
||||
public static RealConnection testConnection(ConnectionPool connectionPool, Route route, Socket socket, long j) {
|
||||
RealConnection realConnection = new RealConnection(connectionPool, route);
|
||||
realConnection.socket = socket;
|
||||
realConnection.idleAtNanos = j;
|
||||
return realConnection;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
Util.closeQuietly(this.rawSocket);
|
||||
}
|
||||
|
||||
/* JADX WARN: Removed duplicated region for block: B:32:0x00e4 */
|
||||
/* JADX WARN: Removed duplicated region for block: B:43:0x00f4 A[ORIG_RETURN, RETURN] */
|
||||
/* JADX WARN: Removed duplicated region for block: B:47:0x012f */
|
||||
/* JADX WARN: Removed duplicated region for block: B:49:0x013b */
|
||||
/* JADX WARN: Removed duplicated region for block: B:54:0x0143 A[SYNTHETIC] */
|
||||
/* JADX WARN: Removed duplicated region for block: B:56:0x0136 */
|
||||
/*
|
||||
Code decompiled incorrectly, please refer to instructions dump.
|
||||
To view partially-correct code enable 'Show inconsistent code' option in preferences
|
||||
*/
|
||||
public void connect(int r17, int r18, int r19, int r20, boolean r21, okhttp3.Call r22, okhttp3.EventListener r23) {
|
||||
/*
|
||||
Method dump skipped, instructions count: 345
|
||||
To view this dump change 'Code comments level' option to 'DEBUG'
|
||||
*/
|
||||
throw new UnsupportedOperationException("Method not decompiled: okhttp3.internal.connection.RealConnection.connect(int, int, int, int, boolean, okhttp3.Call, okhttp3.EventListener):void");
|
||||
}
|
||||
|
||||
@Override // okhttp3.Connection
|
||||
public Handshake handshake() {
|
||||
return this.handshake;
|
||||
}
|
||||
|
||||
public boolean isEligible(Address address, Route route) {
|
||||
if (this.allocations.size() >= this.allocationLimit || this.noNewStreams || !Internal.instance.equalsNonHost(this.route.address(), address)) {
|
||||
return false;
|
||||
}
|
||||
if (address.url().host().equals(route().address().url().host())) {
|
||||
return true;
|
||||
}
|
||||
if (this.http2Connection == null || route == null || route.proxy().type() != Proxy.Type.DIRECT || this.route.proxy().type() != Proxy.Type.DIRECT || !this.route.socketAddress().equals(route.socketAddress()) || route.address().hostnameVerifier() != OkHostnameVerifier.INSTANCE || !supportsUrl(address.url())) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
address.certificatePinner().check(address.url().host(), handshake().peerCertificates());
|
||||
return true;
|
||||
} catch (SSLPeerUnverifiedException unused) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHealthy(boolean z) {
|
||||
if (this.socket.isClosed() || this.socket.isInputShutdown() || this.socket.isOutputShutdown()) {
|
||||
return false;
|
||||
}
|
||||
if (this.http2Connection != null) {
|
||||
return !r0.isShutdown();
|
||||
}
|
||||
if (z) {
|
||||
try {
|
||||
int soTimeout = this.socket.getSoTimeout();
|
||||
try {
|
||||
this.socket.setSoTimeout(1);
|
||||
return !this.source.exhausted();
|
||||
} finally {
|
||||
this.socket.setSoTimeout(soTimeout);
|
||||
}
|
||||
} catch (SocketTimeoutException unused) {
|
||||
} catch (IOException unused2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isMultiplexed() {
|
||||
return this.http2Connection != null;
|
||||
}
|
||||
|
||||
public HttpCodec newCodec(OkHttpClient okHttpClient, Interceptor.Chain chain, StreamAllocation streamAllocation) throws SocketException {
|
||||
Http2Connection http2Connection = this.http2Connection;
|
||||
if (http2Connection != null) {
|
||||
return new Http2Codec(okHttpClient, chain, streamAllocation, http2Connection);
|
||||
}
|
||||
this.socket.setSoTimeout(chain.readTimeoutMillis());
|
||||
this.source.timeout().timeout(chain.readTimeoutMillis(), TimeUnit.MILLISECONDS);
|
||||
this.sink.timeout().timeout(chain.writeTimeoutMillis(), TimeUnit.MILLISECONDS);
|
||||
return new Http1Codec(okHttpClient, streamAllocation, this.source, this.sink);
|
||||
}
|
||||
|
||||
public RealWebSocket.Streams newWebSocketStreams(final StreamAllocation streamAllocation) {
|
||||
return new RealWebSocket.Streams(true, this.source, this.sink) { // from class: okhttp3.internal.connection.RealConnection.1
|
||||
@Override // java.io.Closeable, java.lang.AutoCloseable
|
||||
public void close() throws IOException {
|
||||
StreamAllocation streamAllocation2 = streamAllocation;
|
||||
streamAllocation2.streamFinished(true, streamAllocation2.codec(), -1L, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Connection.Listener
|
||||
public void onSettings(Http2Connection http2Connection) {
|
||||
synchronized (this.connectionPool) {
|
||||
this.allocationLimit = http2Connection.maxConcurrentStreams();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // okhttp3.internal.http2.Http2Connection.Listener
|
||||
public void onStream(Http2Stream http2Stream) throws IOException {
|
||||
http2Stream.close(ErrorCode.REFUSED_STREAM);
|
||||
}
|
||||
|
||||
@Override // okhttp3.Connection
|
||||
public Protocol protocol() {
|
||||
return this.protocol;
|
||||
}
|
||||
|
||||
@Override // okhttp3.Connection
|
||||
public Route route() {
|
||||
return this.route;
|
||||
}
|
||||
|
||||
@Override // okhttp3.Connection
|
||||
public Socket socket() {
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
public boolean supportsUrl(HttpUrl httpUrl) {
|
||||
if (httpUrl.port() != this.route.address().url().port()) {
|
||||
return false;
|
||||
}
|
||||
if (httpUrl.host().equals(this.route.address().url().host())) {
|
||||
return true;
|
||||
}
|
||||
return this.handshake != null && OkHostnameVerifier.INSTANCE.verify(httpUrl.host(), (X509Certificate) this.handshake.peerCertificates().get(0));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Connection{");
|
||||
sb.append(this.route.address().url().host());
|
||||
sb.append(":");
|
||||
sb.append(this.route.address().url().port());
|
||||
sb.append(", proxy=");
|
||||
sb.append(this.route.proxy());
|
||||
sb.append(" hostAddress=");
|
||||
sb.append(this.route.socketAddress());
|
||||
sb.append(" cipherSuite=");
|
||||
Handshake handshake = this.handshake;
|
||||
sb.append(handshake != null ? handshake.cipherSuite() : TransportFile.TYPE_NONE);
|
||||
sb.append(" protocol=");
|
||||
sb.append(this.protocol);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
22
sources/okhttp3/internal/connection/RouteDatabase.java
Normal file
22
sources/okhttp3/internal/connection/RouteDatabase.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package okhttp3.internal.connection;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import okhttp3.Route;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class RouteDatabase {
|
||||
private final Set<Route> failedRoutes = new LinkedHashSet();
|
||||
|
||||
public synchronized void connected(Route route) {
|
||||
this.failedRoutes.remove(route);
|
||||
}
|
||||
|
||||
public synchronized void failed(Route route) {
|
||||
this.failedRoutes.add(route);
|
||||
}
|
||||
|
||||
public synchronized boolean shouldPostpone(Route route) {
|
||||
return this.failedRoutes.contains(route);
|
||||
}
|
||||
}
|
29
sources/okhttp3/internal/connection/RouteException.java
Normal file
29
sources/okhttp3/internal/connection/RouteException.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package okhttp3.internal.connection;
|
||||
|
||||
import java.io.IOException;
|
||||
import okhttp3.internal.Util;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class RouteException extends RuntimeException {
|
||||
private IOException firstException;
|
||||
private IOException lastException;
|
||||
|
||||
public RouteException(IOException iOException) {
|
||||
super(iOException);
|
||||
this.firstException = iOException;
|
||||
this.lastException = iOException;
|
||||
}
|
||||
|
||||
public void addConnectException(IOException iOException) {
|
||||
Util.addSuppressedIfPossible(this.firstException, iOException);
|
||||
this.lastException = iOException;
|
||||
}
|
||||
|
||||
public IOException getFirstConnectException() {
|
||||
return this.firstException;
|
||||
}
|
||||
|
||||
public IOException getLastConnectException() {
|
||||
return this.lastException;
|
||||
}
|
||||
}
|
170
sources/okhttp3/internal/connection/RouteSelector.java
Normal file
170
sources/okhttp3/internal/connection/RouteSelector.java
Normal file
@@ -0,0 +1,170 @@
|
||||
package okhttp3.internal.connection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import okhttp3.Address;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.EventListener;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Route;
|
||||
import okhttp3.internal.Util;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class RouteSelector {
|
||||
private final Address address;
|
||||
private final Call call;
|
||||
private final EventListener eventListener;
|
||||
private int nextProxyIndex;
|
||||
private final RouteDatabase routeDatabase;
|
||||
private List<Proxy> proxies = Collections.emptyList();
|
||||
private List<InetSocketAddress> inetSocketAddresses = Collections.emptyList();
|
||||
private final List<Route> postponedRoutes = new ArrayList();
|
||||
|
||||
public static final class Selection {
|
||||
private int nextRouteIndex = 0;
|
||||
private final List<Route> routes;
|
||||
|
||||
Selection(List<Route> list) {
|
||||
this.routes = list;
|
||||
}
|
||||
|
||||
public List<Route> getAll() {
|
||||
return new ArrayList(this.routes);
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return this.nextRouteIndex < this.routes.size();
|
||||
}
|
||||
|
||||
public Route next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
List<Route> list = this.routes;
|
||||
int i = this.nextRouteIndex;
|
||||
this.nextRouteIndex = i + 1;
|
||||
return list.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
public RouteSelector(Address address, RouteDatabase routeDatabase, Call call, EventListener eventListener) {
|
||||
this.address = address;
|
||||
this.routeDatabase = routeDatabase;
|
||||
this.call = call;
|
||||
this.eventListener = eventListener;
|
||||
resetNextProxy(address.url(), address.proxy());
|
||||
}
|
||||
|
||||
static String getHostString(InetSocketAddress inetSocketAddress) {
|
||||
InetAddress address = inetSocketAddress.getAddress();
|
||||
return address == null ? inetSocketAddress.getHostName() : address.getHostAddress();
|
||||
}
|
||||
|
||||
private boolean hasNextProxy() {
|
||||
return this.nextProxyIndex < this.proxies.size();
|
||||
}
|
||||
|
||||
private Proxy nextProxy() throws IOException {
|
||||
if (hasNextProxy()) {
|
||||
List<Proxy> list = this.proxies;
|
||||
int i = this.nextProxyIndex;
|
||||
this.nextProxyIndex = i + 1;
|
||||
Proxy proxy = list.get(i);
|
||||
resetNextInetSocketAddress(proxy);
|
||||
return proxy;
|
||||
}
|
||||
throw new SocketException("No route to " + this.address.url().host() + "; exhausted proxy configurations: " + this.proxies);
|
||||
}
|
||||
|
||||
private void resetNextInetSocketAddress(Proxy proxy) throws IOException {
|
||||
String host;
|
||||
int port;
|
||||
this.inetSocketAddresses = new ArrayList();
|
||||
if (proxy.type() == Proxy.Type.DIRECT || proxy.type() == Proxy.Type.SOCKS) {
|
||||
host = this.address.url().host();
|
||||
port = this.address.url().port();
|
||||
} else {
|
||||
SocketAddress address = proxy.address();
|
||||
if (!(address instanceof InetSocketAddress)) {
|
||||
throw new IllegalArgumentException("Proxy.address() is not an InetSocketAddress: " + address.getClass());
|
||||
}
|
||||
InetSocketAddress inetSocketAddress = (InetSocketAddress) address;
|
||||
host = getHostString(inetSocketAddress);
|
||||
port = inetSocketAddress.getPort();
|
||||
}
|
||||
if (port < 1 || port > 65535) {
|
||||
throw new SocketException("No route to " + host + ":" + port + "; port is out of range");
|
||||
}
|
||||
if (proxy.type() == Proxy.Type.SOCKS) {
|
||||
this.inetSocketAddresses.add(InetSocketAddress.createUnresolved(host, port));
|
||||
return;
|
||||
}
|
||||
this.eventListener.dnsStart(this.call, host);
|
||||
List<InetAddress> lookup = this.address.dns().lookup(host);
|
||||
if (lookup.isEmpty()) {
|
||||
throw new UnknownHostException(this.address.dns() + " returned no addresses for " + host);
|
||||
}
|
||||
this.eventListener.dnsEnd(this.call, host, lookup);
|
||||
int size = lookup.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
this.inetSocketAddresses.add(new InetSocketAddress(lookup.get(i), port));
|
||||
}
|
||||
}
|
||||
|
||||
private void resetNextProxy(HttpUrl httpUrl, Proxy proxy) {
|
||||
if (proxy != null) {
|
||||
this.proxies = Collections.singletonList(proxy);
|
||||
} else {
|
||||
List<Proxy> select = this.address.proxySelector().select(httpUrl.uri());
|
||||
this.proxies = (select == null || select.isEmpty()) ? Util.immutableList(Proxy.NO_PROXY) : Util.immutableList(select);
|
||||
}
|
||||
this.nextProxyIndex = 0;
|
||||
}
|
||||
|
||||
public void connectFailed(Route route, IOException iOException) {
|
||||
if (route.proxy().type() != Proxy.Type.DIRECT && this.address.proxySelector() != null) {
|
||||
this.address.proxySelector().connectFailed(this.address.url().uri(), route.proxy().address(), iOException);
|
||||
}
|
||||
this.routeDatabase.failed(route);
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return hasNextProxy() || !this.postponedRoutes.isEmpty();
|
||||
}
|
||||
|
||||
public Selection next() throws IOException {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
ArrayList arrayList = new ArrayList();
|
||||
while (hasNextProxy()) {
|
||||
Proxy nextProxy = nextProxy();
|
||||
int size = this.inetSocketAddresses.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Route route = new Route(this.address, nextProxy, this.inetSocketAddresses.get(i));
|
||||
if (this.routeDatabase.shouldPostpone(route)) {
|
||||
this.postponedRoutes.add(route);
|
||||
} else {
|
||||
arrayList.add(route);
|
||||
}
|
||||
}
|
||||
if (!arrayList.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (arrayList.isEmpty()) {
|
||||
arrayList.addAll(this.postponedRoutes);
|
||||
this.postponedRoutes.clear();
|
||||
}
|
||||
return new Selection(arrayList);
|
||||
}
|
||||
}
|
427
sources/okhttp3/internal/connection/StreamAllocation.java
Normal file
427
sources/okhttp3/internal/connection/StreamAllocation.java
Normal file
@@ -0,0 +1,427 @@
|
||||
package okhttp3.internal.connection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.Socket;
|
||||
import java.util.List;
|
||||
import okhttp3.Address;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.EventListener;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Route;
|
||||
import okhttp3.internal.Internal;
|
||||
import okhttp3.internal.Util;
|
||||
import okhttp3.internal.connection.RouteSelector;
|
||||
import okhttp3.internal.http.HttpCodec;
|
||||
import okhttp3.internal.http2.ConnectionShutdownException;
|
||||
import okhttp3.internal.http2.ErrorCode;
|
||||
import okhttp3.internal.http2.StreamResetException;
|
||||
|
||||
/* loaded from: classes2.dex */
|
||||
public final class StreamAllocation {
|
||||
static final /* synthetic */ boolean $assertionsDisabled = false;
|
||||
public final Address address;
|
||||
public final Call call;
|
||||
private final Object callStackTrace;
|
||||
private boolean canceled;
|
||||
private HttpCodec codec;
|
||||
private RealConnection connection;
|
||||
private final ConnectionPool connectionPool;
|
||||
public final EventListener eventListener;
|
||||
private int refusedStreamCount;
|
||||
private boolean released;
|
||||
private boolean reportedAcquired;
|
||||
private Route route;
|
||||
private RouteSelector.Selection routeSelection;
|
||||
private final RouteSelector routeSelector;
|
||||
|
||||
public static final class StreamAllocationReference extends WeakReference<StreamAllocation> {
|
||||
public final Object callStackTrace;
|
||||
|
||||
StreamAllocationReference(StreamAllocation streamAllocation, Object obj) {
|
||||
super(streamAllocation);
|
||||
this.callStackTrace = obj;
|
||||
}
|
||||
}
|
||||
|
||||
public StreamAllocation(ConnectionPool connectionPool, Address address, Call call, EventListener eventListener, Object obj) {
|
||||
this.connectionPool = connectionPool;
|
||||
this.address = address;
|
||||
this.call = call;
|
||||
this.eventListener = eventListener;
|
||||
this.routeSelector = new RouteSelector(address, routeDatabase(), call, eventListener);
|
||||
this.callStackTrace = obj;
|
||||
}
|
||||
|
||||
private Socket deallocate(boolean z, boolean z2, boolean z3) {
|
||||
Socket socket;
|
||||
if (z3) {
|
||||
this.codec = null;
|
||||
}
|
||||
if (z2) {
|
||||
this.released = true;
|
||||
}
|
||||
RealConnection realConnection = this.connection;
|
||||
if (realConnection != null) {
|
||||
if (z) {
|
||||
realConnection.noNewStreams = true;
|
||||
}
|
||||
if (this.codec == null && (this.released || this.connection.noNewStreams)) {
|
||||
release(this.connection);
|
||||
if (this.connection.allocations.isEmpty()) {
|
||||
this.connection.idleAtNanos = System.nanoTime();
|
||||
if (Internal.instance.connectionBecameIdle(this.connectionPool, this.connection)) {
|
||||
socket = this.connection.socket();
|
||||
this.connection = null;
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
socket = null;
|
||||
this.connection = null;
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private RealConnection findConnection(int i, int i2, int i3, int i4, boolean z) throws IOException {
|
||||
Socket releaseIfNoNewStreams;
|
||||
Socket socket;
|
||||
RealConnection realConnection;
|
||||
RealConnection realConnection2;
|
||||
RealConnection realConnection3;
|
||||
Route route;
|
||||
boolean z2;
|
||||
boolean z3;
|
||||
RouteSelector.Selection selection;
|
||||
synchronized (this.connectionPool) {
|
||||
if (this.released) {
|
||||
throw new IllegalStateException("released");
|
||||
}
|
||||
if (this.codec != null) {
|
||||
throw new IllegalStateException("codec != null");
|
||||
}
|
||||
if (this.canceled) {
|
||||
throw new IOException("Canceled");
|
||||
}
|
||||
RealConnection realConnection4 = this.connection;
|
||||
releaseIfNoNewStreams = releaseIfNoNewStreams();
|
||||
socket = null;
|
||||
if (this.connection != null) {
|
||||
realConnection2 = this.connection;
|
||||
realConnection = null;
|
||||
} else {
|
||||
realConnection = realConnection4;
|
||||
realConnection2 = null;
|
||||
}
|
||||
if (!this.reportedAcquired) {
|
||||
realConnection = null;
|
||||
}
|
||||
if (realConnection2 == null) {
|
||||
Internal.instance.get(this.connectionPool, this.address, this, null);
|
||||
if (this.connection != null) {
|
||||
realConnection3 = this.connection;
|
||||
route = null;
|
||||
z2 = true;
|
||||
} else {
|
||||
route = this.route;
|
||||
realConnection3 = realConnection2;
|
||||
}
|
||||
} else {
|
||||
realConnection3 = realConnection2;
|
||||
route = null;
|
||||
}
|
||||
z2 = false;
|
||||
}
|
||||
Util.closeQuietly(releaseIfNoNewStreams);
|
||||
if (realConnection != null) {
|
||||
this.eventListener.connectionReleased(this.call, realConnection);
|
||||
}
|
||||
if (z2) {
|
||||
this.eventListener.connectionAcquired(this.call, realConnection3);
|
||||
}
|
||||
if (realConnection3 != null) {
|
||||
return realConnection3;
|
||||
}
|
||||
if (route != null || ((selection = this.routeSelection) != null && selection.hasNext())) {
|
||||
z3 = false;
|
||||
} else {
|
||||
this.routeSelection = this.routeSelector.next();
|
||||
z3 = true;
|
||||
}
|
||||
synchronized (this.connectionPool) {
|
||||
if (this.canceled) {
|
||||
throw new IOException("Canceled");
|
||||
}
|
||||
if (z3) {
|
||||
List<Route> all = this.routeSelection.getAll();
|
||||
int size = all.size();
|
||||
int i5 = 0;
|
||||
while (true) {
|
||||
if (i5 >= size) {
|
||||
break;
|
||||
}
|
||||
Route route2 = all.get(i5);
|
||||
Internal.instance.get(this.connectionPool, this.address, this, route2);
|
||||
if (this.connection != null) {
|
||||
realConnection3 = this.connection;
|
||||
this.route = route2;
|
||||
z2 = true;
|
||||
break;
|
||||
}
|
||||
i5++;
|
||||
}
|
||||
}
|
||||
if (!z2) {
|
||||
if (route == null) {
|
||||
route = this.routeSelection.next();
|
||||
}
|
||||
this.route = route;
|
||||
this.refusedStreamCount = 0;
|
||||
realConnection3 = new RealConnection(this.connectionPool, route);
|
||||
acquire(realConnection3, false);
|
||||
}
|
||||
}
|
||||
if (z2) {
|
||||
this.eventListener.connectionAcquired(this.call, realConnection3);
|
||||
return realConnection3;
|
||||
}
|
||||
realConnection3.connect(i, i2, i3, i4, z, this.call, this.eventListener);
|
||||
routeDatabase().connected(realConnection3.route());
|
||||
synchronized (this.connectionPool) {
|
||||
this.reportedAcquired = true;
|
||||
Internal.instance.put(this.connectionPool, realConnection3);
|
||||
if (realConnection3.isMultiplexed()) {
|
||||
socket = Internal.instance.deduplicate(this.connectionPool, this.address, this);
|
||||
realConnection3 = this.connection;
|
||||
}
|
||||
}
|
||||
Util.closeQuietly(socket);
|
||||
this.eventListener.connectionAcquired(this.call, realConnection3);
|
||||
return realConnection3;
|
||||
}
|
||||
|
||||
private RealConnection findHealthyConnection(int i, int i2, int i3, int i4, boolean z, boolean z2) throws IOException {
|
||||
while (true) {
|
||||
RealConnection findConnection = findConnection(i, i2, i3, i4, z);
|
||||
synchronized (this.connectionPool) {
|
||||
if (findConnection.successCount == 0) {
|
||||
return findConnection;
|
||||
}
|
||||
if (findConnection.isHealthy(z2)) {
|
||||
return findConnection;
|
||||
}
|
||||
noNewStreams();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Socket releaseIfNoNewStreams() {
|
||||
RealConnection realConnection = this.connection;
|
||||
if (realConnection == null || !realConnection.noNewStreams) {
|
||||
return null;
|
||||
}
|
||||
return deallocate(false, false, true);
|
||||
}
|
||||
|
||||
private RouteDatabase routeDatabase() {
|
||||
return Internal.instance.routeDatabase(this.connectionPool);
|
||||
}
|
||||
|
||||
public void acquire(RealConnection realConnection, boolean z) {
|
||||
if (this.connection != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
this.connection = realConnection;
|
||||
this.reportedAcquired = z;
|
||||
realConnection.allocations.add(new StreamAllocationReference(this, this.callStackTrace));
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
HttpCodec httpCodec;
|
||||
RealConnection realConnection;
|
||||
synchronized (this.connectionPool) {
|
||||
this.canceled = true;
|
||||
httpCodec = this.codec;
|
||||
realConnection = this.connection;
|
||||
}
|
||||
if (httpCodec != null) {
|
||||
httpCodec.cancel();
|
||||
} else if (realConnection != null) {
|
||||
realConnection.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public HttpCodec codec() {
|
||||
HttpCodec httpCodec;
|
||||
synchronized (this.connectionPool) {
|
||||
httpCodec = this.codec;
|
||||
}
|
||||
return httpCodec;
|
||||
}
|
||||
|
||||
public synchronized RealConnection connection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
public boolean hasMoreRoutes() {
|
||||
RouteSelector.Selection selection;
|
||||
return this.route != null || ((selection = this.routeSelection) != null && selection.hasNext()) || this.routeSelector.hasNext();
|
||||
}
|
||||
|
||||
public HttpCodec newStream(OkHttpClient okHttpClient, Interceptor.Chain chain, boolean z) {
|
||||
try {
|
||||
HttpCodec newCodec = findHealthyConnection(chain.connectTimeoutMillis(), chain.readTimeoutMillis(), chain.writeTimeoutMillis(), okHttpClient.pingIntervalMillis(), okHttpClient.retryOnConnectionFailure(), z).newCodec(okHttpClient, chain, this);
|
||||
synchronized (this.connectionPool) {
|
||||
this.codec = newCodec;
|
||||
}
|
||||
return newCodec;
|
||||
} catch (IOException e) {
|
||||
throw new RouteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void noNewStreams() {
|
||||
RealConnection realConnection;
|
||||
Socket deallocate;
|
||||
synchronized (this.connectionPool) {
|
||||
realConnection = this.connection;
|
||||
deallocate = deallocate(true, false, false);
|
||||
if (this.connection != null) {
|
||||
realConnection = null;
|
||||
}
|
||||
}
|
||||
Util.closeQuietly(deallocate);
|
||||
if (realConnection != null) {
|
||||
this.eventListener.connectionReleased(this.call, realConnection);
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
RealConnection realConnection;
|
||||
Socket deallocate;
|
||||
synchronized (this.connectionPool) {
|
||||
realConnection = this.connection;
|
||||
deallocate = deallocate(false, true, false);
|
||||
if (this.connection != null) {
|
||||
realConnection = null;
|
||||
}
|
||||
}
|
||||
Util.closeQuietly(deallocate);
|
||||
if (realConnection != null) {
|
||||
this.eventListener.connectionReleased(this.call, realConnection);
|
||||
this.eventListener.callEnd(this.call);
|
||||
}
|
||||
}
|
||||
|
||||
public Socket releaseAndAcquire(RealConnection realConnection) {
|
||||
if (this.codec != null || this.connection.allocations.size() != 1) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
Reference<StreamAllocation> reference = this.connection.allocations.get(0);
|
||||
Socket deallocate = deallocate(true, false, false);
|
||||
this.connection = realConnection;
|
||||
realConnection.allocations.add(reference);
|
||||
return deallocate;
|
||||
}
|
||||
|
||||
public Route route() {
|
||||
return this.route;
|
||||
}
|
||||
|
||||
public void streamFailed(IOException iOException) {
|
||||
boolean z;
|
||||
RealConnection realConnection;
|
||||
Socket deallocate;
|
||||
synchronized (this.connectionPool) {
|
||||
if (iOException instanceof StreamResetException) {
|
||||
ErrorCode errorCode = ((StreamResetException) iOException).errorCode;
|
||||
if (errorCode == ErrorCode.REFUSED_STREAM) {
|
||||
this.refusedStreamCount++;
|
||||
if (this.refusedStreamCount > 1) {
|
||||
this.route = null;
|
||||
z = true;
|
||||
}
|
||||
z = false;
|
||||
} else {
|
||||
if (errorCode != ErrorCode.CANCEL) {
|
||||
this.route = null;
|
||||
z = true;
|
||||
}
|
||||
z = false;
|
||||
}
|
||||
} else {
|
||||
if (this.connection != null && (!this.connection.isMultiplexed() || (iOException instanceof ConnectionShutdownException))) {
|
||||
if (this.connection.successCount == 0) {
|
||||
if (this.route != null && iOException != null) {
|
||||
this.routeSelector.connectFailed(this.route, iOException);
|
||||
}
|
||||
this.route = null;
|
||||
}
|
||||
z = true;
|
||||
}
|
||||
z = false;
|
||||
}
|
||||
realConnection = this.connection;
|
||||
deallocate = deallocate(z, false, true);
|
||||
if (this.connection != null || !this.reportedAcquired) {
|
||||
realConnection = null;
|
||||
}
|
||||
}
|
||||
Util.closeQuietly(deallocate);
|
||||
if (realConnection != null) {
|
||||
this.eventListener.connectionReleased(this.call, realConnection);
|
||||
}
|
||||
}
|
||||
|
||||
public void streamFinished(boolean z, HttpCodec httpCodec, long j, IOException iOException) {
|
||||
RealConnection realConnection;
|
||||
Socket deallocate;
|
||||
boolean z2;
|
||||
this.eventListener.responseBodyEnd(this.call, j);
|
||||
synchronized (this.connectionPool) {
|
||||
if (httpCodec != null) {
|
||||
if (httpCodec == this.codec) {
|
||||
if (!z) {
|
||||
this.connection.successCount++;
|
||||
}
|
||||
realConnection = this.connection;
|
||||
deallocate = deallocate(z, false, true);
|
||||
if (this.connection != null) {
|
||||
realConnection = null;
|
||||
}
|
||||
z2 = this.released;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("expected " + this.codec + " but was " + httpCodec);
|
||||
}
|
||||
Util.closeQuietly(deallocate);
|
||||
if (realConnection != null) {
|
||||
this.eventListener.connectionReleased(this.call, realConnection);
|
||||
}
|
||||
if (iOException != null) {
|
||||
this.eventListener.callFailed(this.call, iOException);
|
||||
} else if (z2) {
|
||||
this.eventListener.callEnd(this.call);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
RealConnection connection = connection();
|
||||
return connection != null ? connection.toString() : this.address.toString();
|
||||
}
|
||||
|
||||
private void release(RealConnection realConnection) {
|
||||
int size = realConnection.allocations.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (realConnection.allocations.get(i).get() == this) {
|
||||
realConnection.allocations.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user