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