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 }