Home | History | Annotate | Download | only in http
      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 package com.squareup.okhttp.internal.http;
     18 
     19 import com.squareup.okhttp.OkHttpClient;
     20 import java.io.IOException;
     21 import java.io.InputStream;
     22 import java.io.OutputStream;
     23 import java.net.HttpURLConnection;
     24 import java.net.ProtocolException;
     25 import java.net.SecureCacheResponse;
     26 import java.net.URL;
     27 import java.security.Permission;
     28 import java.security.Principal;
     29 import java.security.cert.Certificate;
     30 import java.util.List;
     31 import java.util.Map;
     32 import javax.net.ssl.HostnameVerifier;
     33 import javax.net.ssl.HttpsURLConnection;
     34 import javax.net.ssl.SSLPeerUnverifiedException;
     35 import javax.net.ssl.SSLSocket;
     36 import javax.net.ssl.SSLSocketFactory;
     37 
     38 public final class HttpsURLConnectionImpl extends HttpsURLConnection {
     39 
     40   /** HttpUrlConnectionDelegate allows reuse of HttpURLConnectionImpl. */
     41   private final HttpUrlConnectionDelegate delegate;
     42 
     43   public HttpsURLConnectionImpl(URL url, OkHttpClient client) {
     44     super(url);
     45     delegate = new HttpUrlConnectionDelegate(url, client);
     46   }
     47 
     48   @Override public String getCipherSuite() {
     49     SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
     50     if (cacheResponse != null) {
     51       return cacheResponse.getCipherSuite();
     52     }
     53     SSLSocket sslSocket = getSslSocket();
     54     if (sslSocket != null) {
     55       return sslSocket.getSession().getCipherSuite();
     56     }
     57     return null;
     58   }
     59 
     60   @Override public Certificate[] getLocalCertificates() {
     61     SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
     62     if (cacheResponse != null) {
     63       List<Certificate> result = cacheResponse.getLocalCertificateChain();
     64       return result != null ? result.toArray(new Certificate[result.size()]) : null;
     65     }
     66     SSLSocket sslSocket = getSslSocket();
     67     if (sslSocket != null) {
     68       return sslSocket.getSession().getLocalCertificates();
     69     }
     70     return null;
     71   }
     72 
     73   @Override public Certificate[] getServerCertificates() throws SSLPeerUnverifiedException {
     74     SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
     75     if (cacheResponse != null) {
     76       List<Certificate> result = cacheResponse.getServerCertificateChain();
     77       return result != null ? result.toArray(new Certificate[result.size()]) : null;
     78     }
     79     SSLSocket sslSocket = getSslSocket();
     80     if (sslSocket != null) {
     81       return sslSocket.getSession().getPeerCertificates();
     82     }
     83     return null;
     84   }
     85 
     86   @Override public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
     87     SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
     88     if (cacheResponse != null) {
     89       return cacheResponse.getPeerPrincipal();
     90     }
     91     SSLSocket sslSocket = getSslSocket();
     92     if (sslSocket != null) {
     93       return sslSocket.getSession().getPeerPrincipal();
     94     }
     95     return null;
     96   }
     97 
     98   @Override public Principal getLocalPrincipal() {
     99     SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
    100     if (cacheResponse != null) {
    101       return cacheResponse.getLocalPrincipal();
    102     }
    103     SSLSocket sslSocket = getSslSocket();
    104     if (sslSocket != null) {
    105       return sslSocket.getSession().getLocalPrincipal();
    106     }
    107     return null;
    108   }
    109 
    110   public HttpEngine getHttpEngine() {
    111     return delegate.getHttpEngine();
    112   }
    113 
    114   private SSLSocket getSslSocket() {
    115     if (delegate.httpEngine == null || !delegate.httpEngine.connected) {
    116       throw new IllegalStateException("Connection has not yet been established");
    117     }
    118     return delegate.httpEngine instanceof HttpsEngine
    119         ? ((HttpsEngine) delegate.httpEngine).getSslSocket()
    120         : null; // Not HTTPS! Probably an https:// to http:// redirect.
    121   }
    122 
    123   @Override public void disconnect() {
    124     delegate.disconnect();
    125   }
    126 
    127   @Override public InputStream getErrorStream() {
    128     return delegate.getErrorStream();
    129   }
    130 
    131   @Override public String getRequestMethod() {
    132     return delegate.getRequestMethod();
    133   }
    134 
    135   @Override public int getResponseCode() throws IOException {
    136     return delegate.getResponseCode();
    137   }
    138 
    139   @Override public String getResponseMessage() throws IOException {
    140     return delegate.getResponseMessage();
    141   }
    142 
    143   @Override public void setRequestMethod(String method) throws ProtocolException {
    144     delegate.setRequestMethod(method);
    145   }
    146 
    147   @Override public boolean usingProxy() {
    148     return delegate.usingProxy();
    149   }
    150 
    151   @Override public boolean getInstanceFollowRedirects() {
    152     return delegate.getInstanceFollowRedirects();
    153   }
    154 
    155   @Override public void setInstanceFollowRedirects(boolean followRedirects) {
    156     delegate.setInstanceFollowRedirects(followRedirects);
    157   }
    158 
    159   @Override public void connect() throws IOException {
    160     connected = true;
    161     delegate.connect();
    162   }
    163 
    164   @Override public boolean getAllowUserInteraction() {
    165     return delegate.getAllowUserInteraction();
    166   }
    167 
    168   @Override public Object getContent() throws IOException {
    169     return delegate.getContent();
    170   }
    171 
    172   @SuppressWarnings("unchecked") // Spec does not generify
    173   @Override public Object getContent(Class[] types) throws IOException {
    174     return delegate.getContent(types);
    175   }
    176 
    177   @Override public String getContentEncoding() {
    178     return delegate.getContentEncoding();
    179   }
    180 
    181   @Override public int getContentLength() {
    182     return delegate.getContentLength();
    183   }
    184 
    185   @Override public String getContentType() {
    186     return delegate.getContentType();
    187   }
    188 
    189   @Override public long getDate() {
    190     return delegate.getDate();
    191   }
    192 
    193   @Override public boolean getDefaultUseCaches() {
    194     return delegate.getDefaultUseCaches();
    195   }
    196 
    197   @Override public boolean getDoInput() {
    198     return delegate.getDoInput();
    199   }
    200 
    201   @Override public boolean getDoOutput() {
    202     return delegate.getDoOutput();
    203   }
    204 
    205   @Override public long getExpiration() {
    206     return delegate.getExpiration();
    207   }
    208 
    209   @Override public String getHeaderField(int pos) {
    210     return delegate.getHeaderField(pos);
    211   }
    212 
    213   @Override public Map<String, List<String>> getHeaderFields() {
    214     return delegate.getHeaderFields();
    215   }
    216 
    217   @Override public Map<String, List<String>> getRequestProperties() {
    218     return delegate.getRequestProperties();
    219   }
    220 
    221   @Override public void addRequestProperty(String field, String newValue) {
    222     delegate.addRequestProperty(field, newValue);
    223   }
    224 
    225   @Override public String getHeaderField(String key) {
    226     return delegate.getHeaderField(key);
    227   }
    228 
    229   @Override public long getHeaderFieldDate(String field, long defaultValue) {
    230     return delegate.getHeaderFieldDate(field, defaultValue);
    231   }
    232 
    233   @Override public int getHeaderFieldInt(String field, int defaultValue) {
    234     return delegate.getHeaderFieldInt(field, defaultValue);
    235   }
    236 
    237   @Override public String getHeaderFieldKey(int position) {
    238     return delegate.getHeaderFieldKey(position);
    239   }
    240 
    241   @Override public long getIfModifiedSince() {
    242     return delegate.getIfModifiedSince();
    243   }
    244 
    245   @Override public InputStream getInputStream() throws IOException {
    246     return delegate.getInputStream();
    247   }
    248 
    249   @Override public long getLastModified() {
    250     return delegate.getLastModified();
    251   }
    252 
    253   @Override public OutputStream getOutputStream() throws IOException {
    254     return delegate.getOutputStream();
    255   }
    256 
    257   @Override public Permission getPermission() throws IOException {
    258     return delegate.getPermission();
    259   }
    260 
    261   @Override public String getRequestProperty(String field) {
    262     return delegate.getRequestProperty(field);
    263   }
    264 
    265   @Override public URL getURL() {
    266     return delegate.getURL();
    267   }
    268 
    269   @Override public boolean getUseCaches() {
    270     return delegate.getUseCaches();
    271   }
    272 
    273   @Override public void setAllowUserInteraction(boolean newValue) {
    274     delegate.setAllowUserInteraction(newValue);
    275   }
    276 
    277   @Override public void setDefaultUseCaches(boolean newValue) {
    278     delegate.setDefaultUseCaches(newValue);
    279   }
    280 
    281   @Override public void setDoInput(boolean newValue) {
    282     delegate.setDoInput(newValue);
    283   }
    284 
    285   @Override public void setDoOutput(boolean newValue) {
    286     delegate.setDoOutput(newValue);
    287   }
    288 
    289   @Override public void setIfModifiedSince(long newValue) {
    290     delegate.setIfModifiedSince(newValue);
    291   }
    292 
    293   @Override public void setRequestProperty(String field, String newValue) {
    294     delegate.setRequestProperty(field, newValue);
    295   }
    296 
    297   @Override public void setUseCaches(boolean newValue) {
    298     delegate.setUseCaches(newValue);
    299   }
    300 
    301   @Override public void setConnectTimeout(int timeoutMillis) {
    302     delegate.setConnectTimeout(timeoutMillis);
    303   }
    304 
    305   @Override public int getConnectTimeout() {
    306     return delegate.getConnectTimeout();
    307   }
    308 
    309   @Override public void setReadTimeout(int timeoutMillis) {
    310     delegate.setReadTimeout(timeoutMillis);
    311   }
    312 
    313   @Override public int getReadTimeout() {
    314     return delegate.getReadTimeout();
    315   }
    316 
    317   @Override public String toString() {
    318     return delegate.toString();
    319   }
    320 
    321   @Override public void setFixedLengthStreamingMode(int contentLength) {
    322     delegate.setFixedLengthStreamingMode(contentLength);
    323   }
    324 
    325   @Override public void setChunkedStreamingMode(int chunkLength) {
    326     delegate.setChunkedStreamingMode(chunkLength);
    327   }
    328 
    329   @Override public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
    330     delegate.client.setHostnameVerifier(hostnameVerifier);
    331   }
    332 
    333   @Override public HostnameVerifier getHostnameVerifier() {
    334     return delegate.client.getHostnameVerifier();
    335   }
    336 
    337   @Override public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
    338     delegate.client.setSslSocketFactory(sslSocketFactory);
    339   }
    340 
    341   @Override public SSLSocketFactory getSSLSocketFactory() {
    342     return delegate.client.getSslSocketFactory();
    343   }
    344 
    345   private final class HttpUrlConnectionDelegate extends HttpURLConnectionImpl {
    346     private HttpUrlConnectionDelegate(URL url, OkHttpClient client) {
    347       super(url, client);
    348     }
    349 
    350     @Override public HttpURLConnection getHttpConnectionToCache() {
    351       return HttpsURLConnectionImpl.this;
    352     }
    353 
    354     public SecureCacheResponse getSecureCacheResponse() {
    355       return httpEngine instanceof HttpsEngine
    356           ? (SecureCacheResponse) httpEngine.getCacheResponse()
    357           : null;
    358     }
    359   }
    360 }
    361