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