Search in sources :

Example 1 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class CallServerInterceptor method intercept.

@Override
public Response intercept(Chain chain) throws IOException {
    HttpCodec httpCodec = ((RealInterceptorChain) chain).httpStream();
    StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
    Request request = chain.request();
    long sentRequestMillis = System.currentTimeMillis();
    httpCodec.writeRequestHeaders(request);
    Response.Builder responseBuilder = null;
    if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
        // we did get (such as a 4xx response) without ever transmitting the request body.
        if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
            httpCodec.flushRequest();
            responseBuilder = httpCodec.readResponseHeaders(true);
        }
        // Write the request body, unless an "Expect: 100-continue" expectation failed.
        if (responseBuilder == null) {
            Sink requestBodyOut = httpCodec.createRequestBody(request, request.body().contentLength());
            BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
            request.body().writeTo(bufferedRequestBody);
            bufferedRequestBody.close();
        }
    }
    httpCodec.finishRequest();
    if (responseBuilder == null) {
        responseBuilder = httpCodec.readResponseHeaders(false);
    }
    Response response = responseBuilder.request(request).handshake(streamAllocation.connection().handshake()).sentRequestAtMillis(sentRequestMillis).receivedResponseAtMillis(System.currentTimeMillis()).build();
    int code = response.code();
    if (forWebSocket && code == 101) {
        // Connection is upgrading, but we need to ensure interceptors see a non-null response body.
        response = response.newBuilder().body(Util.EMPTY_RESPONSE).build();
    } else {
        response = response.newBuilder().body(httpCodec.openResponseBody(response)).build();
    }
    if ("close".equalsIgnoreCase(response.request().header("Connection")) || "close".equalsIgnoreCase(response.header("Connection"))) {
        streamAllocation.noNewStreams();
    }
    if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
        throw new ProtocolException("HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
    }
    return response;
}
Also used : StreamAllocation(okhttp3.internal.connection.StreamAllocation) Response(okhttp3.Response) ProtocolException(java.net.ProtocolException) BufferedSink(okio.BufferedSink) Sink(okio.Sink) Request(okhttp3.Request) BufferedSink(okio.BufferedSink)

Example 2 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class RealConnection method connect.

public void connect(int connectTimeout, int readTimeout, int writeTimeout, boolean connectionRetryEnabled) {
    if (protocol != null)
        throw new IllegalStateException("already connected");
    RouteException routeException = null;
    List<ConnectionSpec> connectionSpecs = route.address().connectionSpecs();
    ConnectionSpecSelector connectionSpecSelector = new ConnectionSpecSelector(connectionSpecs);
    if (route.address().sslSocketFactory() == null) {
        if (!connectionSpecs.contains(ConnectionSpec.CLEARTEXT)) {
            throw new RouteException(new UnknownServiceException("CLEARTEXT communication not enabled for client"));
        }
        String host = route.address().url().host();
        if (!Platform.get().isCleartextTrafficPermitted(host)) {
            throw new RouteException(new UnknownServiceException("CLEARTEXT communication to " + host + " not permitted by network security policy"));
        }
    }
    while (true) {
        try {
            if (route.requiresTunnel()) {
                connectTunnel(connectTimeout, readTimeout, writeTimeout);
            } else {
                connectSocket(connectTimeout, readTimeout);
            }
            establishProtocol(connectionSpecSelector);
            break;
        } catch (IOException e) {
            closeQuietly(socket);
            closeQuietly(rawSocket);
            socket = null;
            rawSocket = null;
            source = null;
            sink = null;
            handshake = null;
            protocol = null;
            http2Connection = null;
            if (routeException == null) {
                routeException = new RouteException(e);
            } else {
                routeException.addConnectException(e);
            }
            if (!connectionRetryEnabled || !connectionSpecSelector.connectionFailed(e)) {
                throw routeException;
            }
        }
    }
    if (http2Connection != null) {
        synchronized (connectionPool) {
            allocationLimit = http2Connection.maxConcurrentStreams();
        }
    }
}
Also used : ConnectionSpec(okhttp3.ConnectionSpec) UnknownServiceException(java.net.UnknownServiceException) IOException(java.io.IOException)

Example 3 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class RealConnection method connectTls.

