Home | History | Annotate | Download | only in okhttp
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package com.squareup.okhttp;
     19 
     20 import java.net.Proxy;
     21 import java.util.Arrays;
     22 import java.util.List;
     23 
     24 import javax.net.ssl.HttpsURLConnection;
     25 
     26 public final class HttpsHandler extends HttpHandler {
     27 
     28     /**
     29      * The initial connection spec to use when connecting to an https:// server, and the prototype
     30      * for the others below. Note that Android does not set the cipher suites to use so the socket's
     31      * defaults enabled cipher suites will be used instead. When the SSLSocketFactory is provided by
     32      * the app or GMS core we will not override the enabled ciphers set on the sockets it produces
     33      * with a list hardcoded at release time. This is deliberate.
     34      * For the TLS versions we <em>will</em> select a known subset from the set of enabled TLS
     35      * versions on the socket.
     36      */
     37     private static final ConnectionSpec TLS_1_2_AND_BELOW = new ConnectionSpec.Builder(true)
     38         .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0, TlsVersion.SSL_3_0)
     39         .supportsTlsExtensions(true)
     40         .build();
     41 
     42     private static final ConnectionSpec TLS_1_1_AND_BELOW =
     43         new ConnectionSpec.Builder(TLS_1_2_AND_BELOW)
     44             .tlsVersions(TlsVersion.TLS_1_1, TlsVersion.TLS_1_0, TlsVersion.SSL_3_0)
     45             .supportsTlsExtensions(true)
     46             .build();
     47 
     48     private static final ConnectionSpec TLS_1_0_AND_BELOW =
     49         new ConnectionSpec.Builder(TLS_1_2_AND_BELOW)
     50             .tlsVersions(TlsVersion.TLS_1_0, TlsVersion.SSL_3_0)
     51             .build();
     52 
     53     private static final ConnectionSpec SSL_3_0 =
     54         new ConnectionSpec.Builder(TLS_1_2_AND_BELOW)
     55             .tlsVersions(TlsVersion.SSL_3_0)
     56             .build();
     57 
     58     /** Try up to 4 times to negotiate a connection with each server. */
     59     private static final List<ConnectionSpec> SECURE_CONNECTION_SPECS =
     60         Arrays.asList(TLS_1_2_AND_BELOW, TLS_1_1_AND_BELOW, TLS_1_0_AND_BELOW, SSL_3_0);
     61 
     62     private static final List<Protocol> HTTP_1_1_ONLY = Arrays.asList(Protocol.HTTP_1_1);
     63 
     64     private final ConfigAwareConnectionPool configAwareConnectionPool =
     65             ConfigAwareConnectionPool.getInstance();
     66 
     67     @Override protected int getDefaultPort() {
     68         return 443;
     69     }
     70 
     71     @Override
     72     protected OkUrlFactory newOkUrlFactory(Proxy proxy) {
     73         OkUrlFactory okUrlFactory = createHttpsOkUrlFactory(proxy);
     74         // For HttpsURLConnections created through java.net.URL Android uses a connection pool that
     75         // is aware when the default network changes so that pooled connections are not re-used when
     76         // the default network changes.
     77         okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get());
     78         return okUrlFactory;
     79     }
     80 
     81     /**
     82      * Creates an OkHttpClient suitable for creating {@link HttpsURLConnection} instances on
     83      * Android.
     84      */
     85     // Visible for android.net.Network.
     86     public static OkUrlFactory createHttpsOkUrlFactory(Proxy proxy) {
     87         // The HTTPS OkHttpClient is an HTTP OkHttpClient with extra configuration.
     88         OkUrlFactory okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxy);
     89 
     90         OkHttpClient okHttpClient = okUrlFactory.client();
     91 
     92         // Only enable HTTP/1.1 (implies HTTP/1.0). Disable SPDY / HTTP/2.0.
     93         okHttpClient.setProtocols(HTTP_1_1_ONLY);
     94 
     95         // Use Android's preferred fallback approach and cipher suite selection.
     96         okHttpClient.setConnectionSpecs(SECURE_CONNECTION_SPECS);
     97 
     98         // OkHttp does not automatically honor the system-wide HostnameVerifier set with
     99         // HttpsURLConnection.setDefaultHostnameVerifier().
    100         okUrlFactory.client().setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());
    101         // OkHttp does not automatically honor the system-wide SSLSocketFactory set with
    102         // HttpsURLConnection.setDefaultSSLSocketFactory().
    103         // See https://github.com/square/okhttp/issues/184 for details.
    104         okHttpClient.setSslSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
    105 
    106         return okUrlFactory;
    107     }
    108 }
    109