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 }