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