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