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