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