private void connectTls(ConnectionSpecSelector connectionSpecSelector) throws IOException {
    Address address = route.address();
    SSLSocketFactory sslSocketFactory = address.sslSocketFactory();
    boolean success = false;
    SSLSocket sslSocket = null;
    try {
        // Create the wrapper over the connected socket.
        sslSocket = (SSLSocket) sslSocketFactory.createSocket(rawSocket, address.url().host(), address.url().port(), true);
        // Configure the socket's ciphers, TLS versions, and extensions.
        ConnectionSpec connectionSpec = connectionSpecSelector.configureSecureSocket(sslSocket);
        if (connectionSpec.supportsTlsExtensions()) {
            Platform.get().configureTlsExtensions(sslSocket, address.url().host(), address.protocols());
        }
        // Force handshake. This can throw!
        sslSocket.startHandshake();
        Handshake unverifiedHandshake = Handshake.get(sslSocket.getSession());
        // Verify that the socket's certificates are acceptable for the target host.
        if (!address.hostnameVerifier().verify(address.url().host(), sslSocket.getSession())) {
            X509Certificate cert = (X509Certificate) unverifiedHandshake.peerCertificates().get(0);
            throw new SSLPeerUnverifiedException("Hostname " + address.url().host() + " not verified:" + "\n    certificate: " + CertificatePinner.pin(cert) + "\n    DN: " + cert.getSubjectDN().getName() + "\n    subjectAltNames: " + OkHostnameVerifier.allSubjectAltNames(cert));
        }
        // Check that the certificate pinner is satisfied by the certificates presented.
        address.certificatePinner().check(address.url().host(), unverifiedHandshake.peerCertificates());
        // Success! Save the handshake and the ALPN protocol.
        String maybeProtocol = connectionSpec.supportsTlsExtensions() ? Platform.get().getSelectedProtocol(sslSocket) : null;
        socket = sslSocket;
        source = Okio.buffer(Okio.source(socket));
        sink = Okio.buffer(Okio.sink(socket));
        handshake = unverifiedHandshake;
        protocol = maybeProtocol != null ? Protocol.get(maybeProtocol) : Protocol.HTTP_1_1;
        success = true;
    } catch (AssertionError e) {
        if (Util.isAndroidGetsocknameError(e))
            throw new IOException(e);
        throw e;
    } finally {
        if (sslSocket != null) {
            Platform.get().afterHandshake(sslSocket);
        }
        if (!success) {
            closeQuietly(sslSocket);
        }
    }
}
Also used : Address(okhttp3.Address) ConnectionSpec(okhttp3.ConnectionSpec) SSLSocket(javax.net.ssl.SSLSocket) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) IOException(java.io.IOException) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) X509Certificate(java.security.cert.X509Certificate) Handshake(okhttp3.Handshake)

Example 4 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class StreamAllocation method findConnection.

/**
   * Returns a connection to host a new stream. This prefers the existing connection if it exists,
   * then the pool, finally building a new connection.
   */
private RealConnection findConnection(int connectTimeout, int readTimeout, int writeTimeout, boolean connectionRetryEnabled) throws IOException {
    Route selectedRoute;
    synchronized (connectionPool) {
        if (released)
            throw new IllegalStateException("released");
        if (codec != null)
            throw new IllegalStateException("codec != null");
        if (canceled)
            throw new IOException("Canceled");
        // Attempt to use an already-allocated connection.
        RealConnection allocatedConnection = this.connection;
        if (allocatedConnection != null && !allocatedConnection.noNewStreams) {
            return allocatedConnection;
        }
        // Attempt to get a connection from the pool.
        Internal.instance.get(connectionPool, address, this, null);
        if (connection != null) {
            return connection;
        }
        selectedRoute = route;
    }
    // If we need a route, make one. This is a blocking operation.
    if (selectedRoute == null) {
        selectedRoute = routeSelector.next();
    }
    RealConnection result;
    synchronized (connectionPool) {
        if (canceled)
            throw new IOException("Canceled");
        // Now that we have an IP address, make another attempt at getting a connection from the pool.
        // This could match due to connection coalescing.
        Internal.instance.get(connectionPool, address, this, selectedRoute);
        if (connection != null)
            return connection;
        // Create a connection and assign it to this allocation immediately. This makes it possible
        // for an asynchronous cancel() to interrupt the handshake we're about to do.
        route = selectedRoute;
        refusedStreamCount = 0;
        result = new RealConnection(connectionPool, selectedRoute);
        acquire(result);
    }
    // Do TCP + TLS handshakes. This is a blocking operation.
    result.connect(connectTimeout, readTimeout, writeTimeout, connectionRetryEnabled);
    routeDatabase().connected(result.route());
    Socket socket = null;
    synchronized (connectionPool) {
        // Pool the connection.
        Internal.instance.put(connectionPool, result);
        // release this connection and acquire that one.
        if (result.isMultiplexed()) {
            socket = Internal.instance.deduplicate(connectionPool, address, this);
            result = connection;
        }
    }
    closeQuietly(socket);
    return result;
}
Also used : IOException(java.io.IOException) Route(okhttp3.Route) Socket(java.net.Socket)

