1 /* 2 * Copyright (c) 2001, 2008, 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 26 /* 27 * NOTE: This class lives in the package sun.net.www.protocol.https. 28 * There is a copy in com.sun.net.ssl.internal.www.protocol.https for JSSE 29 * 1.0.2 compatibility. It is 100% identical except the package and extends 30 * lines. Any changes should be made to be class in sun.net.* and then copied 31 * to com.sun.net.*. 32 */ 33 34 // For both copies of the file, uncomment one line and comment the other 35 package sun.net.www.protocol.https; 36 // package com.sun.net.ssl.internal.www.protocol.https; 37 38 import java.net.URL; 39 import java.net.Proxy; 40 import java.net.ProtocolException; 41 import java.io.*; 42 import javax.net.ssl.*; 43 import java.security.Permission; 44 import java.security.Principal; 45 import java.util.Map; 46 import java.util.List; 47 import sun.net.www.http.HttpClient; 48 49 /** 50 * A class to represent an HTTP connection to a remote object. 51 * 52 * Ideally, this class should subclass and inherit the http handler 53 * implementation, but it can't do so because that class have the 54 * wrong Java Type. Thus it uses the delegate (aka, the 55 * Adapter/Wrapper design pattern) to reuse code from the http 56 * handler. 57 * 58 * Since it would use a delegate to access 59 * sun.net.www.protocol.http.HttpURLConnection functionalities, it 60 * needs to implement all public methods in it's super class and all 61 * the way to Object. 62 * 63 */ 64 65 // For both copies of the file, uncomment one line and comment the 66 // other. The differences between the two copies are introduced for 67 // plugin, and it is marked as such. 68 public class HttpsURLConnectionImpl 69 extends javax.net.ssl.HttpsURLConnection { 70 // public class HttpsURLConnectionOldImpl 71 // extends com.sun.net.ssl.HttpsURLConnection { 72 73 // NOTE: made protected for plugin so that subclass can set it. 74 protected DelegateHttpsURLConnection delegate; 75 76 // For both copies of the file, uncomment one line and comment the other HttpsURLConnectionImpl(URL u, Handler handler)77 HttpsURLConnectionImpl(URL u, Handler handler) throws IOException { 78 // HttpsURLConnectionOldImpl(URL u, Handler handler) throws IOException { 79 this(u, null, handler); 80 } 81 82 // For both copies of the file, uncomment one line and comment the other HttpsURLConnectionImpl(URL u, Proxy p, Handler handler)83 HttpsURLConnectionImpl(URL u, Proxy p, Handler handler) throws IOException { 84 // HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException { 85 super(u); 86 delegate = new DelegateHttpsURLConnection(url, p, handler, this); 87 } 88 89 // NOTE: introduced for plugin 90 // subclass needs to overwrite this to set delegate to 91 // the appropriate delegatee HttpsURLConnectionImpl(URL u)92 protected HttpsURLConnectionImpl(URL u) throws IOException { 93 super(u); 94 } 95 96 /** 97 * Create a new HttpClient object, bypassing the cache of 98 * HTTP client objects/connections. 99 * 100 * @param url the URL being accessed 101 */ setNewClient(URL url)102 protected void setNewClient(URL url) throws IOException { 103 delegate.setNewClient(url, false); 104 } 105 106 /** 107 * Obtain a HttpClient object. Use the cached copy if specified. 108 * 109 * @param url the URL being accessed 110 * @param useCache whether the cached connection should be used 111 * if present 112 */ setNewClient(URL url, boolean useCache)113 protected void setNewClient(URL url, boolean useCache) 114 throws IOException { 115 delegate.setNewClient(url, useCache); 116 } 117 118 /** 119 * Create a new HttpClient object, set up so that it uses 120 * per-instance proxying to the given HTTP proxy. This 121 * bypasses the cache of HTTP client objects/connections. 122 * 123 * @param url the URL being accessed 124 * @param proxyHost the proxy host to use 125 * @param proxyPort the proxy port to use 126 */ setProxiedClient(URL url, String proxyHost, int proxyPort)127 protected void setProxiedClient(URL url, String proxyHost, int proxyPort) 128 throws IOException { 129 delegate.setProxiedClient(url, proxyHost, proxyPort); 130 } 131 132 /** 133 * Obtain a HttpClient object, set up so that it uses per-instance 134 * proxying to the given HTTP proxy. Use the cached copy of HTTP 135 * client objects/connections if specified. 136 * 137 * @param url the URL being accessed 138 * @param proxyHost the proxy host to use 139 * @param proxyPort the proxy port to use 140 * @param useCache whether the cached connection should be used 141 * if present 142 */ setProxiedClient(URL url, String proxyHost, int proxyPort, boolean useCache)143 protected void setProxiedClient(URL url, String proxyHost, int proxyPort, 144 boolean useCache) throws IOException { 145 delegate.setProxiedClient(url, proxyHost, proxyPort, useCache); 146 } 147 148 /** 149 * Implements the HTTP protocol handler's "connect" method, 150 * establishing an SSL connection to the server as necessary. 151 */ connect()152 public void connect() throws IOException { 153 delegate.connect(); 154 } 155 156 /** 157 * Used by subclass to access "connected" variable. Since we are 158 * delegating the actual implementation to "delegate", we need to 159 * delegate the access of "connected" as well. 160 */ isConnected()161 protected boolean isConnected() { 162 return delegate.isConnected(); 163 } 164 165 /** 166 * Used by subclass to access "connected" variable. Since we are 167 * delegating the actual implementation to "delegate", we need to 168 * delegate the access of "connected" as well. 169 */ setConnected(boolean conn)170 protected void setConnected(boolean conn) { 171 delegate.setConnected(conn); 172 } 173 174 /** 175 * Returns the cipher suite in use on this connection. 176 */ getCipherSuite()177 public String getCipherSuite() { 178 return delegate.getCipherSuite(); 179 } 180 181 /** 182 * Returns the certificate chain the client sent to the 183 * server, or null if the client did not authenticate. 184 */ 185 public java.security.cert.Certificate [] getLocalCertificates()186 getLocalCertificates() { 187 return delegate.getLocalCertificates(); 188 } 189 190 /** 191 * Returns the server's certificate chain, or throws 192 * SSLPeerUnverified Exception if 193 * the server did not authenticate. 194 */ 195 public java.security.cert.Certificate [] getServerCertificates()196 getServerCertificates() throws SSLPeerUnverifiedException { 197 return delegate.getServerCertificates(); 198 } 199 200 /** 201 * Returns the server's X.509 certificate chain, or null if 202 * the server did not authenticate. 203 * 204 * NOTE: This method is not necessary for the version of this class 205 * implementing javax.net.ssl.HttpsURLConnection, but provided for 206 * compatibility with the com.sun.net.ssl.HttpsURLConnection version. 207 */ getServerCertificateChain()208 public javax.security.cert.X509Certificate[] getServerCertificateChain() { 209 try { 210 return delegate.getServerCertificateChain(); 211 } catch (SSLPeerUnverifiedException e) { 212 // this method does not throw an exception as declared in 213 // com.sun.net.ssl.HttpsURLConnection. 214 // Return null for compatibility. 215 return null; 216 } 217 } 218 219 /** 220 * Returns the principal with which the server authenticated itself, 221 * or throw a SSLPeerUnverifiedException if the server did not authenticate. 222 */ getPeerPrincipal()223 public Principal getPeerPrincipal() 224 throws SSLPeerUnverifiedException 225 { 226 return delegate.getPeerPrincipal(); 227 } 228 229 /** 230 * Returns the principal the client sent to the 231 * server, or null if the client did not authenticate. 232 */ getLocalPrincipal()233 public Principal getLocalPrincipal() 234 { 235 return delegate.getLocalPrincipal(); 236 } 237 238 /* 239 * Allowable input/output sequences: 240 * [interpreted as POST/PUT] 241 * - get output, [write output,] get input, [read input] 242 * - get output, [write output] 243 * [interpreted as GET] 244 * - get input, [read input] 245 * Disallowed: 246 * - get input, [read input,] get output, [write output] 247 */ 248 getOutputStream()249 public synchronized OutputStream getOutputStream() throws IOException { 250 return delegate.getOutputStream(); 251 } 252 getInputStream()253 public synchronized InputStream getInputStream() throws IOException { 254 return delegate.getInputStream(); 255 } 256 getErrorStream()257 public InputStream getErrorStream() { 258 return delegate.getErrorStream(); 259 } 260 261 /** 262 * Disconnect from the server. 263 */ disconnect()264 public void disconnect() { 265 delegate.disconnect(); 266 } 267 usingProxy()268 public boolean usingProxy() { 269 return delegate.usingProxy(); 270 } 271 272 /** 273 * Returns an unmodifiable Map of the header fields. 274 * The Map keys are Strings that represent the 275 * response-header field names. Each Map value is an 276 * unmodifiable List of Strings that represents 277 * the corresponding field values. 278 * 279 * @return a Map of header fields 280 * @since 1.4 281 */ getHeaderFields()282 public Map<String,List<String>> getHeaderFields() { 283 return delegate.getHeaderFields(); 284 } 285 286 /** 287 * Gets a header field by name. Returns null if not known. 288 * @param name the name of the header field 289 */ getHeaderField(String name)290 public String getHeaderField(String name) { 291 return delegate.getHeaderField(name); 292 } 293 294 /** 295 * Gets a header field by index. Returns null if not known. 296 * @param n the index of the header field 297 */ getHeaderField(int n)298 public String getHeaderField(int n) { 299 return delegate.getHeaderField(n); 300 } 301 302 /** 303 * Gets a header field by index. Returns null if not known. 304 * @param n the index of the header field 305 */ getHeaderFieldKey(int n)306 public String getHeaderFieldKey(int n) { 307 return delegate.getHeaderFieldKey(n); 308 } 309 310 /** 311 * Sets request property. If a property with the key already 312 * exists, overwrite its value with the new value. 313 * @param value the value to be set 314 */ setRequestProperty(String key, String value)315 public void setRequestProperty(String key, String value) { 316 delegate.setRequestProperty(key, value); 317 } 318 319 /** 320 * Adds a general request property specified by a 321 * key-value pair. This method will not overwrite 322 * existing values associated with the same key. 323 * 324 * @param key the keyword by which the request is known 325 * (e.g., "<code>accept</code>"). 326 * @param value the value associated with it. 327 * @see #getRequestProperties(java.lang.String) 328 * @since 1.4 329 */ addRequestProperty(String key, String value)330 public void addRequestProperty(String key, String value) { 331 delegate.addRequestProperty(key, value); 332 } 333 334 /** 335 * Overwrite super class method 336 */ getResponseCode()337 public int getResponseCode() throws IOException { 338 return delegate.getResponseCode(); 339 } 340 getRequestProperty(String key)341 public String getRequestProperty(String key) { 342 return delegate.getRequestProperty(key); 343 } 344 345 /** 346 * Returns an unmodifiable Map of general request 347 * properties for this connection. The Map keys 348 * are Strings that represent the request-header 349 * field names. Each Map value is a unmodifiable List 350 * of Strings that represents the corresponding 351 * field values. 352 * 353 * @return a Map of the general request properties for this connection. 354 * @throws IllegalStateException if already connected 355 * @since 1.4 356 */ getRequestProperties()357 public Map<String,List<String>> getRequestProperties() { 358 return delegate.getRequestProperties(); 359 } 360 361 /* 362 * We support JDK 1.2.x so we can't count on these from JDK 1.3. 363 * We override and supply our own version. 364 */ setInstanceFollowRedirects(boolean shouldFollow)365 public void setInstanceFollowRedirects(boolean shouldFollow) { 366 delegate.setInstanceFollowRedirects(shouldFollow); 367 } 368 getInstanceFollowRedirects()369 public boolean getInstanceFollowRedirects() { 370 return delegate.getInstanceFollowRedirects(); 371 } 372 setRequestMethod(String method)373 public void setRequestMethod(String method) throws ProtocolException { 374 delegate.setRequestMethod(method); 375 } 376 getRequestMethod()377 public String getRequestMethod() { 378 return delegate.getRequestMethod(); 379 } 380 getResponseMessage()381 public String getResponseMessage() throws IOException { 382 return delegate.getResponseMessage(); 383 } 384 getHeaderFieldDate(String name, long Default)385 public long getHeaderFieldDate(String name, long Default) { 386 return delegate.getHeaderFieldDate(name, Default); 387 } 388 getPermission()389 public Permission getPermission() throws IOException { 390 return delegate.getPermission(); 391 } 392 getURL()393 public URL getURL() { 394 return delegate.getURL(); 395 } 396 getContentLength()397 public int getContentLength() { 398 return delegate.getContentLength(); 399 } 400 getContentLengthLong()401 public long getContentLengthLong() { 402 return delegate.getContentLengthLong(); 403 } 404 getContentType()405 public String getContentType() { 406 return delegate.getContentType(); 407 } 408 getContentEncoding()409 public String getContentEncoding() { 410 return delegate.getContentEncoding(); 411 } 412 getExpiration()413 public long getExpiration() { 414 return delegate.getExpiration(); 415 } 416 getDate()417 public long getDate() { 418 return delegate.getDate(); 419 } 420 getLastModified()421 public long getLastModified() { 422 return delegate.getLastModified(); 423 } 424 getHeaderFieldInt(String name, int Default)425 public int getHeaderFieldInt(String name, int Default) { 426 return delegate.getHeaderFieldInt(name, Default); 427 } 428 getHeaderFieldLong(String name, long Default)429 public long getHeaderFieldLong(String name, long Default) { 430 return delegate.getHeaderFieldLong(name, Default); 431 } 432 getContent()433 public Object getContent() throws IOException { 434 return delegate.getContent(); 435 } 436 getContent(Class[] classes)437 public Object getContent(Class[] classes) throws IOException { 438 return delegate.getContent(classes); 439 } 440 toString()441 public String toString() { 442 return delegate.toString(); 443 } 444 setDoInput(boolean doinput)445 public void setDoInput(boolean doinput) { 446 delegate.setDoInput(doinput); 447 } 448 getDoInput()449 public boolean getDoInput() { 450 return delegate.getDoInput(); 451 } 452 setDoOutput(boolean dooutput)453 public void setDoOutput(boolean dooutput) { 454 delegate.setDoOutput(dooutput); 455 } 456 getDoOutput()457 public boolean getDoOutput() { 458 return delegate.getDoOutput(); 459 } 460 setAllowUserInteraction(boolean allowuserinteraction)461 public void setAllowUserInteraction(boolean allowuserinteraction) { 462 delegate.setAllowUserInteraction(allowuserinteraction); 463 } 464 getAllowUserInteraction()465 public boolean getAllowUserInteraction() { 466 return delegate.getAllowUserInteraction(); 467 } 468 setUseCaches(boolean usecaches)469 public void setUseCaches(boolean usecaches) { 470 delegate.setUseCaches(usecaches); 471 } 472 getUseCaches()473 public boolean getUseCaches() { 474 return delegate.getUseCaches(); 475 } 476 setIfModifiedSince(long ifmodifiedsince)477 public void setIfModifiedSince(long ifmodifiedsince) { 478 delegate.setIfModifiedSince(ifmodifiedsince); 479 } 480 getIfModifiedSince()481 public long getIfModifiedSince() { 482 return delegate.getIfModifiedSince(); 483 } 484 getDefaultUseCaches()485 public boolean getDefaultUseCaches() { 486 return delegate.getDefaultUseCaches(); 487 } 488 setDefaultUseCaches(boolean defaultusecaches)489 public void setDefaultUseCaches(boolean defaultusecaches) { 490 delegate.setDefaultUseCaches(defaultusecaches); 491 } 492 493 /* 494 * finalize (dispose) the delegated object. Otherwise 495 * sun.net.www.protocol.http.HttpURLConnection's finalize() 496 * would have to be made public. 497 */ finalize()498 protected void finalize() throws Throwable { 499 delegate.dispose(); 500 } 501 equals(Object obj)502 public boolean equals(Object obj) { 503 return delegate.equals(obj); 504 } 505 hashCode()506 public int hashCode() { 507 return delegate.hashCode(); 508 } 509 setConnectTimeout(int timeout)510 public void setConnectTimeout(int timeout) { 511 delegate.setConnectTimeout(timeout); 512 } 513 getConnectTimeout()514 public int getConnectTimeout() { 515 return delegate.getConnectTimeout(); 516 } 517 setReadTimeout(int timeout)518 public void setReadTimeout(int timeout) { 519 delegate.setReadTimeout(timeout); 520 } 521 getReadTimeout()522 public int getReadTimeout() { 523 return delegate.getReadTimeout(); 524 } 525 setFixedLengthStreamingMode(int contentLength)526 public void setFixedLengthStreamingMode (int contentLength) { 527 delegate.setFixedLengthStreamingMode(contentLength); 528 } 529 setFixedLengthStreamingMode(long contentLength)530 public void setFixedLengthStreamingMode(long contentLength) { 531 delegate.setFixedLengthStreamingMode(contentLength); 532 } 533 setChunkedStreamingMode(int chunklen)534 public void setChunkedStreamingMode (int chunklen) { 535 delegate.setChunkedStreamingMode(chunklen); 536 } 537 } 538