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