1/* 2 * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package sun.net.www.protocol.https; 27 28import java.net.URL; 29import java.net.Proxy; 30import java.net.SecureCacheResponse; 31import java.security.Principal; 32import java.io.IOException; 33import java.util.List; 34import javax.net.ssl.SSLPeerUnverifiedException; 35import sun.net.www.http.*; 36import sun.net.www.protocol.http.HttpURLConnection; 37 38/** 39 * HTTPS URL connection support. 40 * We need this delegate because HttpsURLConnection is a subclass of 41 * java.net.HttpURLConnection. We will avoid copying over the code from 42 * sun.net.www.protocol.http.HttpURLConnection by having this class 43 * 44 */ 45public abstract class AbstractDelegateHttpsURLConnection extends 46 HttpURLConnection { 47 48 protected AbstractDelegateHttpsURLConnection(URL url, 49 sun.net.www.protocol.http.Handler handler) throws IOException { 50 this(url, null, handler); 51 } 52 53 protected AbstractDelegateHttpsURLConnection(URL url, Proxy p, 54 sun.net.www.protocol.http.Handler handler) throws IOException { 55 super(url, p, handler); 56 } 57 58 protected abstract javax.net.ssl.SSLSocketFactory getSSLSocketFactory(); 59 60 protected abstract javax.net.ssl.HostnameVerifier getHostnameVerifier(); 61 62 /** 63 * No user application is able to call these routines, as no one 64 * should ever get access to an instance of 65 * DelegateHttpsURLConnection (sun.* or com.*) 66 */ 67 68 /** 69 * Create a new HttpClient object, bypassing the cache of 70 * HTTP client objects/connections. 71 * 72 * Note: this method is changed from protected to public because 73 * the com.sun.ssl.internal.www.protocol.https handler reuses this 74 * class for its actual implemantation 75 * 76 * @param url the URL being accessed 77 */ 78 public void setNewClient (URL url) 79 throws IOException { 80 setNewClient (url, false); 81 } 82 83 /** 84 * Obtain a HttpClient object. Use the cached copy if specified. 85 * 86 * Note: this method is changed from protected to public because 87 * the com.sun.ssl.internal.www.protocol.https handler reuses this 88 * class for its actual implemantation 89 * 90 * @param url the URL being accessed 91 * @param useCache whether the cached connection should be used 92 * if present 93 */ 94 public void setNewClient (URL url, boolean useCache) 95 throws IOException { 96 http = HttpsClient.New (getSSLSocketFactory(), 97 url, 98 getHostnameVerifier(), 99 useCache, this); 100 ((HttpsClient)http).afterConnect(); 101 } 102 103 /** 104 * Create a new HttpClient object, set up so that it uses 105 * per-instance proxying to the given HTTP proxy. This 106 * bypasses the cache of HTTP client objects/connections. 107 * 108 * Note: this method is changed from protected to public because 109 * the com.sun.ssl.internal.www.protocol.https handler reuses this 110 * class for its actual implemantation 111 * 112 * @param url the URL being accessed 113 * @param proxyHost the proxy host to use 114 * @param proxyPort the proxy port to use 115 */ 116 public void setProxiedClient (URL url, String proxyHost, int proxyPort) 117 throws IOException { 118 setProxiedClient(url, proxyHost, proxyPort, false); 119 } 120 121 /** 122 * Obtain a HttpClient object, set up so that it uses per-instance 123 * proxying to the given HTTP proxy. Use the cached copy of HTTP 124 * client objects/connections if specified. 125 * 126 * Note: this method is changed from protected to public because 127 * the com.sun.ssl.internal.www.protocol.https handler reuses this 128 * class for its actual implemantation 129 * 130 * @param url the URL being accessed 131 * @param proxyHost the proxy host to use 132 * @param proxyPort the proxy port to use 133 * @param useCache whether the cached connection should be used 134 * if present 135 */ 136 public void setProxiedClient (URL url, String proxyHost, int proxyPort, 137 boolean useCache) throws IOException { 138 proxiedConnect(url, proxyHost, proxyPort, useCache); 139 if (!http.isCachedConnection()) { 140 doTunneling(); 141 } 142 ((HttpsClient)http).afterConnect(); 143 } 144 145 protected void proxiedConnect(URL url, String proxyHost, int proxyPort, 146 boolean useCache) throws IOException { 147 if (connected) 148 return; 149 http = HttpsClient.New (getSSLSocketFactory(), 150 url, 151 getHostnameVerifier(), 152 proxyHost, proxyPort, useCache, this); 153 connected = true; 154 } 155 156 /** 157 * Used by subclass to access "connected" variable. 158 */ 159 public boolean isConnected() { 160 return connected; 161 } 162 163 /** 164 * Used by subclass to access "connected" variable. 165 */ 166 public void setConnected(boolean conn) { 167 connected = conn; 168 } 169 170 /** 171 * Implements the HTTP protocol handler's "connect" method, 172 * establishing an SSL connection to the server as necessary. 173 */ 174 public void connect() throws IOException { 175 if (connected) 176 return; 177 plainConnect(); 178 if (cachedResponse != null) { 179 // using cached response 180 return; 181 } 182 if (!http.isCachedConnection() && http.needsTunneling()) { 183 doTunneling(); 184 } 185 ((HttpsClient)http).afterConnect(); 186 } 187 188 // will try to use cached HttpsClient 189 protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout) 190 throws IOException { 191 return HttpsClient.New(getSSLSocketFactory(), url, 192 getHostnameVerifier(), p, true, connectTimeout, 193 this); 194 } 195 196 // will open new connection 197 protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout, 198 boolean useCache) 199 throws IOException { 200 return HttpsClient.New(getSSLSocketFactory(), url, 201 getHostnameVerifier(), p, 202 useCache, connectTimeout, this); 203 } 204 205 /** 206 * Returns the cipher suite in use on this connection. 207 */ 208 public String getCipherSuite () { 209 if (cachedResponse != null) { 210 return ((SecureCacheResponse)cachedResponse).getCipherSuite(); 211 } 212 if (http == null) { 213 throw new IllegalStateException("connection not yet open"); 214 } else { 215 return ((HttpsClient)http).getCipherSuite (); 216 } 217 } 218 219 /** 220 * Returns the certificate chain the client sent to the 221 * server, or null if the client did not authenticate. 222 */ 223 public java.security.cert.Certificate[] getLocalCertificates() { 224 if (cachedResponse != null) { 225 List<java.security.cert.Certificate> l = ((SecureCacheResponse)cachedResponse).getLocalCertificateChain(); 226 if (l == null) { 227 return null; 228 } else { 229 return l.toArray(new java.security.cert.Certificate[0]); 230 } 231 } 232 if (http == null) { 233 throw new IllegalStateException("connection not yet open"); 234 } else { 235 return (((HttpsClient)http).getLocalCertificates ()); 236 } 237 } 238 239 /** 240 * Returns the server's certificate chain, or throws 241 * SSLPeerUnverified Exception if 242 * the server did not authenticate. 243 */ 244 public java.security.cert.Certificate[] getServerCertificates() 245 throws SSLPeerUnverifiedException { 246 if (cachedResponse != null) { 247 List<java.security.cert.Certificate> l = 248 ((SecureCacheResponse)cachedResponse) 249 .getServerCertificateChain(); 250 if (l == null) { 251 return null; 252 } else { 253 return l.toArray(new java.security.cert.Certificate[0]); 254 } 255 } 256 257 if (http == null) { 258 throw new IllegalStateException("connection not yet open"); 259 } else { 260 return (((HttpsClient)http).getServerCertificates ()); 261 } 262 } 263 264 /** 265 * Returns the server's principal, or throws SSLPeerUnverifiedException 266 * if the server did not authenticate. 267 */ 268 Principal getPeerPrincipal() 269 throws SSLPeerUnverifiedException 270 { 271 if (cachedResponse != null) { 272 return ((SecureCacheResponse)cachedResponse).getPeerPrincipal(); 273 } 274 275 if (http == null) { 276 throw new IllegalStateException("connection not yet open"); 277 } else { 278 return (((HttpsClient)http).getPeerPrincipal()); 279 } 280 } 281 282 /** 283 * Returns the principal the client sent to the 284 * server, or null if the client did not authenticate. 285 */ 286 Principal getLocalPrincipal() 287 { 288 if (cachedResponse != null) { 289 return ((SecureCacheResponse)cachedResponse).getLocalPrincipal(); 290 } 291 292 if (http == null) { 293 throw new IllegalStateException("connection not yet open"); 294 } else { 295 return (((HttpsClient)http).getLocalPrincipal()); 296 } 297 } 298 299} 300