Example 5 with Handshake

use of okhttp3.Handshake in project okhttp by square.

the class JavaApiConverterTest method createJavaCacheResponse_httpsPost.

@Test
public void createJavaCacheResponse_httpsPost() throws Exception {
    Request okRequest = createArbitraryOkRequest().newBuilder().url("https://secure/request").post(createRequestBody("RequestBody")).build();
    ResponseBody responseBody = createResponseBody("ResponseBody");
    Handshake handshake = Handshake.get(null, CipherSuite.TLS_RSA_WITH_NULL_MD5, Arrays.<Certificate>asList(SERVER_CERT), Arrays.<Certificate>asList(LOCAL_CERT));
    Response okResponse = createArbitraryOkResponse(okRequest).newBuilder().protocol(Protocol.HTTP_1_1).code(200).message("Fantastic").addHeader("key1", "value1_1").addHeader("key2", "value2").addHeader("key1", "value1_2").body(responseBody).handshake(handshake).build();
    SecureCacheResponse javaCacheResponse = (SecureCacheResponse) JavaApiConverter.createJavaCacheResponse(okResponse);
    Map<String, List<String>> javaHeaders = javaCacheResponse.getHeaders();
    assertEquals(Arrays.asList("value1_1", "value1_2"), javaHeaders.get("key1"));
    assertEquals(Arrays.asList("HTTP/1.1 200 Fantastic"), javaHeaders.get(null));
    assertEquals("ResponseBody", readAll(javaCacheResponse.getBody()));
    assertEquals(handshake.cipherSuite().javaName(), javaCacheResponse.getCipherSuite());
    assertEquals(handshake.localCertificates(), javaCacheResponse.getLocalCertificateChain());
    assertEquals(handshake.peerCertificates(), javaCacheResponse.getServerCertificateChain());
    assertEquals(handshake.localPrincipal(), javaCacheResponse.getLocalPrincipal());
    assertEquals(handshake.peerPrincipal(), javaCacheResponse.getPeerPrincipal());
}
Also used : CacheResponse(java.net.CacheResponse) Response(okhttp3.Response) SecureCacheResponse(java.net.SecureCacheResponse) SecureCacheResponse(java.net.SecureCacheResponse) Request(okhttp3.Request) List(java.util.List) ResponseBody(okhttp3.ResponseBody) Handshake(okhttp3.Handshake) Test(org.junit.Test)

Aggregations

Handshake (okhttp3.Handshake)13 Request (okhttp3.Request)12 Response (okhttp3.Response)11 Test (org.junit.jupiter.api.Test)9 Certificate (java.security.cert.Certificate)7 HttpsURLConnection (javax.net.ssl.HttpsURLConnection)7 RecordingHostnameVerifier (okhttp3.RecordingHostnameVerifier)7 HandshakeCertificates (okhttp3.tls.HandshakeCertificates)7 CacheResponse (java.net.CacheResponse)6 SecureCacheResponse (java.net.SecureCacheResponse)6 SSLPeerUnverifiedException (javax.net.ssl.SSLPeerUnverifiedException)5 MockResponse (mockwebserver3.MockResponse)5 HeldCertificate (okhttp3.tls.HeldCertificate)5 Test (org.junit.Test)5 BufferedReader (java.io.BufferedReader)4 IOException (java.io.IOException)4 InputStreamReader (java.io.InputStreamReader)4 Headers (okhttp3.Headers)4 HttpUrl (okhttp3.HttpUrl)4 ResponseBody (okhttp3.ResponseBody)4