• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.net;
28 
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.util.Hashtable;
33 import java.util.Date;
34 import java.util.StringTokenizer;
35 import java.util.Collections;
36 import java.util.Map;
37 import java.util.List;
38 import java.security.Permission;
39 import java.security.AccessController;
40 import sun.security.util.SecurityConstants;
41 import sun.net.www.MessageHeader;
42 
43 /**
44  * The abstract class {@code URLConnection} is the superclass
45  * of all classes that represent a communications link between the
46  * application and a URL. Instances of this class can be used both to
47  * read from and to write to the resource referenced by the URL. In
48  * general, creating a connection to a URL is a multistep process:
49  *
50  * <center><table border=2 summary="Describes the process of creating a connection to a URL: openConnection() and connect() over time.">
51  * <tr><th>{@code openConnection()}</th>
52  *     <th>{@code connect()}</th></tr>
53  * <tr><td>Manipulate parameters that affect the connection to the remote
54  *         resource.</td>
55  *     <td>Interact with the resource; query header fields and
56  *         contents.</td></tr>
57  * </table>
58  * ----------------------------&gt;
59  * <br>time</center>
60  *
61  * <ol>
62  * <li>The connection object is created by invoking the
63  *     {@code openConnection} method on a URL.
64  * <li>The setup parameters and general request properties are manipulated.
65  * <li>The actual connection to the remote object is made, using the
66  *    {@code connect} method.
67  * <li>The remote object becomes available. The header fields and the contents
68  *     of the remote object can be accessed.
69  * </ol>
70  * <p>
71  * The setup parameters are modified using the following methods:
72  * <ul>
73  *   <li>{@code setAllowUserInteraction}
74  *   <li>{@code setDoInput}
75  *   <li>{@code setDoOutput}
76  *   <li>{@code setIfModifiedSince}
77  *   <li>{@code setUseCaches}
78  * </ul>
79  * <p>
80  * and the general request properties are modified using the method:
81  * <ul>
82  *   <li>{@code setRequestProperty}
83  * </ul>
84  * <p>
85  * Default values for the {@code AllowUserInteraction} and
86  * {@code UseCaches} parameters can be set using the methods
87  * {@code setDefaultAllowUserInteraction} and
88  * {@code setDefaultUseCaches}.
89  * <p>
90  * Each of the above {@code set} methods has a corresponding
91  * {@code get} method to retrieve the value of the parameter or
92  * general request property. The specific parameters and general
93  * request properties that are applicable are protocol specific.
94  * <p>
95  * The following methods are used to access the header fields and
96  * the contents after the connection is made to the remote object:
97  * <ul>
98  *   <li>{@code getContent}
99  *   <li>{@code getHeaderField}
100  *   <li>{@code getInputStream}
101  *   <li>{@code getOutputStream}
102  * </ul>
103  * <p>
104  * Certain header fields are accessed frequently. The methods:
105  * <ul>
106  *   <li>{@code getContentEncoding}
107  *   <li>{@code getContentLength}
108  *   <li>{@code getContentType}
109  *   <li>{@code getDate}
110  *   <li>{@code getExpiration}
111  *   <li>{@code getLastModifed}
112  * </ul>
113  * <p>
114  * provide convenient access to these fields. The
115  * {@code getContentType} method is used by the
116  * {@code getContent} method to determine the type of the remote
117  * object; subclasses may find it convenient to override the
118  * {@code getContentType} method.
119  * <p>
120  * In the common case, all of the pre-connection parameters and
121  * general request properties can be ignored: the pre-connection
122  * parameters and request properties default to sensible values. For
123  * most clients of this interface, there are only two interesting
124  * methods: {@code getInputStream} and {@code getContent},
125  * which are mirrored in the {@code URL} class by convenience methods.
126  * <p>
127  * More information on the request properties and header fields of
128  * an {@code http} connection can be found at:
129  * <blockquote><pre>
130  * <a href="http://www.ietf.org/rfc/rfc2616.txt">http://www.ietf.org/rfc/rfc2616.txt</a>
131  * </pre></blockquote>
132  *
133  * Invoking the {@code close()} methods on the {@code InputStream} or {@code OutputStream} of an
134  * {@code URLConnection} after a request may free network resources associated with this
135  * instance, unless particular protocol specifications specify different behaviours
136  * for it.
137  *
138  * @author  James Gosling
139  * @see     java.net.URL#openConnection()
140  * @see     java.net.URLConnection#connect()
141  * @see     java.net.URLConnection#getContent()
142  * @see     java.net.URLConnection#getContentEncoding()
143  * @see     java.net.URLConnection#getContentLength()
144  * @see     java.net.URLConnection#getContentType()
145  * @see     java.net.URLConnection#getDate()
146  * @see     java.net.URLConnection#getExpiration()
147  * @see     java.net.URLConnection#getHeaderField(int)
148  * @see     java.net.URLConnection#getHeaderField(java.lang.String)
149  * @see     java.net.URLConnection#getInputStream()
150  * @see     java.net.URLConnection#getLastModified()
151  * @see     java.net.URLConnection#getOutputStream()
152  * @see     java.net.URLConnection#setAllowUserInteraction(boolean)
153  * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
154  * @see     java.net.URLConnection#setDoInput(boolean)
155  * @see     java.net.URLConnection#setDoOutput(boolean)
156  * @see     java.net.URLConnection#setIfModifiedSince(long)
157  * @see     java.net.URLConnection#setRequestProperty(java.lang.String, java.lang.String)
158  * @see     java.net.URLConnection#setUseCaches(boolean)
159  * @since   JDK1.0
160  */
161 public abstract class URLConnection {
162 
163    /**
164      * The URL represents the remote object on the World Wide Web to
165      * which this connection is opened.
166      * <p>
167      * The value of this field can be accessed by the
168      * {@code getURL} method.
169      * <p>
170      * The default value of this variable is the value of the URL
171      * argument in the {@code URLConnection} constructor.
172      *
173      * @see     java.net.URLConnection#getURL()
174      * @see     java.net.URLConnection#url
175      */
176     protected URL url;
177 
178    /**
179      * This variable is set by the {@code setDoInput} method. Its
180      * value is returned by the {@code getDoInput} method.
181      * <p>
182      * A URL connection can be used for input and/or output. Setting the
183      * {@code doInput} flag to {@code true} indicates that
184      * the application intends to read data from the URL connection.
185      * <p>
186      * The default value of this field is {@code true}.
187      *
188      * @see     java.net.URLConnection#getDoInput()
189      * @see     java.net.URLConnection#setDoInput(boolean)
190      */
191     protected boolean doInput = true;
192 
193    /**
194      * This variable is set by the {@code setDoOutput} method. Its
195      * value is returned by the {@code getDoOutput} method.
196      * <p>
197      * A URL connection can be used for input and/or output. Setting the
198      * {@code doOutput} flag to {@code true} indicates
199      * that the application intends to write data to the URL connection.
200      * <p>
201      * The default value of this field is {@code false}.
202      *
203      * @see     java.net.URLConnection#getDoOutput()
204      * @see     java.net.URLConnection#setDoOutput(boolean)
205      */
206     protected boolean doOutput = false;
207 
208     private static boolean defaultAllowUserInteraction = false;
209 
210    /**
211      * If {@code true}, this {@code URL} is being examined in
212      * a context in which it makes sense to allow user interactions such
213      * as popping up an authentication dialog. If {@code false},
214      * then no user interaction is allowed.
215      * <p>
216      * The value of this field can be set by the
217      * {@code setAllowUserInteraction} method.
218      * Its value is returned by the
219      * {@code getAllowUserInteraction} method.
220      * Its default value is the value of the argument in the last invocation
221      * of the {@code setDefaultAllowUserInteraction} method.
222      *
223      * @see     java.net.URLConnection#getAllowUserInteraction()
224      * @see     java.net.URLConnection#setAllowUserInteraction(boolean)
225      * @see     java.net.URLConnection#setDefaultAllowUserInteraction(boolean)
226      */
227     protected boolean allowUserInteraction = defaultAllowUserInteraction;
228 
229     private static boolean defaultUseCaches = true;
230 
231    /**
232      * If {@code true}, the protocol is allowed to use caching
233      * whenever it can. If {@code false}, the protocol must always
234      * try to get a fresh copy of the object.
235      * <p>
236      * This field is set by the {@code setUseCaches} method. Its
237      * value is returned by the {@code getUseCaches} method.
238      * <p>
239      * Its default value is the value given in the last invocation of the
240      * {@code setDefaultUseCaches} method.
241      *
242      * @see     java.net.URLConnection#setUseCaches(boolean)
243      * @see     java.net.URLConnection#getUseCaches()
244      * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
245      */
246     protected boolean useCaches = defaultUseCaches;
247 
248    /**
249      * Some protocols support skipping the fetching of the object unless
250      * the object has been modified more recently than a certain time.
251      * <p>
252      * A nonzero value gives a time as the number of milliseconds since
253      * January 1, 1970, GMT. The object is fetched only if it has been
254      * modified more recently than that time.
255      * <p>
256      * This variable is set by the {@code setIfModifiedSince}
257      * method. Its value is returned by the
258      * {@code getIfModifiedSince} method.
259      * <p>
260      * The default value of this field is {@code 0}, indicating
261      * that the fetching must always occur.
262      *
263      * @see     java.net.URLConnection#getIfModifiedSince()
264      * @see     java.net.URLConnection#setIfModifiedSince(long)
265      */
266     protected long ifModifiedSince = 0;
267 
268    /**
269      * If {@code false}, this connection object has not created a
270      * communications link to the specified URL. If {@code true},
271      * the communications link has been established.
272      */
273     protected boolean connected = false;
274 
275     /**
276      * @since 1.5
277      */
278     private int connectTimeout;
279     private int readTimeout;
280 
281     /**
282      * @since 1.6
283      */
284     private MessageHeader requests;
285 
286    /**
287     * @since   JDK1.1
288     */
289     private static FileNameMap fileNameMap;
290 
291     // BEGIN Android-removed: Android has its own mime table.
292     /*
293      * @since 1.2.2
294      *
295     private static boolean fileNameMapLoaded = false;
296     */
297     // END Android-removed: Android has its own mime table.
298     /**
299      * Loads filename map (a mimetable) from a data file. It will
300      * first try to load the user-specific table, defined
301      * by &quot;content.types.user.table&quot; property. If that fails,
302      * it tries to load the default built-in table.
303      *
304      * @return the FileNameMap
305      * @since 1.2
306      * @see #setFileNameMap(java.net.FileNameMap)
307      */
getFileNameMap()308     public static synchronized FileNameMap getFileNameMap() {
309         // Android-changed: Android has its own mime table.
310         if (fileNameMap == null) {
311             fileNameMap = new DefaultFileNameMap();
312         }
313         return fileNameMap;
314     }
315 
316     /**
317      * Sets the FileNameMap.
318      * <p>
319      * If there is a security manager, this method first calls
320      * the security manager's {@code checkSetFactory} method
321      * to ensure the operation is allowed.
322      * This could result in a SecurityException.
323      *
324      * @param map the FileNameMap to be set
325      * @exception  SecurityException  if a security manager exists and its
326      *             {@code checkSetFactory} method doesn't allow the operation.
327      * @see        SecurityManager#checkSetFactory
328      * @see #getFileNameMap()
329      * @since 1.2
330      */
setFileNameMap(FileNameMap map)331     public static void setFileNameMap(FileNameMap map) {
332         SecurityManager sm = System.getSecurityManager();
333         if (sm != null) sm.checkSetFactory();
334         fileNameMap = map;
335     }
336 
337     /**
338      * Opens a communications link to the resource referenced by this
339      * URL, if such a connection has not already been established.
340      * <p>
341      * If the {@code connect} method is called when the connection
342      * has already been opened (indicated by the {@code connected}
343      * field having the value {@code true}), the call is ignored.
344      * <p>
345      * URLConnection objects go through two phases: first they are
346      * created, then they are connected.  After being created, and
347      * before being connected, various options can be specified
348      * (e.g., doInput and UseCaches).  After connecting, it is an
349      * error to try to set them.  Operations that depend on being
350      * connected, like getContentLength, will implicitly perform the
351      * connection, if necessary.
352      *
353      * @throws SocketTimeoutException if the timeout expires before
354      *               the connection can be established
355      * @exception  IOException  if an I/O error occurs while opening the
356      *               connection.
357      * @see java.net.URLConnection#connected
358      * @see #getConnectTimeout()
359      * @see #setConnectTimeout(int)
360      */
connect()361     abstract public void connect() throws IOException;
362 
363     // Android-changed: Add javadoc to specify Android's timeout behavior.
364     /**
365      * Sets a specified timeout value, in milliseconds, to be used
366      * when opening a communications link to the resource referenced
367      * by this URLConnection.  If the timeout expires before the
368      * connection can be established, a
369      * java.net.SocketTimeoutException is raised. A timeout of zero is
370      * interpreted as an infinite timeout.
371 
372      * <p> Some non-standard implementation of this method may ignore
373      * the specified timeout. To see the connect timeout set, please
374      * call getConnectTimeout().
375      *
376      * <p><strong>Warning</strong>: If the hostname resolves to multiple IP
377      * addresses, Android's default implementation of {@link HttpURLConnection}
378      * will try each in
379      * <a href="http://www.ietf.org/rfc/rfc3484.txt">RFC 3484</a> order. If
380      * connecting to each of these addresses fails, multiple timeouts will
381      * elapse before the connect attempt throws an exception. Host names
382      * that support both IPv6 and IPv4 always have at least 2 IP addresses.
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      */
setConnectTimeout(int timeout)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      */
getConnectTimeout()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      */
setReadTimeout(int timeout)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      */
getReadTimeout()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      */
URLConnection(URL url)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      */
getURL()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      */
getContentLength()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 7.0
505      */
getContentLengthLong()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      */
getContentType()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      */
getContentEncoding()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      */
getExpiration()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      */
getDate()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      */
getLastModified()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      */
getHeaderField(String name)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      */
getHeaderFields()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      */
getHeaderFieldInt(String name, int Default)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 7.0
633      */
getHeaderFieldLong(String name, long Default)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")
getHeaderFieldDate(String name, long Default)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      */
getHeaderFieldKey(int n)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      */
getHeaderField(int n)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      * <ol>
706      * <li>If the application has set up a content handler factory instance
707      *     using the {@code setContentHandlerFactory} method, the
708      *     {@code createContentHandler} method of that instance is called
709      *     with the content type as an argument; the result is a content
710      *     handler for that content type.
711      * <li>If no content handler factory has yet been set up, or if the
712      *     factory's {@code createContentHandler} method returns
713      *     {@code null}, then the application loads the class named:
714      *     <blockquote><pre>
715      *         sun.net.www.content.&lt;<i>contentType</i>&gt;
716      *     </pre></blockquote>
717      *     where &lt;<i>contentType</i>&gt; is formed by taking the
718      *     content-type string, replacing all slash characters with a
719      *     {@code period} ('.'), and all other non-alphanumeric characters
720      *     with the underscore character '{@code _}'. The alphanumeric
721      *     characters are specifically the 26 uppercase ASCII letters
722      *     '{@code A}' through '{@code Z}', the 26 lowercase ASCII
723      *     letters '{@code a}' through '{@code z}', and the 10 ASCII
724      *     digits '{@code 0}' through '{@code 9}'. If the specified
725      *     class does not exist, or is not a subclass of
726      *     {@code ContentHandler}, then an
727      *     {@code UnknownServiceException} is thrown.
728      * </ol>
729      *
730      * @return     the object fetched. The {@code instanceof} operator
731      *               should be used to determine the specific kind of object
732      *               returned.
733      * @exception  IOException              if an I/O error occurs while
734      *               getting the content.
735      * @exception  UnknownServiceException  if the protocol does not support
736      *               the content type.
737      * @see        java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
738      * @see        java.net.URLConnection#getContentType()
739      * @see        java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
740      */
getContent()741     public Object getContent() throws IOException {
742         // Must call getInputStream before GetHeaderField gets called
743         // so that FileNotFoundException has a chance to be thrown up
744         // from here without being caught.
745         getInputStream();
746         return getContentHandler().getContent(this);
747     }
748 
749     /**
750      * Retrieves the contents of this URL connection.
751      *
752      * @param classes the {@code Class} array
753      * indicating the requested types
754      * @return     the object fetched that is the first match of the type
755      *               specified in the classes array. null if none of
756      *               the requested types are supported.
757      *               The {@code instanceof} operator should be used to
758      *               determine the specific kind of object returned.
759      * @exception  IOException              if an I/O error occurs while
760      *               getting the content.
761      * @exception  UnknownServiceException  if the protocol does not support
762      *               the content type.
763      * @see        java.net.URLConnection#getContent()
764      * @see        java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
765      * @see        java.net.URLConnection#getContent(java.lang.Class[])
766      * @see        java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
767      * @since 1.3
768      */
getContent(Class[] classes)769     public Object getContent(Class[] classes) throws IOException {
770         // Must call getInputStream before GetHeaderField gets called
771         // so that FileNotFoundException has a chance to be thrown up
772         // from here without being caught.
773         getInputStream();
774         return getContentHandler().getContent(this, classes);
775     }
776 
777     /**
778      * Returns a permission object representing the permission
779      * necessary to make the connection represented by this
780      * object. This method returns null if no permission is
781      * required to make the connection. By default, this method
782      * returns {@code java.security.AllPermission}. Subclasses
783      * should override this method and return the permission
784      * that best represents the permission required to make a
785      * a connection to the URL. For example, a {@code URLConnection}
786      * representing a {@code file:} URL would return a
787      * {@code java.io.FilePermission} object.
788      *
789      * <p>The permission returned may dependent upon the state of the
790      * connection. For example, the permission before connecting may be
791      * different from that after connecting. For example, an HTTP
792      * sever, say foo.com, may redirect the connection to a different
793      * host, say bar.com. Before connecting the permission returned by
794      * the connection will represent the permission needed to connect
795      * to foo.com, while the permission returned after connecting will
796      * be to bar.com.
797      *
798      * <p>Permissions are generally used for two purposes: to protect
799      * caches of objects obtained through URLConnections, and to check
800      * the right of a recipient to learn about a particular URL. In
801      * the first case, the permission should be obtained
802      * <em>after</em> the object has been obtained. For example, in an
803      * HTTP connection, this will represent the permission to connect
804      * to the host from which the data was ultimately fetched. In the
805      * second case, the permission should be obtained and tested
806      * <em>before</em> connecting.
807      *
808      * @return the permission object representing the permission
809      * necessary to make the connection represented by this
810      * URLConnection.
811      *
812      * @exception IOException if the computation of the permission
813      * requires network or file I/O and an exception occurs while
814      * computing it.
815      */
getPermission()816     public Permission getPermission() throws IOException {
817         return SecurityConstants.ALL_PERMISSION;
818     }
819 
820     /**
821      * Returns an input stream that reads from this open connection.
822      *
823      * A SocketTimeoutException can be thrown when reading from the
824      * returned input stream if the read timeout expires before data
825      * is available for read.
826      *
827      * @return     an input stream that reads from this open connection.
828      * @exception  IOException              if an I/O error occurs while
829      *               creating the input stream.
830      * @exception  UnknownServiceException  if the protocol does not support
831      *               input.
832      * @see #setReadTimeout(int)
833      * @see #getReadTimeout()
834      */
getInputStream()835     public InputStream getInputStream() throws IOException {
836         throw new UnknownServiceException("protocol doesn't support input");
837     }
838 
839     /**
840      * Returns an output stream that writes to this connection.
841      *
842      * @return     an output stream that writes to this connection.
843      * @exception  IOException              if an I/O error occurs while
844      *               creating the output stream.
845      * @exception  UnknownServiceException  if the protocol does not support
846      *               output.
847      */
getOutputStream()848     public OutputStream getOutputStream() throws IOException {
849         throw new UnknownServiceException("protocol doesn't support output");
850     }
851 
852     /**
853      * Returns a {@code String} representation of this URL connection.
854      *
855      * @return  a string representation of this {@code URLConnection}.
856      */
toString()857     public String toString() {
858         return this.getClass().getName() + ":" + url;
859     }
860 
861     /**
862      * Sets the value of the {@code doInput} field for this
863      * {@code URLConnection} to the specified value.
864      * <p>
865      * A URL connection can be used for input and/or output.  Set the DoInput
866      * flag to true if you intend to use the URL connection for input,
867      * false if not.  The default is true.
868      *
869      * @param   doinput   the new value.
870      * @throws IllegalStateException if already connected
871      * @see     java.net.URLConnection#doInput
872      * @see #getDoInput()
873      */
setDoInput(boolean doinput)874     public void setDoInput(boolean doinput) {
875         if (connected)
876             throw new IllegalStateException("Already connected");
877         doInput = doinput;
878     }
879 
880     /**
881      * Returns the value of this {@code URLConnection}'s
882      * {@code doInput} flag.
883      *
884      * @return  the value of this {@code URLConnection}'s
885      *          {@code doInput} flag.
886      * @see     #setDoInput(boolean)
887      */
getDoInput()888     public boolean getDoInput() {
889         return doInput;
890     }
891 
892     /**
893      * Sets the value of the {@code doOutput} field for this
894      * {@code URLConnection} to the specified value.
895      * <p>
896      * A URL connection can be used for input and/or output.  Set the DoOutput
897      * flag to true if you intend to use the URL connection for output,
898      * false if not.  The default is false.
899      *
900      * @param   dooutput   the new value.
901      * @throws IllegalStateException if already connected
902      * @see #getDoOutput()
903      */
setDoOutput(boolean dooutput)904     public void setDoOutput(boolean dooutput) {
905         if (connected)
906             throw new IllegalStateException("Already connected");
907         doOutput = dooutput;
908     }
909 
910     /**
911      * Returns the value of this {@code URLConnection}'s
912      * {@code doOutput} flag.
913      *
914      * @return  the value of this {@code URLConnection}'s
915      *          {@code doOutput} flag.
916      * @see     #setDoOutput(boolean)
917      */
getDoOutput()918     public boolean getDoOutput() {
919         return doOutput;
920     }
921 
922     /**
923      * Set the value of the {@code allowUserInteraction} field of
924      * this {@code URLConnection}.
925      *
926      * @param   allowuserinteraction   the new value.
927      * @throws IllegalStateException if already connected
928      * @see     #getAllowUserInteraction()
929      */
setAllowUserInteraction(boolean allowuserinteraction)930     public void setAllowUserInteraction(boolean allowuserinteraction) {
931         if (connected)
932             throw new IllegalStateException("Already connected");
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      */
getAllowUserInteraction()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      */
setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)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      */
getDefaultAllowUserInteraction()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      */
setUseCaches(boolean usecaches)993     public void setUseCaches(boolean usecaches) {
994         if (connected)
995             throw new IllegalStateException("Already connected");
996         useCaches = usecaches;
997     }
998 
999     /**
1000      * Returns the value of this {@code URLConnection}'s
1001      * {@code useCaches} field.
1002      *
1003      * @return  the value of this {@code URLConnection}'s
1004      *          {@code useCaches} field.
1005      * @see #setUseCaches(boolean)
1006      */
getUseCaches()1007     public boolean getUseCaches() {
1008         return useCaches;
1009     }
1010 
1011     /**
1012      * Sets the value of the {@code ifModifiedSince} field of
1013      * this {@code URLConnection} to the specified value.
1014      *
1015      * @param   ifmodifiedsince   the new value.
1016      * @throws IllegalStateException if already connected
1017      * @see     #getIfModifiedSince()
1018      */
setIfModifiedSince(long ifmodifiedsince)1019     public void setIfModifiedSince(long ifmodifiedsince) {
1020         if (connected)
1021             throw new IllegalStateException("Already connected");
1022         ifModifiedSince = ifmodifiedsince;
1023     }
1024 
1025     /**
1026      * Returns the value of this object's {@code ifModifiedSince} field.
1027      *
1028      * @return  the value of this object's {@code ifModifiedSince} field.
1029      * @see #setIfModifiedSince(long)
1030      */
getIfModifiedSince()1031     public long getIfModifiedSince() {
1032         return ifModifiedSince;
1033     }
1034 
1035    /**
1036      * Returns the default value of a {@code URLConnection}'s
1037      * {@code useCaches} flag.
1038      * <p>
1039      * Ths default is "sticky", being a part of the static state of all
1040      * URLConnections.  This flag applies to the next, and all following
1041      * URLConnections that are created.
1042      *
1043      * @return  the default value of a {@code URLConnection}'s
1044      *          {@code useCaches} flag.
1045      * @see     #setDefaultUseCaches(boolean)
1046      */
getDefaultUseCaches()1047     public boolean getDefaultUseCaches() {
1048         return defaultUseCaches;
1049     }
1050 
1051    /**
1052      * Sets the default value of the {@code useCaches} field to the
1053      * specified value.
1054      *
1055      * @param   defaultusecaches   the new value.
1056      * @see     #getDefaultUseCaches()
1057      */
setDefaultUseCaches(boolean defaultusecaches)1058     public void setDefaultUseCaches(boolean defaultusecaches) {
1059         defaultUseCaches = defaultusecaches;
1060     }
1061 
1062     /**
1063      * Sets the general request property. If a property with the key already
1064      * exists, overwrite its value with the new value.
1065      *
1066      * <p> NOTE: HTTP requires all request properties which can
1067      * legally have multiple instances with the same key
1068      * to use a comma-separated list syntax which enables multiple
1069      * properties to be appended into a single property.
1070      *
1071      * @param   key     the keyword by which the request is known
1072      *                  (e.g., "{@code Accept}").
1073      * @param   value   the value associated with it.
1074      * @throws IllegalStateException if already connected
1075      * @throws NullPointerException if key is <CODE>null</CODE>
1076      * @see #getRequestProperty(java.lang.String)
1077      */
setRequestProperty(String key, String value)1078     public void setRequestProperty(String key, String value) {
1079         if (connected)
1080             throw new IllegalStateException("Already connected");
1081         if (key == null)
1082             throw new NullPointerException ("key is null");
1083 
1084         if (requests == null)
1085             requests = new MessageHeader();
1086 
1087         requests.set(key, value);
1088     }
1089 
1090     /**
1091      * Adds a general request property specified by a
1092      * key-value pair.  This method will not overwrite
1093      * existing values associated with the same key.
1094      *
1095      * @param   key     the keyword by which the request is known
1096      *                  (e.g., "{@code Accept}").
1097      * @param   value  the value associated with it.
1098      * @throws IllegalStateException if already connected
1099      * @throws NullPointerException if key is null
1100      * @see #getRequestProperties()
1101      * @since 1.4
1102      */
addRequestProperty(String key, String value)1103     public void addRequestProperty(String key, String value) {
1104         if (connected)
1105             throw new IllegalStateException("Already connected");
1106         if (key == null)
1107             throw new NullPointerException ("key is null");
1108 
1109         if (requests == null)
1110             requests = new MessageHeader();
1111 
1112         requests.add(key, value);
1113     }
1114 
1115 
1116     /**
1117      * Returns the value of the named general request property for this
1118      * connection.
1119      *
1120      * @param key the keyword by which the request is known (e.g., "Accept").
1121      * @return  the value of the named general request property for this
1122      *           connection. If key is null, then null is returned.
1123      * @throws IllegalStateException if already connected
1124      * @see #setRequestProperty(java.lang.String, java.lang.String)
1125      */
getRequestProperty(String key)1126     public String getRequestProperty(String key) {
1127         if (connected)
1128             throw new IllegalStateException("Already connected");
1129 
1130         if (requests == null)
1131             return null;
1132 
1133         return requests.findValue(key);
1134     }
1135 
1136     /**
1137      * Returns an unmodifiable Map of general request
1138      * properties for this connection. The Map keys
1139      * are Strings that represent the request-header
1140      * field names. Each Map value is a unmodifiable List
1141      * of Strings that represents the corresponding
1142      * field values.
1143      *
1144      * @return  a Map of the general request properties for this connection.
1145      * @throws IllegalStateException if already connected
1146      * @since 1.4
1147      */
getRequestProperties()1148     public Map<String,List<String>> getRequestProperties() {
1149         if (connected)
1150             throw new IllegalStateException("Already connected");
1151 
1152         if (requests == null)
1153             return Collections.emptyMap();
1154 
1155         return requests.getHeaders(null);
1156     }
1157 
1158     /**
1159      * Sets the default value of a general request property. When a
1160      * {@code URLConnection} is created, it is initialized with
1161      * these properties.
1162      *
1163      * @param   key     the keyword by which the request is known
1164      *                  (e.g., "{@code Accept}").
1165      * @param   value   the value associated with the key.
1166      *
1167      * @see java.net.URLConnection#setRequestProperty(java.lang.String,java.lang.String)
1168      *
1169      * @deprecated The instance specific setRequestProperty method
1170      * should be used after an appropriate instance of URLConnection
1171      * is obtained. Invoking this method will have no effect.
1172      *
1173      * @see #getDefaultRequestProperty(java.lang.String)
1174      */
1175     @Deprecated
setDefaultRequestProperty(String key, String value)1176     public static void setDefaultRequestProperty(String key, String value) {
1177     }
1178 
1179     /**
1180      * Returns the value of the default request property. Default request
1181      * properties are set for every connection.
1182      *
1183      * @param key the keyword by which the request is known (e.g., "Accept").
1184      * @return  the value of the default request property
1185      * for the specified key.
1186      *
1187      * @see java.net.URLConnection#getRequestProperty(java.lang.String)
1188      *
1189      * @deprecated The instance specific getRequestProperty method
1190      * should be used after an appropriate instance of URLConnection
1191      * is obtained.
1192      *
1193      * @see #setDefaultRequestProperty(java.lang.String, java.lang.String)
1194      */
1195     @Deprecated
getDefaultRequestProperty(String key)1196     public static String getDefaultRequestProperty(String key) {
1197         return null;
1198     }
1199 
1200     /**
1201      * The ContentHandler factory.
1202      */
1203     static ContentHandlerFactory factory;
1204 
1205     /**
1206      * Sets the {@code ContentHandlerFactory} of an
1207      * application. It can be called at most once by an application.
1208      * <p>
1209      * The {@code ContentHandlerFactory} instance is used to
1210      * construct a content handler from a content type
1211      * <p>
1212      * If there is a security manager, this method first calls
1213      * the security manager's {@code checkSetFactory} method
1214      * to ensure the operation is allowed.
1215      * This could result in a SecurityException.
1216      *
1217      * @param      fac   the desired factory.
1218      * @exception  Error  if the factory has already been defined.
1219      * @exception  SecurityException  if a security manager exists and its
1220      *             {@code checkSetFactory} method doesn't allow the operation.
1221      * @see        java.net.ContentHandlerFactory
1222      * @see        java.net.URLConnection#getContent()
1223      * @see        SecurityManager#checkSetFactory
1224      */
setContentHandlerFactory(ContentHandlerFactory fac)1225     public static synchronized void setContentHandlerFactory(ContentHandlerFactory fac) {
1226         if (factory != null) {
1227             throw new Error("factory already defined");
1228         }
1229         SecurityManager security = System.getSecurityManager();
1230         if (security != null) {
1231             security.checkSetFactory();
1232         }
1233         factory = fac;
1234     }
1235 
1236     private static Hashtable<String, ContentHandler> handlers = new Hashtable<>();
1237 
1238     /**
1239      * Gets the Content Handler appropriate for this connection.
1240      */
getContentHandler()1241     synchronized ContentHandler getContentHandler()
1242         throws IOException
1243     {
1244         String contentType = stripOffParameters(getContentType());
1245         ContentHandler handler = null;
1246         // BEGIN Android-changed: App Compat. Android guesses content type from name and stream.
1247         if (contentType == null) {
1248             if ((contentType = guessContentTypeFromName(url.getFile())) == null) {
1249                 contentType = guessContentTypeFromStream(getInputStream());
1250             }
1251         }
1252 
1253         if (contentType == null) {
1254             return UnknownContentHandler.INSTANCE;
1255         }
1256         // END Android-changed: App Compat. Android guesses content type from name and stream.
1257         try {
1258             handler = handlers.get(contentType);
1259             if (handler != null)
1260                 return handler;
1261         } catch(Exception e) {
1262         }
1263 
1264         if (factory != null)
1265             handler = factory.createContentHandler(contentType);
1266         if (handler == null) {
1267             try {
1268                 handler = lookupContentHandlerClassFor(contentType);
1269             } catch(Exception e) {
1270                 e.printStackTrace();
1271                 handler = UnknownContentHandler.INSTANCE;
1272             }
1273             handlers.put(contentType, handler);
1274         }
1275         return handler;
1276     }
1277 
1278     /*
1279      * Media types are in the format: type/subtype*(; parameter).
1280      * For looking up the content handler, we should ignore those
1281      * parameters.
1282      */
stripOffParameters(String contentType)1283     private String stripOffParameters(String contentType)
1284     {
1285         if (contentType == null)
1286             return null;
1287         int index = contentType.indexOf(';');
1288 
1289         if (index > 0)
1290             return contentType.substring(0, index);
1291         else
1292             return contentType;
1293     }
1294 
1295     private static final String contentClassPrefix = "sun.net.www.content";
1296     private static final String contentPathProp = "java.content.handler.pkgs";
1297 
1298     /**
1299      * Looks for a content handler in a user-defineable set of places.
1300      * By default it looks in sun.net.www.content, but users can define a
1301      * vertical-bar delimited set of class prefixes to search through in
1302      * addition by defining the java.content.handler.pkgs property.
1303      * The class name must be of the form:
1304      * <pre>
1305      *     {package-prefix}.{major}.{minor}
1306      * e.g.
1307      *     YoyoDyne.experimental.text.plain
1308      * </pre>
1309      */
lookupContentHandlerClassFor(String contentType)1310     private ContentHandler lookupContentHandlerClassFor(String contentType)
1311         throws InstantiationException, IllegalAccessException, ClassNotFoundException {
1312         String contentHandlerClassName = typeToPackageName(contentType);
1313 
1314         String contentHandlerPkgPrefixes =getContentHandlerPkgPrefixes();
1315 
1316         StringTokenizer packagePrefixIter =
1317             new StringTokenizer(contentHandlerPkgPrefixes, "|");
1318 
1319         while (packagePrefixIter.hasMoreTokens()) {
1320             String packagePrefix = packagePrefixIter.nextToken().trim();
1321 
1322             try {
1323                 String clsName = packagePrefix + "." + contentHandlerClassName;
1324                 Class<?> cls = null;
1325                 try {
1326                     cls = Class.forName(clsName);
1327                 } catch (ClassNotFoundException e) {
1328                     ClassLoader cl = ClassLoader.getSystemClassLoader();
1329                     if (cl != null) {
1330                         cls = cl.loadClass(clsName);
1331                     }
1332                 }
1333                 if (cls != null) {
1334                     ContentHandler handler =
1335                         (ContentHandler)cls.newInstance();
1336                     return handler;
1337                 }
1338             } catch(Exception e) {
1339             }
1340         }
1341 
1342         return UnknownContentHandler.INSTANCE;
1343     }
1344 
1345     /**
1346      * Utility function to map a MIME content type into an equivalent
1347      * pair of class name components.  For example: "text/html" would
1348      * be returned as "text.html"
1349      */
typeToPackageName(String contentType)1350     private String typeToPackageName(String contentType) {
1351         // make sure we canonicalize the class name: all lower case
1352         contentType = contentType.toLowerCase();
1353         int len = contentType.length();
1354         char nm[] = new char[len];
1355         contentType.getChars(0, len, nm, 0);
1356         for (int i = 0; i < len; i++) {
1357             char c = nm[i];
1358             if (c == '/') {
1359                 nm[i] = '.';
1360             } else if (!('A' <= c && c <= 'Z' ||
1361                        'a' <= c && c <= 'z' ||
1362                        '0' <= c && c <= '9')) {
1363                 nm[i] = '_';
1364             }
1365         }
1366         return new String(nm);
1367     }
1368 
1369 
1370     /**
1371      * Returns a vertical bar separated list of package prefixes for potential
1372      * content handlers.  Tries to get the java.content.handler.pkgs property
1373      * to use as a set of package prefixes to search.  Whether or not
1374      * that property has been defined, the sun.net.www.content is always
1375      * the last one on the returned package list.
1376      */
getContentHandlerPkgPrefixes()1377     private String getContentHandlerPkgPrefixes() {
1378         String packagePrefixList = AccessController.doPrivileged(
1379             new sun.security.action.GetPropertyAction(contentPathProp, ""));
1380 
1381         if (packagePrefixList != "") {
1382             packagePrefixList += "|";
1383         }
1384 
1385         return packagePrefixList + contentClassPrefix;
1386     }
1387 
1388     /**
1389      * Tries to determine the content type of an object, based
1390      * on the specified "file" component of a URL.
1391      * This is a convenience method that can be used by
1392      * subclasses that override the {@code getContentType} method.
1393      *
1394      * @param   fname   a filename.
1395      * @return  a guess as to what the content type of the object is,
1396      *          based upon its file name.
1397      * @see     java.net.URLConnection#getContentType()
1398      */
guessContentTypeFromName(String fname)1399     public static String guessContentTypeFromName(String fname) {
1400         return getFileNameMap().getContentTypeFor(fname);
1401     }
1402 
1403     /**
1404      * Tries to determine the type of an input stream based on the
1405      * characters at the beginning of the input stream. This method can
1406      * be used by subclasses that override the
1407      * {@code getContentType} method.
1408      * <p>
1409      * Ideally, this routine would not be needed. But many
1410      * {@code http} servers return the incorrect content type; in
1411      * addition, there are many nonstandard extensions. Direct inspection
1412      * of the bytes to determine the content type is often more accurate
1413      * than believing the content type claimed by the {@code http} server.
1414      *
1415      * @param      is   an input stream that supports marks.
1416      * @return     a guess at the content type, or {@code null} if none
1417      *             can be determined.
1418      * @exception  IOException  if an I/O error occurs while reading the
1419      *               input stream.
1420      * @see        java.io.InputStream#mark(int)
1421      * @see        java.io.InputStream#markSupported()
1422      * @see        java.net.URLConnection#getContentType()
1423      */
guessContentTypeFromStream(InputStream is)1424     static public String guessContentTypeFromStream(InputStream is)
1425                         throws IOException {
1426         // If we can't read ahead safely, just give up on guessing
1427         if (!is.markSupported())
1428             return null;
1429 
1430         is.mark(16);
1431         int c1 = is.read();
1432         int c2 = is.read();
1433         int c3 = is.read();
1434         int c4 = is.read();
1435         int c5 = is.read();
1436         int c6 = is.read();
1437         int c7 = is.read();
1438         int c8 = is.read();
1439         int c9 = is.read();
1440         int c10 = is.read();
1441         int c11 = is.read();
1442         int c12 = is.read();
1443         int c13 = is.read();
1444         int c14 = is.read();
1445         int c15 = is.read();
1446         int c16 = is.read();
1447         is.reset();
1448 
1449         if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) {
1450             return "application/java-vm";
1451         }
1452 
1453         if (c1 == 0xAC && c2 == 0xED) {
1454             // next two bytes are version number, currently 0x00 0x05
1455             return "application/x-java-serialized-object";
1456         }
1457 
1458         if (c1 == '<') {
1459             if (c2 == '!'
1460                 || ((c2 == 'h' && (c3 == 't' && c4 == 'm' && c5 == 'l' ||
1461                                    c3 == 'e' && c4 == 'a' && c5 == 'd') ||
1462                 (c2 == 'b' && c3 == 'o' && c4 == 'd' && c5 == 'y'))) ||
1463                 ((c2 == 'H' && (c3 == 'T' && c4 == 'M' && c5 == 'L' ||
1464                                 c3 == 'E' && c4 == 'A' && c5 == 'D') ||
1465                 (c2 == 'B' && c3 == 'O' && c4 == 'D' && c5 == 'Y')))) {
1466                 return "text/html";
1467             }
1468 
1469             if (c2 == '?' && c3 == 'x' && c4 == 'm' && c5 == 'l' && c6 == ' ') {
1470                 return "application/xml";
1471             }
1472         }
1473 
1474         // big and little (identical) endian UTF-8 encodings, with BOM
1475         if (c1 == 0xef &&  c2 == 0xbb &&  c3 == 0xbf) {
1476             if (c4 == '<' &&  c5 == '?' &&  c6 == 'x') {
1477                 return "application/xml";
1478             }
1479         }
1480 
1481         // big and little endian UTF-16 encodings, with byte order mark
1482         if (c1 == 0xfe && c2 == 0xff) {
1483             if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' &&
1484                 c7 == 0 && c8 == 'x') {
1485                 return "application/xml";
1486             }
1487         }
1488 
1489         if (c1 == 0xff && c2 == 0xfe) {
1490             if (c3 == '<' && c4 == 0 && c5 == '?' && c6 == 0 &&
1491                 c7 == 'x' && c8 == 0) {
1492                 return "application/xml";
1493             }
1494         }
1495 
1496         // big and little endian UTF-32 encodings, with BOM
1497         if (c1 == 0x00 &&  c2 == 0x00 &&  c3 == 0xfe &&  c4 == 0xff) {
1498             if (c5  == 0 && c6  == 0 && c7  == 0 && c8  == '<' &&
1499                 c9  == 0 && c10 == 0 && c11 == 0 && c12 == '?' &&
1500                 c13 == 0 && c14 == 0 && c15 == 0 && c16 == 'x') {
1501                 return "application/xml";
1502             }
1503         }
1504 
1505         if (c1 == 0xff &&  c2 == 0xfe &&  c3 == 0x00 &&  c4 == 0x00) {
1506             if (c5  == '<' && c6  == 0 && c7  == 0 && c8  == 0 &&
1507                 c9  == '?' && c10 == 0 && c11 == 0 && c12 == 0 &&
1508                 c13 == 'x' && c14 == 0 && c15 == 0 && c16 == 0) {
1509                 return "application/xml";
1510             }
1511         }
1512 
1513         if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') {
1514             return "image/gif";
1515         }
1516 
1517         if (c1 == '#' && c2 == 'd' && c3 == 'e' && c4 == 'f') {
1518             return "image/x-bitmap";
1519         }
1520 
1521         if (c1 == '!' && c2 == ' ' && c3 == 'X' && c4 == 'P' &&
1522                         c5 == 'M' && c6 == '2') {
1523             return "image/x-pixmap";
1524         }
1525 
1526         if (c1 == 137 && c2 == 80 && c3 == 78 &&
1527                 c4 == 71 && c5 == 13 && c6 == 10 &&
1528                 c7 == 26 && c8 == 10) {
1529             return "image/png";
1530         }
1531 
1532         if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) {
1533             if (c4 == 0xE0 || c4 == 0xEE) {
1534                 return "image/jpeg";
1535             }
1536 
1537             /**
1538              * File format used by digital cameras to store images.
1539              * Exif Format can be read by any application supporting
1540              * JPEG. Exif Spec can be found at:
1541              * http://www.pima.net/standards/it10/PIMA15740/Exif_2-1.PDF
1542              */
1543             if ((c4 == 0xE1) &&
1544                 (c7 == 'E' && c8 == 'x' && c9 == 'i' && c10 =='f' &&
1545                  c11 == 0)) {
1546                 return "image/jpeg";
1547             }
1548         }
1549 
1550         if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 &&
1551             c5 == 0xA1 && c6 == 0xB1 && c7 == 0x1A && c8 == 0xE1) {
1552 
1553             /* Above is signature of Microsoft Structured Storage.
1554              * Below this, could have tests for various SS entities.
1555              * For now, just test for FlashPix.
1556              */
1557             if (checkfpx(is)) {
1558                 return "image/vnd.fpx";
1559             }
1560         }
1561 
1562         if (c1 == 0x2E && c2 == 0x73 && c3 == 0x6E && c4 == 0x64) {
1563             return "audio/basic";  // .au format, big endian
1564         }
1565 
1566         if (c1 == 0x64 && c2 == 0x6E && c3 == 0x73 && c4 == 0x2E) {
1567             return "audio/basic";  // .au format, little endian
1568         }
1569 
1570         if (c1 == 'R' && c2 == 'I' && c3 == 'F' && c4 == 'F') {
1571             /* I don't know if this is official but evidence
1572              * suggests that .wav files start with "RIFF" - brown
1573              */
1574             return "audio/x-wav";
1575         }
1576         return null;
1577     }
1578 
1579     /**
1580      * Check for FlashPix image data in InputStream is.  Return true if
1581      * the stream has FlashPix data, false otherwise.  Before calling this
1582      * method, the stream should have already been checked to be sure it
1583      * contains Microsoft Structured Storage data.
1584      */
checkfpx(InputStream is)1585     static private boolean checkfpx(InputStream is) throws IOException {
1586 
1587         /* Test for FlashPix image data in Microsoft Structured Storage format.
1588          * In general, should do this with calls to an SS implementation.
1589          * Lacking that, need to dig via offsets to get to the FlashPix
1590          * ClassID.  Details:
1591          *
1592          * Offset to Fpx ClsID from beginning of stream should be:
1593          *
1594          * FpxClsidOffset = rootEntryOffset + clsidOffset
1595          *
1596          * where: clsidOffset = 0x50.
1597          *        rootEntryOffset = headerSize + sectorSize*sectDirStart
1598          *                          + 128*rootEntryDirectory
1599          *
1600          *        where:  headerSize = 0x200 (always)
1601          *                sectorSize = 2 raised to power of uSectorShift,
1602          *                             which is found in the header at
1603          *                             offset 0x1E.
1604          *                sectDirStart = found in the header at offset 0x30.
1605          *                rootEntryDirectory = in general, should search for
1606          *                                     directory labelled as root.
1607          *                                     We will assume value of 0 (i.e.,
1608          *                                     rootEntry is in first directory)
1609          */
1610 
1611         // Mark the stream so we can reset it. 0x100 is enough for the first
1612         // few reads, but the mark will have to be reset and set again once
1613         // the offset to the root directory entry is computed. That offset
1614         // can be very large and isn't know until the stream has been read from
1615         is.mark(0x100);
1616 
1617         // Get the byte ordering located at 0x1E. 0xFE is Intel,
1618         // 0xFF is other
1619         long toSkip = (long)0x1C;
1620         long posn;
1621 
1622         if ((posn = skipForward(is, toSkip)) < toSkip) {
1623           is.reset();
1624           return false;
1625         }
1626 
1627         int c[] = new int[16];
1628         if (readBytes(c, 2, is) < 0) {
1629             is.reset();
1630             return false;
1631         }
1632 
1633         int byteOrder = c[0];
1634 
1635         posn+=2;
1636         int uSectorShift;
1637         if (readBytes(c, 2, is) < 0) {
1638             is.reset();
1639             return false;
1640         }
1641 
1642         if(byteOrder == 0xFE) {
1643             uSectorShift = c[0];
1644             uSectorShift += c[1] << 8;
1645         }
1646         else {
1647             uSectorShift = c[0] << 8;
1648             uSectorShift += c[1];
1649         }
1650 
1651         posn += 2;
1652         toSkip = (long)0x30 - posn;
1653         long skipped = 0;
1654         if ((skipped = skipForward(is, toSkip)) < toSkip) {
1655           is.reset();
1656           return false;
1657         }
1658         posn += skipped;
1659 
1660         if (readBytes(c, 4, is) < 0) {
1661             is.reset();
1662             return false;
1663         }
1664 
1665         int sectDirStart;
1666         if(byteOrder == 0xFE) {
1667             sectDirStart = c[0];
1668             sectDirStart += c[1] << 8;
1669             sectDirStart += c[2] << 16;
1670             sectDirStart += c[3] << 24;
1671         } else {
1672             sectDirStart =  c[0] << 24;
1673             sectDirStart += c[1] << 16;
1674             sectDirStart += c[2] << 8;
1675             sectDirStart += c[3];
1676         }
1677         posn += 4;
1678         is.reset(); // Reset back to the beginning
1679 
1680         toSkip = 0x200L + (long)(1<<uSectorShift)*sectDirStart + 0x50L;
1681 
1682         // Sanity check!
1683         if (toSkip < 0) {
1684             return false;
1685         }
1686 
1687         /*
1688          * How far can we skip? Is there any performance problem here?
1689          * This skip can be fairly long, at least 0x4c650 in at least
1690          * one case. Have to assume that the skip will fit in an int.
1691          * Leave room to read whole root dir
1692          */
1693         is.mark((int)toSkip+0x30);
1694 
1695         if ((skipForward(is, toSkip)) < toSkip) {
1696             is.reset();
1697             return false;
1698         }
1699 
1700         /* should be at beginning of ClassID, which is as follows
1701          * (in Intel byte order):
1702          *    00 67 61 56 54 C1 CE 11 85 53 00 AA 00 A1 F9 5B
1703          *
1704          * This is stored from Windows as long,short,short,char[8]
1705          * so for byte order changes, the order only changes for
1706          * the first 8 bytes in the ClassID.
1707          *
1708          * Test against this, ignoring second byte (Intel) since
1709          * this could change depending on part of Fpx file we have.
1710          */
1711 
1712         if (readBytes(c, 16, is) < 0) {
1713             is.reset();
1714             return false;
1715         }
1716 
1717         // intel byte order
1718         if (byteOrder == 0xFE &&
1719             c[0] == 0x00 && c[2] == 0x61 && c[3] == 0x56 &&
1720             c[4] == 0x54 && c[5] == 0xC1 && c[6] == 0xCE &&
1721             c[7] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
1722             c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
1723             c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
1724             is.reset();
1725             return true;
1726         }
1727 
1728         // non-intel byte order
1729         else if (c[3] == 0x00 && c[1] == 0x61 && c[0] == 0x56 &&
1730             c[5] == 0x54 && c[4] == 0xC1 && c[7] == 0xCE &&
1731             c[6] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
1732             c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
1733             c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
1734             is.reset();
1735             return true;
1736         }
1737         is.reset();
1738         return false;
1739     }
1740 
1741     /**
1742      * Tries to read the specified number of bytes from the stream
1743      * Returns -1, If EOF is reached before len bytes are read, returns 0
1744      * otherwise
1745      */
readBytes(int c[], int len, InputStream is)1746     static private int readBytes(int c[], int len, InputStream is)
1747                 throws IOException {
1748 
1749         byte buf[] = new byte[len];
1750         if (is.read(buf, 0, len) < len) {
1751             return -1;
1752         }
1753 
1754         // fill the passed in int array
1755         for (int i = 0; i < len; i++) {
1756              c[i] = buf[i] & 0xff;
1757         }
1758         return 0;
1759     }
1760 
1761 
1762     /**
1763      * Skips through the specified number of bytes from the stream
1764      * until either EOF is reached, or the specified
1765      * number of bytes have been skipped
1766      */
skipForward(InputStream is, long toSkip)1767     static private long skipForward(InputStream is, long toSkip)
1768                 throws IOException {
1769 
1770         long eachSkip = 0;
1771         long skipped = 0;
1772 
1773         while (skipped != toSkip) {
1774             eachSkip = is.skip(toSkip - skipped);
1775 
1776             // check if EOF is reached
1777             if (eachSkip <= 0) {
1778                 if (is.read() == -1) {
1779                     return skipped ;
1780                 } else {
1781                     skipped++;
1782                 }
1783             }
1784             skipped += eachSkip;
1785         }
1786         return skipped;
1787     }
1788 
1789 }
1790 
1791 
1792 class UnknownContentHandler extends ContentHandler {
1793     static final ContentHandler INSTANCE = new UnknownContentHandler();
1794 
getContent(URLConnection uc)1795     public Object getContent(URLConnection uc) throws IOException {
1796         return uc.getInputStream();
1797     }
1798 }
1799