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