Search in sources :

Example 11 with Route

use of okhttp3.Route in project okhttp by square.

the class URLConnectionTest method sslFallbackNotUsedWhenRecycledConnectionFails.

/**
   * When a pooled connection fails, don't blame the route. Otherwise pooled connection failures can
   * cause unnecessary SSL fallbacks.
   *
   * https://github.com/square/okhttp/issues/515
   */
@Test
public void sslFallbackNotUsedWhenRecycledConnectionFails() throws Exception {
    server.useHttps(sslClient.socketFactory, false);
    server.enqueue(new MockResponse().setBody("abc").setSocketPolicy(DISCONNECT_AT_END));
    server.enqueue(new MockResponse().setBody("def"));
    urlFactory.setClient(urlFactory.client().newBuilder().hostnameVerifier(new RecordingHostnameVerifier()).sslSocketFactory(suppressTlsFallbackClientSocketFactory(), sslClient.trustManager).build());
    assertContent("abc", urlFactory.open(server.url("/").url()));
    // Give the server time to disconnect.
    Thread.sleep(500);
    assertContent("def", urlFactory.open(server.url("/").url()));
    Set<TlsVersion> tlsVersions = // v1.2 on OpenJDK 8.
    EnumSet.of(TlsVersion.TLS_1_0, TlsVersion.TLS_1_2);
    RecordedRequest request1 = server.takeRequest();
    assertTrue(tlsVersions.contains(request1.getTlsVersion()));
    RecordedRequest request2 = server.takeRequest();
    assertTrue(tlsVersions.contains(request2.getTlsVersion()));
}
Also used : RecordedRequest(okhttp3.mockwebserver.RecordedRequest) MockResponse(okhttp3.mockwebserver.MockResponse) Test(org.junit.Test)

Example 12 with Route

use of okhttp3.Route in project okhttp by square.

the class RealConnection method createTunnel.

/**
   * To make an HTTPS connection over an HTTP proxy, send an unencrypted CONNECT request to create
   * the proxy connection. This may need to be retried if the proxy requires authorization.
   */
private Request createTunnel(int readTimeout, int writeTimeout, Request tunnelRequest, HttpUrl url) throws IOException {
    // Make an SSL Tunnel on the first message pair of each SSL + proxy connection.
    String requestLine = "CONNECT " + Util.hostHeader(url, true) + " HTTP/1.1";
    while (true) {
        Http1Codec tunnelConnection = new Http1Codec(null, null, source, sink);
        source.timeout().timeout(readTimeout, MILLISECONDS);
        sink.timeout().timeout(writeTimeout, MILLISECONDS);
        tunnelConnection.writeRequest(tunnelRequest.headers(), requestLine);
        tunnelConnection.finishRequest();
        Response response = tunnelConnection.readResponseHeaders(false).request(tunnelRequest).build();
        // The response body from a CONNECT should be empty, but if it is not then we should consume
        // it before proceeding.
        long contentLength = HttpHeaders.contentLength(response);
        if (contentLength == -1L) {
            contentLength = 0L;
        }
        Source body = tunnelConnection.newFixedLengthSource(contentLength);
        Util.skipAll(body, Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
        body.close();
        switch(response.code()) {
            case HTTP_OK:
                // that it will almost certainly fail because the proxy has sent unexpected data.
                if (!source.buffer().exhausted() || !sink.buffer().exhausted()) {
                    throw new IOException("TLS tunnel buffered too many bytes!");
                }
                return null;
            case HTTP_PROXY_AUTH:
                tunnelRequest = route.address().proxyAuthenticator().authenticate(route, response);
                if (tunnelRequest == null)
                    throw new IOException("Failed to authenticate with proxy");
                if ("close".equalsIgnoreCase(response.header("Connection"))) {
                    return tunnelRequest;
                }
                break;
            default:
                throw new IOException("Unexpected response code for CONNECT: " + response.code());
        }
    }
}
Also used : Http1Codec(okhttp3.internal.http1.Http1Codec) Response(okhttp3.Response) IOException(java.io.IOException) BufferedSource(okio.BufferedSource) Source(okio.Source)

Example 13 with Route

use of okhttp3.Route in project okhttp by square.

the class RouteSelector method next.

public Route next() throws IOException {
    // Compute the next route to attempt.
    if (!hasNextInetSocketAddress()) {
        if (!hasNextProxy()) {
            if (!hasNextPostponed()) {
                throw new NoSuchElementException();
            }
            return nextPostponed();
        }
        lastProxy = nextProxy();
    }
    lastInetSocketAddress = nextInetSocketAddress();
    Route route = new Route(address, lastProxy, lastInetSocketAddress);
    if (routeDatabase.shouldPostpone(route)) {
        postponedRoutes.add(route);
        // We will only recurse in order to skip previously failed routes. They will be tried last.
        return next();
    }
    return route;
}
Also used : NoSuchElementException(java.util.NoSuchElementException) Route(okhttp3.Route)

Example 14 with Route

use of okhttp3.Route in project okhttp by square.

the class StreamAllocation method streamFailed.

public void streamFailed(IOException e) {
    Socket socket;
    boolean noNewStreams = false;
    synchronized (connectionPool) {
        if (e instanceof StreamResetException) {
            StreamResetException streamResetException = (StreamResetException) e;
            if (streamResetException.errorCode == ErrorCode.REFUSED_STREAM) {
                refusedStreamCount++;
            }
            // other errors must be retried on a new connection.
            if (streamResetException.errorCode != ErrorCode.REFUSED_STREAM || refusedStreamCount > 1) {
                noNewStreams = true;
                route = null;
            }
        } else if (connection != null && (!connection.isMultiplexed() || e instanceof ConnectionShutdownException)) {
            noNewStreams = true;
            // If this route hasn't completed a call, avoid it for new connections.
            if (connection.successCount == 0) {
                if (route != null && e != null) {
                    routeSelector.connectFailed(route, e);
                }
                route = null;
            }
        }
        socket = deallocate(noNewStreams, false, true);
    }
    closeQuietly(socket);
}
Also used : ConnectionShutdownException(okhttp3.internal.http2.ConnectionShutdownException) StreamResetException(okhttp3.internal.http2.StreamResetException) Socket(java.net.Socket)

Aggregations

Route (okhttp3.Route)7 Test (org.junit.Test)7 IOException (java.io.IOException)4 InetSocketAddress (java.net.InetSocketAddress)4 MockResponse (okhttp3.mockwebserver.MockResponse)4 RecordedRequest (okhttp3.mockwebserver.RecordedRequest)4 Proxy (java.net.Proxy)3 Request (okhttp3.Request)3 Response (okhttp3.Response)3 InetAddress (java.net.InetAddress)2 ProtocolException (java.net.ProtocolException)2 Socket (java.net.Socket)2 SocketAddress (java.net.SocketAddress)2 NoSuchElementException (java.util.NoSuchElementException)2 Address (okhttp3.Address)2 HttpUrl (okhttp3.HttpUrl)2 RecordingProxySelector (okhttp3.internal.http.RecordingProxySelector)2 ConnectionShutdownException (okhttp3.internal.http2.ConnectionShutdownException)2 InterruptedIOException (java.io.InterruptedIOException)1 HttpRetryException (java.net.HttpRetryException)1