1 /*
   2  * Copyright (c) 1995, 2016, 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 java.net;
  27 
  28 import java.io.IOException;
  29 import java.io.InputStream;
  30 import java.io.OutputStream;
  31 import java.security.PrivilegedAction;
  32 import java.util.Hashtable;
  33 import java.util.concurrent.ConcurrentHashMap;
  34 import java.util.Date;
  35 import java.util.Iterator;
  36 import java.util.Locale;
  37 import java.util.Objects;
  38 import java.util.ServiceConfigurationError;
  39 import java.util.ServiceLoader;
  40 import java.util.StringTokenizer;
  41 import java.util.Collections;
  42 import java.util.Map;
  43 import java.util.List;
  44 import java.security.Permission;
  45 import java.security.AccessController;
  46 import sun.security.util.SecurityConstants;
  47 import sun.net.www.MessageHeader;
  48 import sun.security.action.GetPropertyAction;
  49 
  50 /**
  51  * The abstract class {@code URLConnection} is the superclass
  52  * of all classes that represent a communications link between the
  53  * application and a URL. Instances of this class can be used both to
  54  * read from and to write to the resource referenced by the URL. In
  55  * general, creating a connection to a URL is a multistep process:
  56  *
  57  * <div style="text-align:center"><table class="plain" style="margin:0 auto">
  58  * <caption style="display:none">Describes the process of creating a connection to a URL: openConnection() and connect() over time.</caption>
  59  * <thead>
  60  * <tr><th>{@code openConnection()}</th>
  61  *     <th>{@code connect()}</th></tr>
  62  * </thead>
  63  * <tbody>
  64  * <tr><td>Manipulate parameters that affect the connection to the remote
  65  *         resource.</td>
  66  *     <td>Interact with the resource; query header fields and
  67  *         contents.</td></tr>
  68  * </tbody>
  69  * </table>
  70  * ----------------------------&gt;
  71  * <br>time</div>
  72  *
  73  * <ol>
  74  * <li>The connection object is created by invoking the
  75  *     {@code openConnection} method on a URL.
  76  * <li>The setup parameters and general request properties are manipulated.
  77  * <li>The actual connection to the remote object is made, using the
  78  *    {@code connect} method.
  79  * <li>The remote object becomes available. The header fields and the contents
  80  *     of the remote object can be accessed.
  81  * </ol>
  82  * <p>
  83  * The setup parameters are modified using the following methods:
  84  * <ul>
  85  *   <li>{@code setAllowUserInteraction}
  86  *   <li>{@code setDoInput}
  87  *   <li>{@code setDoOutput}
  88  *   <li>{@code setIfModifiedSince}
  89  *   <li>{@code setUseCaches}
  90  * </ul>
  91  * <p>
  92  * and the general request properties are modified using the method:
  93  * <ul>
  94  *   <li>{@code setRequestProperty}
  95  * </ul>
  96  * <p>
  97  * Default values for the {@code AllowUserInteraction} and
  98  * {@code UseCaches} parameters can be set using the methods
  99  * {@code setDefaultAllowUserInteraction} and
 100  * {@code setDefaultUseCaches}.
 101  * <p>
 102  * Each of the above {@code set} methods has a corresponding
 103  * {@code get} method to retrieve the value of the parameter or
 104  * general request property. The specific parameters and general
 105  * request properties that are applicable are protocol specific.
 106  * <p>
 107  * The following methods are used to access the header fields and
 108  * the contents after the connection is made to the remote object:
 109  * <ul>
 110  *   <li>{@code getContent}
 111  *   <li>{@code getHeaderField}
 112  *   <li>{@code getInputStream}
 113  *   <li>{@code getOutputStream}
 114  * </ul>
 115  * <p>
 116  * Certain header fields are accessed frequently. The methods:
 117  * <ul>
 118  *   <li>{@code getContentEncoding}
 119  *   <li>{@code getContentLength}
 120  *   <li>{@code getContentType}
 121  *   <li>{@code getDate}
 122  *   <li>{@code getExpiration}
 123  *   <li>{@code getLastModified}
 124  * </ul>
 125  * <p>
 126  * provide convenient access to these fields. The
 127  * {@code getContentType} method is used by the
 128  * {@code getContent} method to determine the type of the remote
 129  * object; subclasses may find it convenient to override the
 130  * {@code getContentType} method.
 131  * <p>
 132  * In the common case, all of the pre-connection parameters and
 133  * general request properties can be ignored: the pre-connection
 134  * parameters and request properties default to sensible values. For
 135  * most clients of this interface, there are only two interesting
 136  * methods: {@code getInputStream} and {@code getContent},
 137  * which are mirrored in the {@code URL} class by convenience methods.
 138  * <p>
 139  * More information on the request properties and header fields of
 140  * an {@code http} connection can be found at:
 141  * <blockquote><pre>
 142  * <a href="http://www.ietf.org/rfc/rfc2616.txt">http://www.ietf.org/rfc/rfc2616.txt</a>
 143  * </pre></blockquote>
 144  *
 145  * Invoking the {@code close()} methods on the {@code InputStream} or {@code OutputStream} of an
 146  * {@code URLConnection} after a request may free network resources associated with this
 147  * instance, unless particular protocol specifications specify different behaviours
 148  * for it.
 149  *
 150  * @author  James Gosling
 151  * @see     java.net.URL#openConnection()
 152  * @see     java.net.URLConnection#connect()
 153  * @see     java.net.URLConnection#getContent()
 154  * @see     java.net.URLConnection#getContentEncoding()
 155  * @see     java.net.URLConnection#getContentLength()
 156  * @see     java.net.URLConnection#getContentType()
 157  * @see     java.net.URLConnection#getDate()
 158  * @see     java.net.URLConnection#getExpiration()
 159  * @see     java.net.URLConnection#getHeaderField(int)
 160  * @see     java.net.URLConnection#getHeaderField(java.lang.String)
 161  * @see     java.net.URLConnection#getInputStream()
 162  * @see     java.net.URLConnection#getLastModified()
 163  * @see     java.net.URLConnection#getOutputStream()
 164  * @see     java.net.URLConnection#setAllowUserInteraction(boolean)
 165  * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
 166  * @see     java.net.URLConnection#setDoInput(boolean)
 167  * @see     java.net.URLConnection#setDoOutput(boolean)
 168  * @see     java.net.URLConnection#setIfModifiedSince(long)
 169  * @see     java.net.URLConnection#setRequestProperty(java.lang.String, java.lang.String)
 170  * @see     java.net.URLConnection#setUseCaches(boolean)
 171  * @since   1.0
 172  */
 173 public abstract class URLConnection {
 174 
 175    /**
 176      * The URL represents the remote object on the World Wide Web to
 177      * which this connection is opened.
 178      * <p>
 179      * The value of this field can be accessed by the
 180      * {@code getURL} method.
 181      * <p>
 182      * The default value of this variable is the value of the URL
 183      * argument in the {@code URLConnection} constructor.
 184      *
 185      * @see     java.net.URLConnection#getURL()
 186      * @see     java.net.URLConnection#url
 187      */
 188     protected URL url;
 189 
 190    /**
 191      * This variable is set by the {@code setDoInput} method. Its
 192      * value is returned by the {@code getDoInput} method.
 193      * <p>
 194      * A URL connection can be used for input and/or output. Setting the
 195      * {@code doInput} flag to {@code true} indicates that
 196      * the application intends to read data from the URL connection.
 197      * <p>
 198      * The default value of this field is {@code true}.
 199      *
 200      * @see     java.net.URLConnection#getDoInput()
 201      * @see     java.net.URLConnection#setDoInput(boolean)
 202      */
 203     protected boolean doInput = true;
 204 
 205    /**
 206      * This variable is set by the {@code setDoOutput} method. Its
 207      * value is returned by the {@code getDoOutput} method.
 208      * <p>
 209      * A URL connection can be used for input and/or output. Setting the
 210      * {@code doOutput} flag to {@code true} indicates
 211      * that the application intends to write data to the URL connection.
 212      * <p>
 213      * The default value of this field is {@code false}.
 214      *
 215      * @see     java.net.URLConnection#getDoOutput()
 216      * @see     java.net.URLConnection#setDoOutput(boolean)
 217      */
 218     protected boolean doOutput = false;
 219 
 220     private static boolean defaultAllowUserInteraction = false;
 221 
 222    /**
 223      * If {@code true}, this {@code URL} is being examined in
 224      * a context in which it makes sense to allow user interactions such
 225      * as popping up an authentication dialog. If {@code false},
 226      * then no user interaction is allowed.
 227      * <p>
 228      * The value of this field can be set by the
 229      * {@code setAllowUserInteraction} method.
 230      * Its value is returned by the
 231      * {@code getAllowUserInteraction} method.
 232      * Its default value is the value of the argument in the last invocation
 233      * of the {@code setDefaultAllowUserInteraction} method.
 234      *
 235      * @see     java.net.URLConnection#getAllowUserInteraction()
 236      * @see     java.net.URLConnection#setAllowUserInteraction(boolean)
 237      * @see     java.net.URLConnection#setDefaultAllowUserInteraction(boolean)
 238      */
 239     protected boolean allowUserInteraction = defaultAllowUserInteraction;
 240 
 241     private static volatile boolean defaultUseCaches = true;
 242 
 243    /**
 244      * If {@code true}, the protocol is allowed to use caching
 245      * whenever it can. If {@code false}, the protocol must always
 246      * try to get a fresh copy of the object.
 247      * <p>
 248      * This field is set by the {@code setUseCaches} method. Its
 249      * value is returned by the {@code getUseCaches} method.
 250      * <p>
 251      * Its default value is the value given in the last invocation of the
 252      * {@code setDefaultUseCaches} method.
 253      * <p>
 254      * The default setting may be overridden per protocol with
 255      * {@link #setDefaultUseCaches(String,boolean)}.
 256      *
 257      * @see     java.net.URLConnection#setUseCaches(boolean)
 258      * @see     java.net.URLConnection#getUseCaches()
 259      * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
 260      */
 261     protected boolean useCaches;
 262 
 263     private static final ConcurrentHashMap<String,Boolean> defaultCaching =
 264         new ConcurrentHashMap<>();
 265 
 266    /**
 267      * Some protocols support skipping the fetching of the object unless
 268      * the object has been modified more recently than a certain time.
 269      * <p>
 270      * A nonzero value gives a time as the number of milliseconds since
 271      * January 1, 1970, GMT. The object is fetched only if it has been
 272      * modified more recently than that time.
 273      * <p>
 274      * This variable is set by the {@code setIfModifiedSince}
 275      * method. Its value is returned by the
 276      * {@code getIfModifiedSince} method.
 277      * <p>
 278      * The default value of this field is {@code 0}, indicating
 279      * that the fetching must always occur.
 280      *
 281      * @see     java.net.URLConnection#getIfModifiedSince()
 282      * @see     java.net.URLConnection#setIfModifiedSince(long)
 283      */
 284     protected long ifModifiedSince = 0;
 285 
 286    /**
 287      * If {@code false}, this connection object has not created a
 288      * communications link to the specified URL. If {@code true},
 289      * the communications link has been established.
 290      */
 291     protected boolean connected = false;
 292 
 293     /**
 294      * @since 1.5
 295      */
 296     private int connectTimeout;
 297     private int readTimeout;
 298 
 299     /**
 300      * @since 1.6
 301      */
 302     private MessageHeader requests;
 303 
 304    /**
 305     * @since   1.1
 306     */
 307     private static volatile FileNameMap fileNameMap;
 308 
 309     /**
 310      * Loads filename map (a mimetable) from a data file. It will
 311      * first try to load the user-specific table, defined
 312      * by &quot;content.types.user.table&quot; property. If that fails,
 313      * it tries to load the default built-in table.
 314      *
 315      * @return the FileNameMap
 316      * @since 1.2
 317      * @see #setFileNameMap(java.net.FileNameMap)
 318      */
 319     public static FileNameMap getFileNameMap() {
 320         FileNameMap map = fileNameMap;
 321 
 322         if (map == null) {
 323             fileNameMap = map = new FileNameMap() {
 324                 private FileNameMap internalMap =
 325                     sun.net.www.MimeTable.loadTable();
 326 
 327                 public String getContentTypeFor(String fileName) {
 328                     return internalMap.getContentTypeFor(fileName);
 329                 }
 330             };
 331         }
 332 
 333         return map;
 334     }
 335 
 336     /**
 337      * Sets the FileNameMap.
 338      * <p>
 339      * If there is a security manager, this method first calls
 340      * the security manager's {@code checkSetFactory} method
 341      * to ensure the operation is allowed.
 342      * This could result in a SecurityException.
 343      *
 344      * @param map the FileNameMap to be set
 345      * @exception  SecurityException  if a security manager exists and its
 346      *             {@code checkSetFactory} method doesn't allow the operation.
 347      * @see        SecurityManager#checkSetFactory
 348      * @see #getFileNameMap()
 349      * @since 1.2
 350      */
 351     public static void setFileNameMap(FileNameMap map) {
 352         SecurityManager sm = System.getSecurityManager();
 353         if (sm != null) sm.checkSetFactory();
 354         fileNameMap = map;
 355     }
 356 
 357     /**
 358      * Opens a communications link to the resource referenced by this
 359      * URL, if such a connection has not already been established.
 360      * <p>
 361      * If the {@code connect} method is called when the connection
 362      * has already been opened (indicated by the {@code connected}
 363      * field having the value {@code true}), the call is ignored.
 364      * <p>
 365      * URLConnection objects go through two phases: first they are
 366      * created, then they are connected.  After being created, and
 367      * before being connected, various options can be specified
 368      * (e.g., doInput and UseCaches).  After connecting, it is an
 369      * error to try to set them.  Operations that depend on being
 370      * connected, like getContentLength, will implicitly perform the
 371      * connection, if necessary.
 372      *
 373      * @throws SocketTimeoutException if the timeout expires before
 374      *               the connection can be established
 375      * @exception  IOException  if an I/O error occurs while opening the
 376      *               connection.
 377      * @see java.net.URLConnection#connected
 378      * @see #getConnectTimeout()
 379      * @see #setConnectTimeout(int)
 380      */
 381     public abstract void connect() throws IOException;
 382 
 383     /**
 384      * Sets a specified timeout value, in milliseconds, to be used
 385      * when opening a communications link to the resource referenced
 386      * by this URLConnection.  If the timeout expires before the
 387      * connection can be established, a
 388      * java.net.SocketTimeoutException is raised. A timeout of zero is
 389      * interpreted as an infinite timeout.
 390 
 391      * <p> Some non-standard implementation of this method may ignore
 392      * the specified timeout. To see the connect timeout set, please
 393      * call getConnectTimeout().
 394      *
 395      * @param timeout an {@code int} that specifies the connect
 396      *               timeout value in milliseconds
 397      * @throws IllegalArgumentException if the timeout parameter is negative
 398      *
 399      * @see #getConnectTimeout()
 400      * @see #connect()
 401      * @since 1.5
 402      */
 403     public void setConnectTimeout(int timeout) {
 404         if (timeout < 0) {
 405             throw new IllegalArgumentException("timeout can not be negative");
 406         }
 407         connectTimeout = timeout;
 408     }
 409 
 410     /**
 411      * Returns setting for connect timeout.
 412      * <p>
 413      * 0 return implies that the option is disabled
 414      * (i.e., timeout of infinity).
 415      *
 416      * @return an {@code int} that indicates the connect timeout
 417      *         value in milliseconds
 418      * @see #setConnectTimeout(int)
 419      * @see #connect()
 420      * @since 1.5
 421      */
 422     public int getConnectTimeout() {
 423         return connectTimeout;
 424     }
 425 
 426     /**
 427      * Sets the read timeout to a specified timeout, in
 428      * milliseconds. A non-zero value specifies the timeout when
 429      * reading from Input stream when a connection is established to a
 430      * resource. If the timeout expires before there is data available
 431      * for read, a java.net.SocketTimeoutException is raised. A
 432      * timeout of zero is interpreted as an infinite timeout.
 433      *
 434      *<p> Some non-standard implementation of this method ignores the
 435      * specified timeout. To see the read timeout set, please call
 436      * getReadTimeout().
 437      *
 438      * @param timeout an {@code int} that specifies the timeout
 439      * value to be used in milliseconds
 440      * @throws IllegalArgumentException if the timeout parameter is negative
 441      *
 442      * @see #getReadTimeout()
 443      * @see InputStream#read()
 444      * @since 1.5
 445      */
 446     public void setReadTimeout(int timeout) {
 447         if (timeout < 0) {
 448             throw new IllegalArgumentException("timeout can not be negative");
 449         }
 450         readTimeout = timeout;
 451     }
 452 
 453     /**
 454      * Returns setting for read timeout. 0 return implies that the
 455      * option is disabled (i.e., timeout of infinity).
 456      *
 457      * @return an {@code int} that indicates the read timeout
 458      *         value in milliseconds
 459      *
 460      * @see #setReadTimeout(int)
 461      * @see InputStream#read()
 462      * @since 1.5
 463      */
 464     public int getReadTimeout() {
 465         return readTimeout;
 466     }
 467 
 468     /**
 469      * Constructs a URL connection to the specified URL. A connection to
 470      * the object referenced by the URL is not created.
 471      *
 472      * @param   url   the specified URL.
 473      */
 474     protected URLConnection(URL url) {
 475         this.url = url;
 476         if (url == null) {
 477             this.useCaches = defaultUseCaches;
 478         } else {
 479             this.useCaches = getDefaultUseCaches(url.getProtocol());
 480         }
 481     }
 482 
 483     /**
 484      * Returns the value of this {@code URLConnection}'s {@code URL}
 485      * field.
 486      *
 487      * @return  the value of this {@code URLConnection}'s {@code URL}
 488      *          field.
 489      * @see     java.net.URLConnection#url
 490      */
 491     public URL getURL() {
 492         return url;
 493     }
 494 
 495     /**
 496      * Returns the value of the {@code content-length} header field.
 497      * <P>
 498      * <B>Note</B>: {@link #getContentLengthLong() getContentLengthLong()}
 499      * should be preferred over this method, since it returns a {@code long}
 500      * instead and is therefore more portable.</P>
 501      *
 502      * @return  the content length of the resource that this connection's URL
 503      *          references, {@code -1} if the content length is not known,
 504      *          or if the content length is greater than Integer.MAX_VALUE.
 505      */
 506     public int getContentLength() {
 507         long l = getContentLengthLong();
 508         if (l > Integer.MAX_VALUE)
 509             return -1;
 510         return (int) l;
 511     }
 512 
 513     /**
 514      * Returns the value of the {@code content-length} header field as a
 515      * long.
 516      *
 517      * @return  the content length of the resource that this connection's URL
 518      *          references, or {@code -1} if the content length is
 519      *          not known.
 520      * @since 1.7
 521      */
 522     public long getContentLengthLong() {
 523         return getHeaderFieldLong("content-length", -1);
 524     }
 525 
 526     /**
 527      * Returns the value of the {@code content-type} header field.
 528      *
 529      * @return  the content type of the resource that the URL references,
 530      *          or {@code null} if not known.
 531      * @see     java.net.URLConnection#getHeaderField(java.lang.String)
 532      */
 533     public String getContentType() {
 534         return getHeaderField("content-type");
 535     }
 536 
 537     /**
 538      * Returns the value of the {@code content-encoding} header field.
 539      *
 540      * @return  the content encoding of the resource that the URL references,
 541      *          or {@code null} if not known.
 542      * @see     java.net.URLConnection#getHeaderField(java.lang.String)
 543      */
 544     public String getContentEncoding() {
 545         return getHeaderField("content-encoding");
 546     }
 547 
 548     /**
 549      * Returns the value of the {@code expires} header field.
 550      *
 551      * @return  the expiration date of the resource that this URL references,
 552      *          or 0 if not known. The value is the number of milliseconds since
 553      *          January 1, 1970 GMT.
 554      * @see     java.net.URLConnection#getHeaderField(java.lang.String)
 555      */
 556     public long getExpiration() {
 557         return getHeaderFieldDate("expires", 0);
 558     }
 559 
 560     /**
 561      * Returns the value of the {@code date} header field.
 562      *
 563      * @return  the sending date of the resource that the URL references,
 564      *          or {@code 0} if not known. The value returned is the
 565      *          number of milliseconds since January 1, 1970 GMT.
 566      * @see     java.net.URLConnection#getHeaderField(java.lang.String)
 567      */
 568     public long getDate() {
 569         return getHeaderFieldDate("date", 0);
 570     }
 571 
 572     /**
 573      * Returns the value of the {@code last-modified} header field.
 574      * The result is the number of milliseconds since January 1, 1970 GMT.
 575      *
 576      * @return  the date the resource referenced by this
 577      *          {@code URLConnection} was last modified, or 0 if not known.
 578      * @see     java.net.URLConnection#getHeaderField(java.lang.String)
 579      */
 580     public long getLastModified() {
 581         return getHeaderFieldDate("last-modified", 0);
 582     }
 583 
 584     /**
 585      * Returns the value of the named header field.
 586      * <p>
 587      * If called on a connection that sets the same header multiple times
 588      * with possibly different values, only the last value is returned.
 589      *
 590      *
 591      * @param   name   the name of a header field.
 592      * @return  the value of the named header field, or {@code null}
 593      *          if there is no such field in the header.
 594      */
 595     public String getHeaderField(String name) {
 596         return null;
 597     }
 598 
 599     /**
 600      * Returns an unmodifiable Map of the header fields.
 601      * The Map keys are Strings that represent the
 602      * response-header field names. Each Map value is an
 603      * unmodifiable List of Strings that represents
 604      * the corresponding field values.
 605      *
 606      * @return a Map of header fields
 607      * @since 1.4
 608      */
 609     public Map<String,List<String>> getHeaderFields() {
 610         return Collections.emptyMap();
 611     }
 612 
 613     /**
 614      * Returns the value of the named field parsed as a number.
 615      * <p>
 616      * This form of {@code getHeaderField} exists because some
 617      * connection types (e.g., {@code http-ng}) have pre-parsed
 618      * headers. Classes for that connection type can override this method
 619      * and short-circuit the parsing.
 620      *
 621      * @param   name      the name of the header field.
 622      * @param   Default   the default value.
 623      * @return  the value of the named field, parsed as an integer. The
 624      *          {@code Default} value is returned if the field is
 625      *          missing or malformed.
 626      */
 627     public int getHeaderFieldInt(String name, int Default) {
 628         String value = getHeaderField(name);
 629         try {
 630             return Integer.parseInt(value);
 631         } catch (Exception e) { }
 632         return Default;
 633     }
 634 
 635     /**
 636      * Returns the value of the named field parsed as a number.
 637      * <p>
 638      * This form of {@code getHeaderField} exists because some
 639      * connection types (e.g., {@code http-ng}) have pre-parsed
 640      * headers. Classes for that connection type can override this method
 641      * and short-circuit the parsing.
 642      *
 643      * @param   name      the name of the header field.
 644      * @param   Default   the default value.
 645      * @return  the value of the named field, parsed as a long. The
 646      *          {@code Default} value is returned if the field is
 647      *          missing or malformed.
 648      * @since 1.7
 649      */
 650     public long getHeaderFieldLong(String name, long Default) {
 651         String value = getHeaderField(name);
 652         try {
 653             return Long.parseLong(value);
 654         } catch (Exception e) { }
 655         return Default;
 656     }
 657 
 658     /**
 659      * Returns the value of the named field parsed as date.
 660      * The result is the number of milliseconds since January 1, 1970 GMT
 661      * represented by the named field.
 662      * <p>
 663      * This form of {@code getHeaderField} exists because some
 664      * connection types (e.g., {@code http-ng}) have pre-parsed
 665      * headers. Classes for that connection type can override this method
 666      * and short-circuit the parsing.
 667      *
 668      * @param   name     the name of the header field.
 669      * @param   Default   a default value.
 670      * @return  the value of the field, parsed as a date. The value of the
 671      *          {@code Default} argument is returned if the field is
 672      *          missing or malformed.
 673      */
 674     @SuppressWarnings("deprecation")
 675     public long getHeaderFieldDate(String name, long Default) {
 676         String value = getHeaderField(name);
 677         try {
 678             return Date.parse(value);
 679         } catch (Exception e) { }
 680         return Default;
 681     }
 682 
 683     /**
 684      * Returns the key for the {@code n}<sup>th</sup> header field.
 685      * It returns {@code null} if there are fewer than {@code n+1} fields.
 686      *
 687      * @param   n   an index, where {@code n>=0}
 688      * @return  the key for the {@code n}<sup>th</sup> header field,
 689      *          or {@code null} if there are fewer than {@code n+1}
 690      *          fields.
 691      */
 692     public String getHeaderFieldKey(int n) {
 693         return null;
 694     }
 695 
 696     /**
 697      * Returns the value for the {@code n}<sup>th</sup> header field.
 698      * It returns {@code null} if there are fewer than
 699      * {@code n+1}fields.
 700      * <p>
 701      * This method can be used in conjunction with the
 702      * {@link #getHeaderFieldKey(int) getHeaderFieldKey} method to iterate through all
 703      * the headers in the message.
 704      *
 705      * @param   n   an index, where {@code n>=0}
 706      * @return  the value of the {@code n}<sup>th</sup> header field
 707      *          or {@code null} if there are fewer than {@code n+1} fields
 708      * @see     java.net.URLConnection#getHeaderFieldKey(int)
 709      */
 710     public String getHeaderField(int n) {
 711         return null;
 712     }
 713 
 714     /**
 715      * Retrieves the contents of this URL connection.
 716      * <p>
 717      * This method first determines the content type of the object by
 718      * calling the {@code getContentType} method. If this is
 719      * the first time that the application has seen that specific content
 720      * type, a content handler for that content type is created.
 721      * <p> This is done as follows:
 722      * <ol>
 723      * <li>If the application has set up a content handler factory instance
 724      *     using the {@code setContentHandlerFactory} method, the
 725      *     {@code createContentHandler} method of that instance is called
 726      *     with the content type as an argument; the result is a content
 727      *     handler for that content type.
 728      * <li>If no {@code ContentHandlerFactory} has yet been set up,
 729      *     or if the factory's {@code createContentHandler} method
 730      *     returns {@code null}, then the {@linkplain java.util.ServiceLoader
 731      *     ServiceLoader} mechanism is used to locate {@linkplain
 732      *     java.net.ContentHandlerFactory ContentHandlerFactory}
 733      *     implementations using the system class
 734      *     loader. The order that factories are located is implementation
 735      *     specific, and an implementation is free to cache the located
 736      *     factories. A {@linkplain java.util.ServiceConfigurationError
 737      *     ServiceConfigurationError}, {@code Error} or {@code RuntimeException}
 738      *     thrown from the {@code createContentHandler}, if encountered, will
 739      *     be propagated to the calling thread. The {@code
 740      *     createContentHandler} method of each factory, if instantiated, is
 741      *     invoked, with the content type, until a factory returns non-null,
 742      *     or all factories have been exhausted.
 743      * <li>Failing that, this method tries to load a content handler
 744      *     class as defined by {@link java.net.ContentHandler ContentHandler}.
 745      *     If the class does not exist, or is not a subclass of {@code
 746      *     ContentHandler}, then an {@code UnknownServiceException} is thrown.
 747      * </ol>
 748      *
 749      * @return     the object fetched. The {@code instanceof} operator
 750      *               should be used to determine the specific kind of object
 751      *               returned.
 752      * @exception  IOException              if an I/O error occurs while
 753      *               getting the content.
 754      * @exception  UnknownServiceException  if the protocol does not support
 755      *               the content type.
 756      * @see        java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
 757      * @see        java.net.URLConnection#getContentType()
 758      * @see        java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
 759      */
 760     public Object getContent() throws IOException {
 761         // Must call getInputStream before GetHeaderField gets called
 762         // so that FileNotFoundException has a chance to be thrown up
 763         // from here without being caught.
 764         getInputStream();
 765         return getContentHandler().getContent(this);
 766     }
 767 
 768     /**
 769      * Retrieves the contents of this URL connection.
 770      *
 771      * @param classes the {@code Class} array
 772      * indicating the requested types
 773      * @return     the object fetched that is the first match of the type
 774      *               specified in the classes array. null if none of
 775      *               the requested types are supported.
 776      *               The {@code instanceof} operator should be used to
 777      *               determine the specific kind of object returned.
 778      * @exception  IOException              if an I/O error occurs while
 779      *               getting the content.
 780      * @exception  UnknownServiceException  if the protocol does not support
 781      *               the content type.
 782      * @see        java.net.URLConnection#getContent()
 783      * @see        java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
 784      * @see        java.net.URLConnection#getContent(java.lang.Class[])
 785      * @see        java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
 786      * @since 1.3
 787      */
 788     public Object getContent(Class<?>[] classes) throws IOException {
 789         // Must call getInputStream before GetHeaderField gets called
 790         // so that FileNotFoundException has a chance to be thrown up
 791         // from here without being caught.
 792         getInputStream();
 793         return getContentHandler().getContent(this, classes);
 794     }
 795 
 796     /**
 797      * Returns a permission object representing the permission
 798      * necessary to make the connection represented by this
 799      * object. This method returns null if no permission is
 800      * required to make the connection. By default, this method
 801      * returns {@code java.security.AllPermission}. Subclasses
 802      * should override this method and return the permission
 803      * that best represents the permission required to make a
 804      * a connection to the URL. For example, a {@code URLConnection}
 805      * representing a {@code file:} URL would return a
 806      * {@code java.io.FilePermission} object.
 807      *
 808      * <p>The permission returned may dependent upon the state of the
 809      * connection. For example, the permission before connecting may be
 810      * different from that after connecting. For example, an HTTP
 811      * sever, say foo.com, may redirect the connection to a different
 812      * host, say bar.com. Before connecting the permission returned by
 813      * the connection will represent the permission needed to connect
 814      * to foo.com, while the permission returned after connecting will
 815      * be to bar.com.
 816      *
 817      * <p>Permissions are generally used for two purposes: to protect
 818      * caches of objects obtained through URLConnections, and to check
 819      * the right of a recipient to learn about a particular URL. In
 820      * the first case, the permission should be obtained
 821      * <em>after</em> the object has been obtained. For example, in an
 822      * HTTP connection, this will represent the permission to connect
 823      * to the host from which the data was ultimately fetched. In the
 824      * second case, the permission should be obtained and tested
 825      * <em>before</em> connecting.
 826      *
 827      * @return the permission object representing the permission
 828      * necessary to make the connection represented by this
 829      * URLConnection.
 830      *
 831      * @exception IOException if the computation of the permission
 832      * requires network or file I/O and an exception occurs while
 833      * computing it.
 834      */
 835     public Permission getPermission() throws IOException {
 836         return SecurityConstants.ALL_PERMISSION;
 837     }
 838 
 839     /**
 840      * Returns an input stream that reads from this open connection.
 841      *
 842      * A SocketTimeoutException can be thrown when reading from the
 843      * returned input stream if the read timeout expires before data
 844      * is available for read.
 845      *
 846      * @return     an input stream that reads from this open connection.
 847      * @exception  IOException              if an I/O error occurs while
 848      *               creating the input stream.
 849      * @exception  UnknownServiceException  if the protocol does not support
 850      *               input.
 851      * @see #setReadTimeout(int)
 852      * @see #getReadTimeout()
 853      */
 854     public InputStream getInputStream() throws IOException {
 855         throw new UnknownServiceException("protocol doesn't support input");
 856     }
 857 
 858     /**
 859      * Returns an output stream that writes to this connection.
 860      *
 861      * @return     an output stream that writes to this connection.
 862      * @exception  IOException              if an I/O error occurs while
 863      *               creating the output stream.
 864      * @exception  UnknownServiceException  if the protocol does not support
 865      *               output.
 866      */
 867     public OutputStream getOutputStream() throws IOException {
 868         throw new UnknownServiceException("protocol doesn't support output");
 869     }
 870 
 871     /**
 872      * Returns a {@code String} representation of this URL connection.
 873      *
 874      * @return  a string representation of this {@code URLConnection}.
 875      */
 876     public String toString() {
 877         return this.getClass().getName() + ":" + url;
 878     }
 879 
 880     /**
 881      * Sets the value of the {@code doInput} field for this
 882      * {@code URLConnection} to the specified value.
 883      * <p>
 884      * A URL connection can be used for input and/or output.  Set the DoInput
 885      * flag to true if you intend to use the URL connection for input,
 886      * false if not.  The default is true.
 887      *
 888      * @param   doinput   the new value.
 889      * @throws IllegalStateException if already connected
 890      * @see     java.net.URLConnection#doInput
 891      * @see #getDoInput()
 892      */
 893     public void setDoInput(boolean doinput) {
 894         checkConnected();
 895         doInput = doinput;
 896     }
 897 
 898     /**
 899      * Returns the value of this {@code URLConnection}'s
 900      * {@code doInput} flag.
 901      *
 902      * @return  the value of this {@code URLConnection}'s
 903      *          {@code doInput} flag.
 904      * @see     #setDoInput(boolean)
 905      */
 906     public boolean getDoInput() {
 907         return doInput;
 908     }
 909 
 910     /**
 911      * Sets the value of the {@code doOutput} field for this
 912      * {@code URLConnection} to the specified value.
 913      * <p>
 914      * A URL connection can be used for input and/or output.  Set the DoOutput
 915      * flag to true if you intend to use the URL connection for output,
 916      * false if not.  The default is false.
 917      *
 918      * @param   dooutput   the new value.
 919      * @throws IllegalStateException if already connected
 920      * @see #getDoOutput()
 921      */
 922     public void setDoOutput(boolean dooutput) {
 923         checkConnected();
 924         doOutput = dooutput;
 925     }
 926 
 927     /**
 928      * Returns the value of this {@code URLConnection}'s
 929      * {@code doOutput} flag.
 930      *
 931      * @return  the value of this {@code URLConnection}'s
 932      *          {@code doOutput} flag.
 933      * @see     #setDoOutput(boolean)
 934      */
 935     public boolean getDoOutput() {
 936         return doOutput;
 937     }
 938 
 939     /**
 940      * Set the value of the {@code allowUserInteraction} field of
 941      * this {@code URLConnection}.
 942      *
 943      * @param   allowuserinteraction   the new value.
 944      * @throws IllegalStateException if already connected
 945      * @see     #getAllowUserInteraction()
 946      */
 947     public void setAllowUserInteraction(boolean allowuserinteraction) {
 948         checkConnected();
 949         allowUserInteraction = allowuserinteraction;
 950     }
 951 
 952     /**
 953      * Returns the value of the {@code allowUserInteraction} field for
 954      * this object.
 955      *
 956      * @return  the value of the {@code allowUserInteraction} field for
 957      *          this object.
 958      * @see     #setAllowUserInteraction(boolean)
 959      */
 960     public boolean getAllowUserInteraction() {
 961         return allowUserInteraction;
 962     }
 963 
 964     /**
 965      * Sets the default value of the
 966      * {@code allowUserInteraction} field for all future
 967      * {@code URLConnection} objects to the specified value.
 968      *
 969      * @param   defaultallowuserinteraction   the new value.
 970      * @see     #getDefaultAllowUserInteraction()
 971      */
 972     public static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction) {
 973         defaultAllowUserInteraction = defaultallowuserinteraction;
 974     }
 975 
 976     /**
 977      * Returns the default value of the {@code allowUserInteraction}
 978      * field.
 979      * <p>
 980      * Ths default is "sticky", being a part of the static state of all
 981      * URLConnections.  This flag applies to the next, and all following
 982      * URLConnections that are created.
 983      *
 984      * @return  the default value of the {@code allowUserInteraction}
 985      *          field.
 986      * @see     #setDefaultAllowUserInteraction(boolean)
 987      */
 988     public static boolean getDefaultAllowUserInteraction() {
 989         return defaultAllowUserInteraction;
 990     }
 991 
 992     /**
 993      * Sets the value of the {@code useCaches} field of this
 994      * {@code URLConnection} to the specified value.
 995      * <p>
 996      * Some protocols do caching of documents.  Occasionally, it is important
 997      * to be able to "tunnel through" and ignore the caches (e.g., the
 998      * "reload" button in a browser).  If the UseCaches flag on a connection
 999      * is true, the connection is allowed to use whatever caches it can.
1000      *  If false, caches are to be ignored.
1001      *  The default value comes from DefaultUseCaches, which defaults to
1002      * true. A default value can also be set per-protocol using
1003      * {@link #setDefaultUseCaches(String,boolean)}.
1004      *
1005      * @param usecaches a {@code boolean} indicating whether
1006      * or not to allow caching
1007      * @throws IllegalStateException if already connected
1008      * @see #getUseCaches()
1009      */
1010     public void setUseCaches(boolean usecaches) {
1011         checkConnected();
1012         useCaches = usecaches;
1013     }
1014 
1015     /**
1016      * Returns the value of this {@code URLConnection}'s
1017      * {@code useCaches} field.
1018      *
1019      * @return  the value of this {@code URLConnection}'s
1020      *          {@code useCaches} field.
1021      * @see #setUseCaches(boolean)
1022      */
1023     public boolean getUseCaches() {
1024         return useCaches;
1025     }
1026 
1027     /**
1028      * Sets the value of the {@code ifModifiedSince} field of
1029      * this {@code URLConnection} to the specified value.
1030      *
1031      * @param   ifmodifiedsince   the new value.
1032      * @throws IllegalStateException if already connected
1033      * @see     #getIfModifiedSince()
1034      */
1035     public void setIfModifiedSince(long ifmodifiedsince) {
1036         checkConnected();
1037         ifModifiedSince = ifmodifiedsince;
1038     }
1039 
1040     /**
1041      * Returns the value of this object's {@code ifModifiedSince} field.
1042      *
1043      * @return  the value of this object's {@code ifModifiedSince} field.
1044      * @see #setIfModifiedSince(long)
1045      */
1046     public long getIfModifiedSince() {
1047         return ifModifiedSince;
1048     }
1049 
1050    /**
1051      * Returns the default value of a {@code URLConnection}'s
1052      * {@code useCaches} flag.
1053      * <p>
1054      * This default is "sticky", being a part of the static state of all
1055      * URLConnections.  This flag applies to the next, and all following
1056      * URLConnections that are created. This default value can be over-ridden
1057      * per protocol using {@link #setDefaultUseCaches(String,boolean)}
1058      *
1059      * @return  the default value of a {@code URLConnection}'s
1060      *          {@code useCaches} flag.
1061      * @see     #setDefaultUseCaches(boolean)
1062      */
1063     public boolean getDefaultUseCaches() {
1064         return defaultUseCaches;
1065     }
1066 
1067    /**
1068      * Sets the default value of the {@code useCaches} field to the
1069      * specified value. This default value can be over-ridden
1070      * per protocol using {@link #setDefaultUseCaches(String,boolean)}
1071      *
1072      * @param   defaultusecaches   the new value.
1073      * @see     #getDefaultUseCaches()
1074      */
1075     public void setDefaultUseCaches(boolean defaultusecaches) {
1076         defaultUseCaches = defaultusecaches;
1077     }
1078 
1079    /**
1080      * Sets the default value of the {@code useCaches} field for the named
1081      * protocol to the given value. This value overrides any default setting
1082      * set by {@link #setDefaultUseCaches(boolean)} for the given protocol.
1083      * Successive calls to this method change the setting and affect the
1084      * default value for all future connections of that protocol. The protocol
1085      * name is case insensitive.
1086      *
1087      * @param   protocol the protocol to set the default for
1088      * @param   defaultVal whether caching is enabled by default for the given protocol
1089      * @since 9
1090      */
1091     public static void setDefaultUseCaches(String protocol, boolean defaultVal) {
1092         protocol = protocol.toLowerCase(Locale.US);
1093         defaultCaching.put(protocol, defaultVal);
1094     }
1095 
1096    /**
1097      * Returns the default value of the {@code useCaches} flag for the given protocol. If
1098      * {@link #setDefaultUseCaches(String,boolean)} was called for the given protocol,
1099      * then that value is returned. Otherwise, if {@link #setDefaultUseCaches(boolean)}
1100      * was called, then that value is returned. If neither method was called,
1101      * the return value is {@code true}. The protocol name is case insensitive.
1102      *
1103      * @param protocol the protocol whose defaultUseCaches setting is required
1104      * @return  the default value of the {@code useCaches} flag for the given protocol.
1105      * @since 9
1106      */
1107     public static boolean getDefaultUseCaches(String protocol) {
1108         Boolean protoDefault = defaultCaching.get(protocol.toLowerCase(Locale.US));
1109         if (protoDefault != null) {
1110             return protoDefault.booleanValue();
1111         } else {
1112             return defaultUseCaches;
1113         }
1114     }
1115 
1116     /**
1117      * Sets the general request property. If a property with the key already
1118      * exists, overwrite its value with the new value.
1119      *
1120      * <p> NOTE: HTTP requires all request properties which can
1121      * legally have multiple instances with the same key
1122      * to use a comma-separated list syntax which enables multiple
1123      * properties to be appended into a single property.
1124      *
1125      * @param   key     the keyword by which the request is known
1126      *                  (e.g., "{@code Accept}").
1127      * @param   value   the value associated with it.
1128      * @throws IllegalStateException if already connected
1129      * @throws NullPointerException if key is {@code null}
1130      * @see #getRequestProperty(java.lang.String)
1131      */
1132     public void setRequestProperty(String key, String value) {
1133         checkConnected();
1134         if (key == null)
1135             throw new NullPointerException ("key is null");
1136 
1137         if (requests == null)
1138             requests = new MessageHeader();
1139 
1140         requests.set(key, value);
1141     }
1142 
1143     /**
1144      * Adds a general request property specified by a
1145      * key-value pair.  This method will not overwrite
1146      * existing values associated with the same key.
1147      *
1148      * @param   key     the keyword by which the request is known
1149      *                  (e.g., "{@code Accept}").
1150      * @param   value  the value associated with it.
1151      * @throws IllegalStateException if already connected
1152      * @throws NullPointerException if key is null
1153      * @see #getRequestProperties()
1154      * @since 1.4
1155      */
1156     public void addRequestProperty(String key, String value) {
1157         checkConnected();
1158         if (key == null)
1159             throw new NullPointerException ("key is null");
1160 
1161         if (requests == null)
1162             requests = new MessageHeader();
1163 
1164         requests.add(key, value);
1165     }
1166 
1167 
1168     /**
1169      * Returns the value of the named general request property for this
1170      * connection.
1171      *
1172      * @param key the keyword by which the request is known (e.g., "Accept").
1173      * @return  the value of the named general request property for this
1174      *           connection. If key is null, then null is returned.
1175      * @throws IllegalStateException if already connected
1176      * @see #setRequestProperty(java.lang.String, java.lang.String)
1177      */
1178     public String getRequestProperty(String key) {
1179         checkConnected();
1180 
1181         if (requests == null)
1182             return null;
1183 
1184         return requests.findValue(key);
1185     }
1186 
1187     /**
1188      * Returns an unmodifiable Map of general request
1189      * properties for this connection. The Map keys
1190      * are Strings that represent the request-header
1191      * field names. Each Map value is a unmodifiable List
1192      * of Strings that represents the corresponding
1193      * field values.
1194      *
1195      * @return  a Map of the general request properties for this connection.
1196      * @throws IllegalStateException if already connected
1197      * @since 1.4
1198      */
1199     public Map<String,List<String>> getRequestProperties() {
1200         checkConnected();
1201 
1202         if (requests == null)
1203             return Collections.emptyMap();
1204 
1205         return requests.getHeaders(null);
1206     }
1207 
1208     /**
1209      * Sets the default value of a general request property. When a
1210      * {@code URLConnection} is created, it is initialized with
1211      * these properties.
1212      *
1213      * @param   key     the keyword by which the request is known
1214      *                  (e.g., "{@code Accept}").
1215      * @param   value   the value associated with the key.
1216      *
1217      * @see java.net.URLConnection#setRequestProperty(java.lang.String,java.lang.String)
1218      *
1219      * @deprecated The instance specific setRequestProperty method
1220      * should be used after an appropriate instance of URLConnection
1221      * is obtained. Invoking this method will have no effect.
1222      *
1223      * @see #getDefaultRequestProperty(java.lang.String)
1224      */
1225     @Deprecated
1226     public static void setDefaultRequestProperty(String key, String value) {
1227     }
1228 
1229     /**
1230      * Returns the value of the default request property. Default request
1231      * properties are set for every connection.
1232      *
1233      * @param key the keyword by which the request is known (e.g., "Accept").
1234      * @return  the value of the default request property
1235      * for the specified key.
1236      *
1237      * @see java.net.URLConnection#getRequestProperty(java.lang.String)
1238      *
1239      * @deprecated The instance specific getRequestProperty method
1240      * should be used after an appropriate instance of URLConnection
1241      * is obtained.
1242      *
1243      * @see #setDefaultRequestProperty(java.lang.String, java.lang.String)
1244      */
1245     @Deprecated
1246     public static String getDefaultRequestProperty(String key) {
1247         return null;
1248     }
1249 
1250     /**
1251      * The ContentHandler factory.
1252      */
1253     private static volatile ContentHandlerFactory factory;
1254 
1255     /**
1256      * Sets the {@code ContentHandlerFactory} of an
1257      * application. It can be called at most once by an application.
1258      * <p>
1259      * The {@code ContentHandlerFactory} instance is used to
1260      * construct a content handler from a content type
1261      * <p>
1262      * If there is a security manager, this method first calls
1263      * the security manager's {@code checkSetFactory} method
1264      * to ensure the operation is allowed.
1265      * This could result in a SecurityException.
1266      *
1267      * @param      fac   the desired factory.
1268      * @exception  Error  if the factory has already been defined.
1269      * @exception  SecurityException  if a security manager exists and its
1270      *             {@code checkSetFactory} method doesn't allow the operation.
1271      * @see        java.net.ContentHandlerFactory
1272      * @see        java.net.URLConnection#getContent()
1273      * @see        SecurityManager#checkSetFactory
1274      */
1275     public static synchronized void setContentHandlerFactory(ContentHandlerFactory fac) {
1276         if (factory != null) {
1277             throw new Error("factory already defined");
1278         }
1279         SecurityManager security = System.getSecurityManager();
1280         if (security != null) {
1281             security.checkSetFactory();
1282         }
1283         factory = fac;
1284     }
1285 
1286     private static final Hashtable<String, ContentHandler> handlers = new Hashtable<>();
1287 
1288     /**
1289      * Gets the Content Handler appropriate for this connection.
1290      */
1291     private ContentHandler getContentHandler() throws UnknownServiceException {
1292         String contentType = stripOffParameters(getContentType());
1293         if (contentType == null) {
1294             throw new UnknownServiceException("no content-type");
1295         }
1296 
1297         ContentHandler handler = handlers.get(contentType);
1298         if (handler != null)
1299             return handler;
1300 
1301         if (factory != null) {
1302             handler = factory.createContentHandler(contentType);
1303             if (handler != null)
1304                 return handler;
1305         }
1306 
1307         handler = lookupContentHandlerViaProvider(contentType);
1308 
1309         if (handler != null) {
1310             ContentHandler h = handlers.putIfAbsent(contentType, handler);
1311             return Objects.requireNonNullElse(h, handler);
1312         }
1313 
1314         try {
1315             handler = lookupContentHandlerClassFor(contentType);
1316         } catch (Exception e) {
1317             e.printStackTrace();
1318             handler = UnknownContentHandler.INSTANCE;
1319         }
1320 
1321         assert handler != null;
1322 
1323         ContentHandler h = handlers.putIfAbsent(contentType, handler);
1324         return Objects.requireNonNullElse(h, handler);
1325     }
1326 
1327     /*
1328      * Media types are in the format: type/subtype*(; parameter).
1329      * For looking up the content handler, we should ignore those
1330      * parameters.
1331      */
1332     private String stripOffParameters(String contentType)
1333     {
1334         if (contentType == null)
1335             return null;
1336         int index = contentType.indexOf(';');
1337 
1338         if (index > 0)
1339             return contentType.substring(0, index);
1340         else
1341             return contentType;
1342     }
1343 
1344     private static final String contentClassPrefix = "sun.net.www.content";
1345     private static final String contentPathProp = "java.content.handler.pkgs";
1346 
1347     /**
1348      * Looks for a content handler in a user-definable set of places.
1349      * By default it looks in {@value #contentClassPrefix}, but users can define
1350      * a vertical-bar delimited set of class prefixes to search through in
1351      * addition by defining the {@value #contentPathProp} property.
1352      * The class name must be of the form:
1353      * <pre>
1354      *     {package-prefix}.{major}.{minor}
1355      * e.g.
1356      *     YoyoDyne.experimental.text.plain
1357      * </pre>
1358      */
1359     private ContentHandler lookupContentHandlerClassFor(String contentType) {
1360         String contentHandlerClassName = typeToPackageName(contentType);
1361 
1362         String contentHandlerPkgPrefixes = getContentHandlerPkgPrefixes();
1363 
1364         StringTokenizer packagePrefixIter =
1365             new StringTokenizer(contentHandlerPkgPrefixes, "|");
1366 
1367         while (packagePrefixIter.hasMoreTokens()) {
1368             String packagePrefix = packagePrefixIter.nextToken().trim();
1369 
1370             try {
1371                 String clsName = packagePrefix + "." + contentHandlerClassName;
1372                 Class<?> cls = null;
1373                 try {
1374                     cls = Class.forName(clsName);
1375                 } catch (ClassNotFoundException e) {
1376                     ClassLoader cl = ClassLoader.getSystemClassLoader();
1377                     if (cl != null) {
1378                         cls = cl.loadClass(clsName);
1379                     }
1380                 }
1381                 if (cls != null) {
1382                     @SuppressWarnings("deprecation")
1383                     Object tmp = cls.newInstance();
1384                     return (ContentHandler) tmp;
1385                 }
1386             } catch(Exception ignored) { }
1387         }
1388 
1389         return UnknownContentHandler.INSTANCE;
1390     }
1391 
1392     private ContentHandler lookupContentHandlerViaProvider(String contentType) {
1393         return AccessController.doPrivileged(
1394                 new PrivilegedAction<>() {
1395                     @Override
1396                     public ContentHandler run() {
1397                         ClassLoader cl = ClassLoader.getSystemClassLoader();
1398                         ServiceLoader<ContentHandlerFactory> sl =
1399                                 ServiceLoader.load(ContentHandlerFactory.class, cl);
1400 
1401                         Iterator<ContentHandlerFactory> iterator = sl.iterator();
1402 
1403                         ContentHandler handler = null;
1404                         while (iterator.hasNext()) {
1405                             ContentHandlerFactory f;
1406                             try {
1407                                 f = iterator.next();
1408                             } catch (ServiceConfigurationError e) {
1409                                 if (e.getCause() instanceof SecurityException) {
1410                                     continue;
1411                                 }
1412                                 throw e;
1413                             }
1414                             handler = f.createContentHandler(contentType);
1415                             if (handler != null) {
1416                                 break;
1417                             }
1418                         }
1419                         return handler;
1420                     }
1421                 });
1422     }
1423 
1424     /**
1425      * Utility function to map a MIME content type into an equivalent
1426      * pair of class name components.  For example: "text/html" would
1427      * be returned as "text.html"
1428      */
1429     private String typeToPackageName(String contentType) {
1430         // make sure we canonicalize the class name: all lower case
1431         contentType = contentType.toLowerCase();
1432         int len = contentType.length();
1433         char nm[] = new char[len];
1434         contentType.getChars(0, len, nm, 0);
1435         for (int i = 0; i < len; i++) {
1436             char c = nm[i];
1437             if (c == '/') {
1438                 nm[i] = '.';
1439             } else if (!('A' <= c && c <= 'Z' ||
1440                        'a' <= c && c <= 'z' ||
1441                        '0' <= c && c <= '9')) {
1442                 nm[i] = '_';
1443             }
1444         }
1445         return new String(nm);
1446     }
1447 
1448 
1449     /**
1450      * Returns a vertical bar separated list of package prefixes for potential
1451      * content handlers.  Tries to get the java.content.handler.pkgs property
1452      * to use as a set of package prefixes to search.  Whether or not
1453      * that property has been defined, the {@value #contentClassPrefix}
1454      * is always the last one on the returned package list.
1455      */
1456     private String getContentHandlerPkgPrefixes() {
1457         String packagePrefixList =
1458                 GetPropertyAction.privilegedGetProperty(contentPathProp, "");
1459 
1460         if (packagePrefixList != "") {
1461             packagePrefixList += "|";
1462         }
1463 
1464         return packagePrefixList + contentClassPrefix;
1465     }
1466 
1467     /**
1468      * Tries to determine the content type of an object, based
1469      * on the specified "file" component of a URL.
1470      * This is a convenience method that can be used by
1471      * subclasses that override the {@code getContentType} method.
1472      *
1473      * @param   fname   a filename.
1474      * @return  a guess as to what the content type of the object is,
1475      *          based upon its file name.
1476      * @see     java.net.URLConnection#getContentType()
1477      */
1478     public static String guessContentTypeFromName(String fname) {
1479         return getFileNameMap().getContentTypeFor(fname);
1480     }
1481 
1482     /**
1483      * Tries to determine the type of an input stream based on the
1484      * characters at the beginning of the input stream. This method can
1485      * be used by subclasses that override the
1486      * {@code getContentType} method.
1487      * <p>
1488      * Ideally, this routine would not be needed. But many
1489      * {@code http} servers return the incorrect content type; in
1490      * addition, there are many nonstandard extensions. Direct inspection
1491      * of the bytes to determine the content type is often more accurate
1492      * than believing the content type claimed by the {@code http} server.
1493      *
1494      * @param      is   an input stream that supports marks.
1495      * @return     a guess at the content type, or {@code null} if none
1496      *             can be determined.
1497      * @exception  IOException  if an I/O error occurs while reading the
1498      *               input stream.
1499      * @see        java.io.InputStream#mark(int)
1500      * @see        java.io.InputStream#markSupported()
1501      * @see        java.net.URLConnection#getContentType()
1502      */
1503     public static String guessContentTypeFromStream(InputStream is)
1504                         throws IOException {
1505         // If we can't read ahead safely, just give up on guessing
1506         if (!is.markSupported())
1507             return null;
1508 
1509         is.mark(16);
1510         int c1 = is.read();
1511         int c2 = is.read();
1512         int c3 = is.read();
1513         int c4 = is.read();
1514         int c5 = is.read();
1515         int c6 = is.read();
1516         int c7 = is.read();
1517         int c8 = is.read();
1518         int c9 = is.read();
1519         int c10 = is.read();
1520         int c11 = is.read();
1521         int c12 = is.read();
1522         int c13 = is.read();
1523         int c14 = is.read();
1524         int c15 = is.read();
1525         int c16 = is.read();
1526         is.reset();
1527 
1528         if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) {
1529             return "application/java-vm";
1530         }
1531 
1532         if (c1 == 0xAC && c2 == 0xED) {
1533             // next two bytes are version number, currently 0x00 0x05
1534             return "application/x-java-serialized-object";
1535         }
1536 
1537         if (c1 == '<') {
1538             if (c2 == '!'
1539                 || ((c2 == 'h' && (c3 == 't' && c4 == 'm' && c5 == 'l' ||
1540                                    c3 == 'e' && c4 == 'a' && c5 == 'd') ||
1541                 (c2 == 'b' && c3 == 'o' && c4 == 'd' && c5 == 'y'))) ||
1542                 ((c2 == 'H' && (c3 == 'T' && c4 == 'M' && c5 == 'L' ||
1543                                 c3 == 'E' && c4 == 'A' && c5 == 'D') ||
1544                 (c2 == 'B' && c3 == 'O' && c4 == 'D' && c5 == 'Y')))) {
1545                 return "text/html";
1546             }
1547 
1548             if (c2 == '?' && c3 == 'x' && c4 == 'm' && c5 == 'l' && c6 == ' ') {
1549                 return "application/xml";
1550             }
1551         }
1552 
1553         // big and little (identical) endian UTF-8 encodings, with BOM
1554         if (c1 == 0xef &&  c2 == 0xbb &&  c3 == 0xbf) {
1555             if (c4 == '<' &&  c5 == '?' &&  c6 == 'x') {
1556                 return "application/xml";
1557             }
1558         }
1559 
1560         // big and little endian UTF-16 encodings, with byte order mark
1561         if (c1 == 0xfe && c2 == 0xff) {
1562             if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' &&
1563                 c7 == 0 && c8 == 'x') {
1564                 return "application/xml";
1565             }
1566         }
1567 
1568         if (c1 == 0xff && c2 == 0xfe) {
1569             if (c3 == '<' && c4 == 0 && c5 == '?' && c6 == 0 &&
1570                 c7 == 'x' && c8 == 0) {
1571                 return "application/xml";
1572             }
1573         }
1574 
1575         // big and little endian UTF-32 encodings, with BOM
1576         if (c1 == 0x00 &&  c2 == 0x00 &&  c3 == 0xfe &&  c4 == 0xff) {
1577             if (c5  == 0 && c6  == 0 && c7  == 0 && c8  == '<' &&
1578                 c9  == 0 && c10 == 0 && c11 == 0 && c12 == '?' &&
1579                 c13 == 0 && c14 == 0 && c15 == 0 && c16 == 'x') {
1580                 return "application/xml";
1581             }
1582         }
1583 
1584         if (c1 == 0xff &&  c2 == 0xfe &&  c3 == 0x00 &&  c4 == 0x00) {
1585             if (c5  == '<' && c6  == 0 && c7  == 0 && c8  == 0 &&
1586                 c9  == '?' && c10 == 0 && c11 == 0 && c12 == 0 &&
1587                 c13 == 'x' && c14 == 0 && c15 == 0 && c16 == 0) {
1588                 return "application/xml";
1589             }
1590         }
1591 
1592         if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') {
1593             return "image/gif";
1594         }
1595 
1596         if (c1 == '#' && c2 == 'd' && c3 == 'e' && c4 == 'f') {
1597             return "image/x-bitmap";
1598         }
1599 
1600         if (c1 == '!' && c2 == ' ' && c3 == 'X' && c4 == 'P' &&
1601                         c5 == 'M' && c6 == '2') {
1602             return "image/x-pixmap";
1603         }
1604 
1605         if (c1 == 137 && c2 == 80 && c3 == 78 &&
1606                 c4 == 71 && c5 == 13 && c6 == 10 &&
1607                 c7 == 26 && c8 == 10) {
1608             return "image/png";
1609         }
1610 
1611         if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) {
1612             if (c4 == 0xE0 || c4 == 0xEE) {
1613                 return "image/jpeg";
1614             }
1615 
1616             /**
1617              * File format used by digital cameras to store images.
1618              * Exif Format can be read by any application supporting
1619              * JPEG. Exif Spec can be found at:
1620              * http://www.pima.net/standards/it10/PIMA15740/Exif_2-1.PDF
1621              */
1622             if ((c4 == 0xE1) &&
1623                 (c7 == 'E' && c8 == 'x' && c9 == 'i' && c10 =='f' &&
1624                  c11 == 0)) {
1625                 return "image/jpeg";
1626             }
1627         }
1628 
1629         if ((c1 == 0x49 && c2 == 0x49 && c3 == 0x2a && c4 == 0x00)
1630             || (c1 == 0x4d && c2 == 0x4d && c3 == 0x00 && c4 == 0x2a)) {
1631             return "image/tiff";
1632         }
1633 
1634         if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 &&
1635             c5 == 0xA1 && c6 == 0xB1 && c7 == 0x1A && c8 == 0xE1) {
1636 
1637             /* Above is signature of Microsoft Structured Storage.
1638              * Below this, could have tests for various SS entities.
1639              * For now, just test for FlashPix.
1640              */
1641             if (checkfpx(is)) {
1642                 return "image/vnd.fpx";
1643             }
1644         }
1645 
1646         if (c1 == 0x2E && c2 == 0x73 && c3 == 0x6E && c4 == 0x64) {
1647             return "audio/basic";  // .au format, big endian
1648         }
1649 
1650         if (c1 == 0x64 && c2 == 0x6E && c3 == 0x73 && c4 == 0x2E) {
1651             return "audio/basic";  // .au format, little endian
1652         }
1653 
1654         if (c1 == 'R' && c2 == 'I' && c3 == 'F' && c4 == 'F') {
1655             /* I don't know if this is official but evidence
1656              * suggests that .wav files start with "RIFF" - brown
1657              */
1658             return "audio/x-wav";
1659         }
1660         return null;
1661     }
1662 
1663     /**
1664      * Check for FlashPix image data in InputStream is.  Return true if
1665      * the stream has FlashPix data, false otherwise.  Before calling this
1666      * method, the stream should have already been checked to be sure it
1667      * contains Microsoft Structured Storage data.
1668      */
1669     private static boolean checkfpx(InputStream is) throws IOException {
1670 
1671         /* Test for FlashPix image data in Microsoft Structured Storage format.
1672          * In general, should do this with calls to an SS implementation.
1673          * Lacking that, need to dig via offsets to get to the FlashPix
1674          * ClassID.  Details:
1675          *
1676          * Offset to Fpx ClsID from beginning of stream should be:
1677          *
1678          * FpxClsidOffset = rootEntryOffset + clsidOffset
1679          *
1680          * where: clsidOffset = 0x50.
1681          *        rootEntryOffset = headerSize + sectorSize*sectDirStart
1682          *                          + 128*rootEntryDirectory
1683          *
1684          *        where:  headerSize = 0x200 (always)
1685          *                sectorSize = 2 raised to power of uSectorShift,
1686          *                             which is found in the header at
1687          *                             offset 0x1E.
1688          *                sectDirStart = found in the header at offset 0x30.
1689          *                rootEntryDirectory = in general, should search for
1690          *                                     directory labelled as root.
1691          *                                     We will assume value of 0 (i.e.,
1692          *                                     rootEntry is in first directory)
1693          */
1694 
1695         // Mark the stream so we can reset it. 0x100 is enough for the first
1696         // few reads, but the mark will have to be reset and set again once
1697         // the offset to the root directory entry is computed. That offset
1698         // can be very large and isn't know until the stream has been read from
1699         is.mark(0x100);
1700 
1701         // Get the byte ordering located at 0x1E. 0xFE is Intel,
1702         // 0xFF is other
1703         long toSkip = (long)0x1C;
1704         long posn;
1705 
1706         if ((posn = skipForward(is, toSkip)) < toSkip) {
1707           is.reset();
1708           return false;
1709         }
1710 
1711         int c[] = new int[16];
1712         if (readBytes(c, 2, is) < 0) {
1713             is.reset();
1714             return false;
1715         }
1716 
1717         int byteOrder = c[0];
1718 
1719         posn+=2;
1720         int uSectorShift;
1721         if (readBytes(c, 2, is) < 0) {
1722             is.reset();
1723             return false;
1724         }
1725 
1726         if(byteOrder == 0xFE) {
1727             uSectorShift = c[0];
1728             uSectorShift += c[1] << 8;
1729         }
1730         else {
1731             uSectorShift = c[0] << 8;
1732             uSectorShift += c[1];
1733         }
1734 
1735         posn += 2;
1736         toSkip = (long)0x30 - posn;
1737         long skipped = 0;
1738         if ((skipped = skipForward(is, toSkip)) < toSkip) {
1739           is.reset();
1740           return false;
1741         }
1742         posn += skipped;
1743 
1744         if (readBytes(c, 4, is) < 0) {
1745             is.reset();
1746             return false;
1747         }
1748 
1749         int sectDirStart;
1750         if(byteOrder == 0xFE) {
1751             sectDirStart = c[0];
1752             sectDirStart += c[1] << 8;
1753             sectDirStart += c[2] << 16;
1754             sectDirStart += c[3] << 24;
1755         } else {
1756             sectDirStart =  c[0] << 24;
1757             sectDirStart += c[1] << 16;
1758             sectDirStart += c[2] << 8;
1759             sectDirStart += c[3];
1760         }
1761         posn += 4;
1762         is.reset(); // Reset back to the beginning
1763 
1764         toSkip = 0x200L + (long)(1<<uSectorShift)*sectDirStart + 0x50L;
1765 
1766         // Sanity check!
1767         if (toSkip < 0) {
1768             return false;
1769         }
1770 
1771         /*
1772          * How far can we skip? Is there any performance problem here?
1773          * This skip can be fairly long, at least 0x4c650 in at least
1774          * one case. Have to assume that the skip will fit in an int.
1775          * Leave room to read whole root dir
1776          */
1777         is.mark((int)toSkip+0x30);
1778 
1779         if ((skipForward(is, toSkip)) < toSkip) {
1780             is.reset();
1781             return false;
1782         }
1783 
1784         /* should be at beginning of ClassID, which is as follows
1785          * (in Intel byte order):
1786          *    00 67 61 56 54 C1 CE 11 85 53 00 AA 00 A1 F9 5B
1787          *
1788          * This is stored from Windows as long,short,short,char[8]
1789          * so for byte order changes, the order only changes for
1790          * the first 8 bytes in the ClassID.
1791          *
1792          * Test against this, ignoring second byte (Intel) since
1793          * this could change depending on part of Fpx file we have.
1794          */
1795 
1796         if (readBytes(c, 16, is) < 0) {
1797             is.reset();
1798             return false;
1799         }
1800 
1801         // intel byte order
1802         if (byteOrder == 0xFE &&
1803             c[0] == 0x00 && c[2] == 0x61 && c[3] == 0x56 &&
1804             c[4] == 0x54 && c[5] == 0xC1 && c[6] == 0xCE &&
1805             c[7] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
1806             c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
1807             c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
1808             is.reset();
1809             return true;
1810         }
1811 
1812         // non-intel byte order
1813         else if (c[3] == 0x00 && c[1] == 0x61 && c[0] == 0x56 &&
1814             c[5] == 0x54 && c[4] == 0xC1 && c[7] == 0xCE &&
1815             c[6] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
1816             c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
1817             c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
1818             is.reset();
1819             return true;
1820         }
1821         is.reset();
1822         return false;
1823     }
1824 
1825     /**
1826      * Tries to read the specified number of bytes from the stream
1827      * Returns -1, If EOF is reached before len bytes are read, returns 0
1828      * otherwise
1829      */
1830     private static int readBytes(int c[], int len, InputStream is)
1831                 throws IOException {
1832 
1833         byte buf[] = new byte[len];
1834         if (is.read(buf, 0, len) < len) {
1835             return -1;
1836         }
1837 
1838         // fill the passed in int array
1839         for (int i = 0; i < len; i++) {
1840              c[i] = buf[i] & 0xff;
1841         }
1842         return 0;
1843     }
1844 
1845 
1846     /**
1847      * Skips through the specified number of bytes from the stream
1848      * until either EOF is reached, or the specified
1849      * number of bytes have been skipped
1850      */
1851     private static long skipForward(InputStream is, long toSkip)
1852                 throws IOException {
1853 
1854         long eachSkip = 0;
1855         long skipped = 0;
1856 
1857         while (skipped != toSkip) {
1858             eachSkip = is.skip(toSkip - skipped);
1859 
1860             // check if EOF is reached
1861             if (eachSkip <= 0) {
1862                 if (is.read() == -1) {
1863                     return skipped ;
1864                 } else {
1865                     skipped++;
1866                 }
1867             }
1868             skipped += eachSkip;
1869         }
1870         return skipped;
1871     }
1872 
1873     private void checkConnected() {
1874         if (connected)
1875             throw new IllegalStateException("Already connected");
1876     }
1877 }
1878 
1879 class UnknownContentHandler extends ContentHandler {
1880     static final ContentHandler INSTANCE = new UnknownContentHandler();
1881 
1882     public Object getContent(URLConnection uc) throws IOException {
1883         return uc.getInputStream();
1884     }
1885 }