1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/net/URLConnection.java Thu Oct 31 10:50:19 2013 +0100
1.3 @@ -0,0 +1,1797 @@
1.4 +/*
1.5 + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.net;
1.30 +
1.31 +import java.io.IOException;
1.32 +import java.io.InputStream;
1.33 +import java.io.OutputStream;
1.34 +import java.util.Hashtable;
1.35 +import java.util.Date;
1.36 +import java.util.StringTokenizer;
1.37 +import java.util.Collections;
1.38 +import java.util.Map;
1.39 +import java.util.List;
1.40 +import java.security.Permission;
1.41 +import java.security.AccessController;
1.42 +import sun.security.util.SecurityConstants;
1.43 +import sun.net.www.MessageHeader;
1.44 +
1.45 +/**
1.46 + * The abstract class <code>URLConnection</code> is the superclass
1.47 + * of all classes that represent a communications link between the
1.48 + * application and a URL. Instances of this class can be used both to
1.49 + * read from and to write to the resource referenced by the URL. In
1.50 + * general, creating a connection to a URL is a multistep process:
1.51 + * <p>
1.52 + * <center><table border=2 summary="Describes the process of creating a connection to a URL: openConnection() and connect() over time.">
1.53 + * <tr><th><code>openConnection()</code></th>
1.54 + * <th><code>connect()</code></th></tr>
1.55 + * <tr><td>Manipulate parameters that affect the connection to the remote
1.56 + * resource.</td>
1.57 + * <td>Interact with the resource; query header fields and
1.58 + * contents.</td></tr>
1.59 + * </table>
1.60 + * ---------------------------->
1.61 + * <br>time</center>
1.62 + *
1.63 + * <ol>
1.64 + * <li>The connection object is created by invoking the
1.65 + * <code>openConnection</code> method on a URL.
1.66 + * <li>The setup parameters and general request properties are manipulated.
1.67 + * <li>The actual connection to the remote object is made, using the
1.68 + * <code>connect</code> method.
1.69 + * <li>The remote object becomes available. The header fields and the contents
1.70 + * of the remote object can be accessed.
1.71 + * </ol>
1.72 + * <p>
1.73 + * The setup parameters are modified using the following methods:
1.74 + * <ul>
1.75 + * <li><code>setAllowUserInteraction</code>
1.76 + * <li><code>setDoInput</code>
1.77 + * <li><code>setDoOutput</code>
1.78 + * <li><code>setIfModifiedSince</code>
1.79 + * <li><code>setUseCaches</code>
1.80 + * </ul>
1.81 + * <p>
1.82 + * and the general request properties are modified using the method:
1.83 + * <ul>
1.84 + * <li><code>setRequestProperty</code>
1.85 + * </ul>
1.86 + * <p>
1.87 + * Default values for the <code>AllowUserInteraction</code> and
1.88 + * <code>UseCaches</code> parameters can be set using the methods
1.89 + * <code>setDefaultAllowUserInteraction</code> and
1.90 + * <code>setDefaultUseCaches</code>.
1.91 + * <p>
1.92 + * Each of the above <code>set</code> methods has a corresponding
1.93 + * <code>get</code> method to retrieve the value of the parameter or
1.94 + * general request property. The specific parameters and general
1.95 + * request properties that are applicable are protocol specific.
1.96 + * <p>
1.97 + * The following methods are used to access the header fields and
1.98 + * the contents after the connection is made to the remote object:
1.99 + * <ul>
1.100 + * <li><code>getContent</code>
1.101 + * <li><code>getHeaderField</code>
1.102 + * <li><code>getInputStream</code>
1.103 + * <li><code>getOutputStream</code>
1.104 + * </ul>
1.105 + * <p>
1.106 + * Certain header fields are accessed frequently. The methods:
1.107 + * <ul>
1.108 + * <li><code>getContentEncoding</code>
1.109 + * <li><code>getContentLength</code>
1.110 + * <li><code>getContentType</code>
1.111 + * <li><code>getDate</code>
1.112 + * <li><code>getExpiration</code>
1.113 + * <li><code>getLastModifed</code>
1.114 + * </ul>
1.115 + * <p>
1.116 + * provide convenient access to these fields. The
1.117 + * <code>getContentType</code> method is used by the
1.118 + * <code>getContent</code> method to determine the type of the remote
1.119 + * object; subclasses may find it convenient to override the
1.120 + * <code>getContentType</code> method.
1.121 + * <p>
1.122 + * In the common case, all of the pre-connection parameters and
1.123 + * general request properties can be ignored: the pre-connection
1.124 + * parameters and request properties default to sensible values. For
1.125 + * most clients of this interface, there are only two interesting
1.126 + * methods: <code>getInputStream</code> and <code>getContent</code>,
1.127 + * which are mirrored in the <code>URL</code> class by convenience methods.
1.128 + * <p>
1.129 + * More information on the request properties and header fields of
1.130 + * an <code>http</code> connection can be found at:
1.131 + * <blockquote><pre>
1.132 + * <a href="http://www.ietf.org/rfc/rfc2616.txt">http://www.ietf.org/rfc/rfc2616.txt</a>
1.133 + * </pre></blockquote>
1.134 + *
1.135 + * Note about <code>fileNameMap</code>: In versions prior to JDK 1.1.6,
1.136 + * field <code>fileNameMap</code> of <code>URLConnection</code> was public.
1.137 + * In JDK 1.1.6 and later, <code>fileNameMap</code> is private; accessor
1.138 + * and mutator methods {@link #getFileNameMap() getFileNameMap} and
1.139 + * {@link #setFileNameMap(java.net.FileNameMap) setFileNameMap} are added
1.140 + * to access it. This change is also described on the <a href=
1.141 + * "http://java.sun.com/products/jdk/1.2/compatibility.html">
1.142 + * Compatibility</a> page.
1.143 + *
1.144 + * Invoking the <tt>close()</tt> methods on the <tt>InputStream</tt> or <tt>OutputStream</tt> of an
1.145 + * <tt>URLConnection</tt> after a request may free network resources associated with this
1.146 + * instance, unless particular protocol specifications specify different behaviours
1.147 + * for it.
1.148 + *
1.149 + * @author James Gosling
1.150 + * @see java.net.URL#openConnection()
1.151 + * @see java.net.URLConnection#connect()
1.152 + * @see java.net.URLConnection#getContent()
1.153 + * @see java.net.URLConnection#getContentEncoding()
1.154 + * @see java.net.URLConnection#getContentLength()
1.155 + * @see java.net.URLConnection#getContentType()
1.156 + * @see java.net.URLConnection#getDate()
1.157 + * @see java.net.URLConnection#getExpiration()
1.158 + * @see java.net.URLConnection#getHeaderField(int)
1.159 + * @see java.net.URLConnection#getHeaderField(java.lang.String)
1.160 + * @see java.net.URLConnection#getInputStream()
1.161 + * @see java.net.URLConnection#getLastModified()
1.162 + * @see java.net.URLConnection#getOutputStream()
1.163 + * @see java.net.URLConnection#setAllowUserInteraction(boolean)
1.164 + * @see java.net.URLConnection#setDefaultUseCaches(boolean)
1.165 + * @see java.net.URLConnection#setDoInput(boolean)
1.166 + * @see java.net.URLConnection#setDoOutput(boolean)
1.167 + * @see java.net.URLConnection#setIfModifiedSince(long)
1.168 + * @see java.net.URLConnection#setRequestProperty(java.lang.String, java.lang.String)
1.169 + * @see java.net.URLConnection#setUseCaches(boolean)
1.170 + * @since JDK1.0
1.171 + */
1.172 +public abstract class URLConnection {
1.173 +
1.174 + /**
1.175 + * The URL represents the remote object on the World Wide Web to
1.176 + * which this connection is opened.
1.177 + * <p>
1.178 + * The value of this field can be accessed by the
1.179 + * <code>getURL</code> method.
1.180 + * <p>
1.181 + * The default value of this variable is the value of the URL
1.182 + * argument in the <code>URLConnection</code> constructor.
1.183 + *
1.184 + * @see java.net.URLConnection#getURL()
1.185 + * @see java.net.URLConnection#url
1.186 + */
1.187 + protected URL url;
1.188 +
1.189 + /**
1.190 + * This variable is set by the <code>setDoInput</code> method. Its
1.191 + * value is returned by the <code>getDoInput</code> method.
1.192 + * <p>
1.193 + * A URL connection can be used for input and/or output. Setting the
1.194 + * <code>doInput</code> flag to <code>true</code> indicates that
1.195 + * the application intends to read data from the URL connection.
1.196 + * <p>
1.197 + * The default value of this field is <code>true</code>.
1.198 + *
1.199 + * @see java.net.URLConnection#getDoInput()
1.200 + * @see java.net.URLConnection#setDoInput(boolean)
1.201 + */
1.202 + protected boolean doInput = true;
1.203 +
1.204 + /**
1.205 + * This variable is set by the <code>setDoOutput</code> method. Its
1.206 + * value is returned by the <code>getDoOutput</code> method.
1.207 + * <p>
1.208 + * A URL connection can be used for input and/or output. Setting the
1.209 + * <code>doOutput</code> flag to <code>true</code> indicates
1.210 + * that the application intends to write data to the URL connection.
1.211 + * <p>
1.212 + * The default value of this field is <code>false</code>.
1.213 + *
1.214 + * @see java.net.URLConnection#getDoOutput()
1.215 + * @see java.net.URLConnection#setDoOutput(boolean)
1.216 + */
1.217 + protected boolean doOutput = false;
1.218 +
1.219 + private static boolean defaultAllowUserInteraction = false;
1.220 +
1.221 + /**
1.222 + * If <code>true</code>, this <code>URL</code> is being examined in
1.223 + * a context in which it makes sense to allow user interactions such
1.224 + * as popping up an authentication dialog. If <code>false</code>,
1.225 + * then no user interaction is allowed.
1.226 + * <p>
1.227 + * The value of this field can be set by the
1.228 + * <code>setAllowUserInteraction</code> method.
1.229 + * Its value is returned by the
1.230 + * <code>getAllowUserInteraction</code> method.
1.231 + * Its default value is the value of the argument in the last invocation
1.232 + * of the <code>setDefaultAllowUserInteraction</code> method.
1.233 + *
1.234 + * @see java.net.URLConnection#getAllowUserInteraction()
1.235 + * @see java.net.URLConnection#setAllowUserInteraction(boolean)
1.236 + * @see java.net.URLConnection#setDefaultAllowUserInteraction(boolean)
1.237 + */
1.238 + protected boolean allowUserInteraction = defaultAllowUserInteraction;
1.239 +
1.240 + private static boolean defaultUseCaches = true;
1.241 +
1.242 + /**
1.243 + * If <code>true</code>, the protocol is allowed to use caching
1.244 + * whenever it can. If <code>false</code>, the protocol must always
1.245 + * try to get a fresh copy of the object.
1.246 + * <p>
1.247 + * This field is set by the <code>setUseCaches</code> method. Its
1.248 + * value is returned by the <code>getUseCaches</code> method.
1.249 + * <p>
1.250 + * Its default value is the value given in the last invocation of the
1.251 + * <code>setDefaultUseCaches</code> method.
1.252 + *
1.253 + * @see java.net.URLConnection#setUseCaches(boolean)
1.254 + * @see java.net.URLConnection#getUseCaches()
1.255 + * @see java.net.URLConnection#setDefaultUseCaches(boolean)
1.256 + */
1.257 + protected boolean useCaches = defaultUseCaches;
1.258 +
1.259 + /**
1.260 + * Some protocols support skipping the fetching of the object unless
1.261 + * the object has been modified more recently than a certain time.
1.262 + * <p>
1.263 + * A nonzero value gives a time as the number of milliseconds since
1.264 + * January 1, 1970, GMT. The object is fetched only if it has been
1.265 + * modified more recently than that time.
1.266 + * <p>
1.267 + * This variable is set by the <code>setIfModifiedSince</code>
1.268 + * method. Its value is returned by the
1.269 + * <code>getIfModifiedSince</code> method.
1.270 + * <p>
1.271 + * The default value of this field is <code>0</code>, indicating
1.272 + * that the fetching must always occur.
1.273 + *
1.274 + * @see java.net.URLConnection#getIfModifiedSince()
1.275 + * @see java.net.URLConnection#setIfModifiedSince(long)
1.276 + */
1.277 + protected long ifModifiedSince = 0;
1.278 +
1.279 + /**
1.280 + * If <code>false</code>, this connection object has not created a
1.281 + * communications link to the specified URL. If <code>true</code>,
1.282 + * the communications link has been established.
1.283 + */
1.284 + protected boolean connected = false;
1.285 +
1.286 + /**
1.287 + * @since 1.5
1.288 + */
1.289 + private int connectTimeout;
1.290 + private int readTimeout;
1.291 +
1.292 + /**
1.293 + * @since 1.6
1.294 + */
1.295 + private MessageHeader requests;
1.296 +
1.297 + /**
1.298 + * @since JDK1.1
1.299 + */
1.300 + private static FileNameMap fileNameMap;
1.301 +
1.302 + /**
1.303 + * @since 1.2.2
1.304 + */
1.305 + private static boolean fileNameMapLoaded = false;
1.306 +
1.307 + /**
1.308 + * Loads filename map (a mimetable) from a data file. It will
1.309 + * first try to load the user-specific table, defined
1.310 + * by "content.types.user.table" property. If that fails,
1.311 + * it tries to load the default built-in table at
1.312 + * lib/content-types.properties under java home.
1.313 + *
1.314 + * @return the FileNameMap
1.315 + * @since 1.2
1.316 + * @see #setFileNameMap(java.net.FileNameMap)
1.317 + */
1.318 + public static synchronized FileNameMap getFileNameMap() {
1.319 + if ((fileNameMap == null) && !fileNameMapLoaded) {
1.320 + fileNameMap = sun.net.www.MimeTable.loadTable();
1.321 + fileNameMapLoaded = true;
1.322 + }
1.323 +
1.324 + return new FileNameMap() {
1.325 + private FileNameMap map = fileNameMap;
1.326 + public String getContentTypeFor(String fileName) {
1.327 + return map.getContentTypeFor(fileName);
1.328 + }
1.329 + };
1.330 + }
1.331 +
1.332 + /**
1.333 + * Sets the FileNameMap.
1.334 + * <p>
1.335 + * If there is a security manager, this method first calls
1.336 + * the security manager's <code>checkSetFactory</code> method
1.337 + * to ensure the operation is allowed.
1.338 + * This could result in a SecurityException.
1.339 + *
1.340 + * @param map the FileNameMap to be set
1.341 + * @exception SecurityException if a security manager exists and its
1.342 + * <code>checkSetFactory</code> method doesn't allow the operation.
1.343 + * @see SecurityManager#checkSetFactory
1.344 + * @see #getFileNameMap()
1.345 + * @since 1.2
1.346 + */
1.347 + public static void setFileNameMap(FileNameMap map) {
1.348 + SecurityManager sm = System.getSecurityManager();
1.349 + if (sm != null) sm.checkSetFactory();
1.350 + fileNameMap = map;
1.351 + }
1.352 +
1.353 + /**
1.354 + * Opens a communications link to the resource referenced by this
1.355 + * URL, if such a connection has not already been established.
1.356 + * <p>
1.357 + * If the <code>connect</code> method is called when the connection
1.358 + * has already been opened (indicated by the <code>connected</code>
1.359 + * field having the value <code>true</code>), the call is ignored.
1.360 + * <p>
1.361 + * URLConnection objects go through two phases: first they are
1.362 + * created, then they are connected. After being created, and
1.363 + * before being connected, various options can be specified
1.364 + * (e.g., doInput and UseCaches). After connecting, it is an
1.365 + * error to try to set them. Operations that depend on being
1.366 + * connected, like getContentLength, will implicitly perform the
1.367 + * connection, if necessary.
1.368 + *
1.369 + * @throws SocketTimeoutException if the timeout expires before
1.370 + * the connection can be established
1.371 + * @exception IOException if an I/O error occurs while opening the
1.372 + * connection.
1.373 + * @see java.net.URLConnection#connected
1.374 + * @see #getConnectTimeout()
1.375 + * @see #setConnectTimeout(int)
1.376 + */
1.377 + abstract public void connect() throws IOException;
1.378 +
1.379 + /**
1.380 + * Sets a specified timeout value, in milliseconds, to be used
1.381 + * when opening a communications link to the resource referenced
1.382 + * by this URLConnection. If the timeout expires before the
1.383 + * connection can be established, a
1.384 + * java.net.SocketTimeoutException is raised. A timeout of zero is
1.385 + * interpreted as an infinite timeout.
1.386 +
1.387 + * <p> Some non-standard implmentation of this method may ignore
1.388 + * the specified timeout. To see the connect timeout set, please
1.389 + * call getConnectTimeout().
1.390 + *
1.391 + * @param timeout an <code>int</code> that specifies the connect
1.392 + * timeout value in milliseconds
1.393 + * @throws IllegalArgumentException if the timeout parameter is negative
1.394 + *
1.395 + * @see #getConnectTimeout()
1.396 + * @see #connect()
1.397 + * @since 1.5
1.398 + */
1.399 + public void setConnectTimeout(int timeout) {
1.400 + if (timeout < 0) {
1.401 + throw new IllegalArgumentException("timeout can not be negative");
1.402 + }
1.403 + connectTimeout = timeout;
1.404 + }
1.405 +
1.406 + /**
1.407 + * Returns setting for connect timeout.
1.408 + * <p>
1.409 + * 0 return implies that the option is disabled
1.410 + * (i.e., timeout of infinity).
1.411 + *
1.412 + * @return an <code>int</code> that indicates the connect timeout
1.413 + * value in milliseconds
1.414 + * @see #setConnectTimeout(int)
1.415 + * @see #connect()
1.416 + * @since 1.5
1.417 + */
1.418 + public int getConnectTimeout() {
1.419 + return connectTimeout;
1.420 + }
1.421 +
1.422 + /**
1.423 + * Sets the read timeout to a specified timeout, in
1.424 + * milliseconds. A non-zero value specifies the timeout when
1.425 + * reading from Input stream when a connection is established to a
1.426 + * resource. If the timeout expires before there is data available
1.427 + * for read, a java.net.SocketTimeoutException is raised. A
1.428 + * timeout of zero is interpreted as an infinite timeout.
1.429 + *
1.430 + *<p> Some non-standard implementation of this method ignores the
1.431 + * specified timeout. To see the read timeout set, please call
1.432 + * getReadTimeout().
1.433 + *
1.434 + * @param timeout an <code>int</code> that specifies the timeout
1.435 + * value to be used in milliseconds
1.436 + * @throws IllegalArgumentException if the timeout parameter is negative
1.437 + *
1.438 + * @see #getReadTimeout()
1.439 + * @see InputStream#read()
1.440 + * @since 1.5
1.441 + */
1.442 + public void setReadTimeout(int timeout) {
1.443 + if (timeout < 0) {
1.444 + throw new IllegalArgumentException("timeout can not be negative");
1.445 + }
1.446 + readTimeout = timeout;
1.447 + }
1.448 +
1.449 + /**
1.450 + * Returns setting for read timeout. 0 return implies that the
1.451 + * option is disabled (i.e., timeout of infinity).
1.452 + *
1.453 + * @return an <code>int</code> that indicates the read timeout
1.454 + * value in milliseconds
1.455 + *
1.456 + * @see #setReadTimeout(int)
1.457 + * @see InputStream#read()
1.458 + * @since 1.5
1.459 + */
1.460 + public int getReadTimeout() {
1.461 + return readTimeout;
1.462 + }
1.463 +
1.464 + /**
1.465 + * Constructs a URL connection to the specified URL. A connection to
1.466 + * the object referenced by the URL is not created.
1.467 + *
1.468 + * @param url the specified URL.
1.469 + */
1.470 + protected URLConnection(URL url) {
1.471 + this.url = url;
1.472 + }
1.473 +
1.474 + /**
1.475 + * Returns the value of this <code>URLConnection</code>'s <code>URL</code>
1.476 + * field.
1.477 + *
1.478 + * @return the value of this <code>URLConnection</code>'s <code>URL</code>
1.479 + * field.
1.480 + * @see java.net.URLConnection#url
1.481 + */
1.482 + public URL getURL() {
1.483 + return url;
1.484 + }
1.485 +
1.486 + /**
1.487 + * Returns the value of the <code>content-length</code> header field.
1.488 + * <P>
1.489 + * <B>Note</B>: {@link #getContentLengthLong() getContentLengthLong()}
1.490 + * should be preferred over this method, since it returns a {@code long}
1.491 + * instead and is therefore more portable.</P>
1.492 + *
1.493 + * @return the content length of the resource that this connection's URL
1.494 + * references, {@code -1} if the content length is not known,
1.495 + * or if the content length is greater than Integer.MAX_VALUE.
1.496 + */
1.497 + public int getContentLength() {
1.498 + long l = getContentLengthLong();
1.499 + if (l > Integer.MAX_VALUE)
1.500 + return -1;
1.501 + return (int) l;
1.502 + }
1.503 +
1.504 + /**
1.505 + * Returns the value of the <code>content-length</code> header field as a
1.506 + * long.
1.507 + *
1.508 + * @return the content length of the resource that this connection's URL
1.509 + * references, or <code>-1</code> if the content length is
1.510 + * not known.
1.511 + * @since 7.0
1.512 + */
1.513 + public long getContentLengthLong() {
1.514 + return getHeaderFieldLong("content-length", -1);
1.515 + }
1.516 +
1.517 + /**
1.518 + * Returns the value of the <code>content-type</code> header field.
1.519 + *
1.520 + * @return the content type of the resource that the URL references,
1.521 + * or <code>null</code> if not known.
1.522 + * @see java.net.URLConnection#getHeaderField(java.lang.String)
1.523 + */
1.524 + public String getContentType() {
1.525 + return getHeaderField("content-type");
1.526 + }
1.527 +
1.528 + /**
1.529 + * Returns the value of the <code>content-encoding</code> header field.
1.530 + *
1.531 + * @return the content encoding of the resource that the URL references,
1.532 + * or <code>null</code> if not known.
1.533 + * @see java.net.URLConnection#getHeaderField(java.lang.String)
1.534 + */
1.535 + public String getContentEncoding() {
1.536 + return getHeaderField("content-encoding");
1.537 + }
1.538 +
1.539 + /**
1.540 + * Returns the value of the <code>expires</code> header field.
1.541 + *
1.542 + * @return the expiration date of the resource that this URL references,
1.543 + * or 0 if not known. The value is the number of milliseconds since
1.544 + * January 1, 1970 GMT.
1.545 + * @see java.net.URLConnection#getHeaderField(java.lang.String)
1.546 + */
1.547 + public long getExpiration() {
1.548 + return getHeaderFieldDate("expires", 0);
1.549 + }
1.550 +
1.551 + /**
1.552 + * Returns the value of the <code>date</code> header field.
1.553 + *
1.554 + * @return the sending date of the resource that the URL references,
1.555 + * or <code>0</code> if not known. The value returned is the
1.556 + * number of milliseconds since January 1, 1970 GMT.
1.557 + * @see java.net.URLConnection#getHeaderField(java.lang.String)
1.558 + */
1.559 + public long getDate() {
1.560 + return getHeaderFieldDate("date", 0);
1.561 + }
1.562 +
1.563 + /**
1.564 + * Returns the value of the <code>last-modified</code> header field.
1.565 + * The result is the number of milliseconds since January 1, 1970 GMT.
1.566 + *
1.567 + * @return the date the resource referenced by this
1.568 + * <code>URLConnection</code> was last modified, or 0 if not known.
1.569 + * @see java.net.URLConnection#getHeaderField(java.lang.String)
1.570 + */
1.571 + public long getLastModified() {
1.572 + return getHeaderFieldDate("last-modified", 0);
1.573 + }
1.574 +
1.575 + /**
1.576 + * Returns the value of the named header field.
1.577 + * <p>
1.578 + * If called on a connection that sets the same header multiple times
1.579 + * with possibly different values, only the last value is returned.
1.580 + *
1.581 + *
1.582 + * @param name the name of a header field.
1.583 + * @return the value of the named header field, or <code>null</code>
1.584 + * if there is no such field in the header.
1.585 + */
1.586 + public String getHeaderField(String name) {
1.587 + return null;
1.588 + }
1.589 +
1.590 + /**
1.591 + * Returns an unmodifiable Map of the header fields.
1.592 + * The Map keys are Strings that represent the
1.593 + * response-header field names. Each Map value is an
1.594 + * unmodifiable List of Strings that represents
1.595 + * the corresponding field values.
1.596 + *
1.597 + * @return a Map of header fields
1.598 + * @since 1.4
1.599 + */
1.600 + public Map<String,List<String>> getHeaderFields() {
1.601 + return Collections.EMPTY_MAP;
1.602 + }
1.603 +
1.604 + /**
1.605 + * Returns the value of the named field parsed as a number.
1.606 + * <p>
1.607 + * This form of <code>getHeaderField</code> exists because some
1.608 + * connection types (e.g., <code>http-ng</code>) have pre-parsed
1.609 + * headers. Classes for that connection type can override this method
1.610 + * and short-circuit the parsing.
1.611 + *
1.612 + * @param name the name of the header field.
1.613 + * @param Default the default value.
1.614 + * @return the value of the named field, parsed as an integer. The
1.615 + * <code>Default</code> value is returned if the field is
1.616 + * missing or malformed.
1.617 + */
1.618 + public int getHeaderFieldInt(String name, int Default) {
1.619 + String value = getHeaderField(name);
1.620 + try {
1.621 + return Integer.parseInt(value);
1.622 + } catch (Exception e) { }
1.623 + return Default;
1.624 + }
1.625 +
1.626 + /**
1.627 + * Returns the value of the named field parsed as a number.
1.628 + * <p>
1.629 + * This form of <code>getHeaderField</code> exists because some
1.630 + * connection types (e.g., <code>http-ng</code>) have pre-parsed
1.631 + * headers. Classes for that connection type can override this method
1.632 + * and short-circuit the parsing.
1.633 + *
1.634 + * @param name the name of the header field.
1.635 + * @param Default the default value.
1.636 + * @return the value of the named field, parsed as a long. The
1.637 + * <code>Default</code> value is returned if the field is
1.638 + * missing or malformed.
1.639 + * @since 7.0
1.640 + */
1.641 + public long getHeaderFieldLong(String name, long Default) {
1.642 + String value = getHeaderField(name);
1.643 + try {
1.644 + return Long.parseLong(value);
1.645 + } catch (Exception e) { }
1.646 + return Default;
1.647 + }
1.648 +
1.649 + /**
1.650 + * Returns the value of the named field parsed as date.
1.651 + * The result is the number of milliseconds since January 1, 1970 GMT
1.652 + * represented by the named field.
1.653 + * <p>
1.654 + * This form of <code>getHeaderField</code> exists because some
1.655 + * connection types (e.g., <code>http-ng</code>) have pre-parsed
1.656 + * headers. Classes for that connection type can override this method
1.657 + * and short-circuit the parsing.
1.658 + *
1.659 + * @param name the name of the header field.
1.660 + * @param Default a default value.
1.661 + * @return the value of the field, parsed as a date. The value of the
1.662 + * <code>Default</code> argument is returned if the field is
1.663 + * missing or malformed.
1.664 + */
1.665 + public long getHeaderFieldDate(String name, long Default) {
1.666 + String value = getHeaderField(name);
1.667 + try {
1.668 + return Date.parse(value);
1.669 + } catch (Exception e) { }
1.670 + return Default;
1.671 + }
1.672 +
1.673 + /**
1.674 + * Returns the key for the <code>n</code><sup>th</sup> header field.
1.675 + * It returns <code>null</code> if there are fewer than <code>n+1</code> fields.
1.676 + *
1.677 + * @param n an index, where n>=0
1.678 + * @return the key for the <code>n</code><sup>th</sup> header field,
1.679 + * or <code>null</code> if there are fewer than <code>n+1</code>
1.680 + * fields.
1.681 + */
1.682 + public String getHeaderFieldKey(int n) {
1.683 + return null;
1.684 + }
1.685 +
1.686 + /**
1.687 + * Returns the value for the <code>n</code><sup>th</sup> header field.
1.688 + * It returns <code>null</code> if there are fewer than
1.689 + * <code>n+1</code>fields.
1.690 + * <p>
1.691 + * This method can be used in conjunction with the
1.692 + * {@link #getHeaderFieldKey(int) getHeaderFieldKey} method to iterate through all
1.693 + * the headers in the message.
1.694 + *
1.695 + * @param n an index, where n>=0
1.696 + * @return the value of the <code>n</code><sup>th</sup> header field
1.697 + * or <code>null</code> if there are fewer than <code>n+1</code> fields
1.698 + * @see java.net.URLConnection#getHeaderFieldKey(int)
1.699 + */
1.700 + public String getHeaderField(int n) {
1.701 + return null;
1.702 + }
1.703 +
1.704 + /**
1.705 + * Retrieves the contents of this URL connection.
1.706 + * <p>
1.707 + * This method first determines the content type of the object by
1.708 + * calling the <code>getContentType</code> method. If this is
1.709 + * the first time that the application has seen that specific content
1.710 + * type, a content handler for that content type is created:
1.711 + * <ol>
1.712 + * <li>If the application has set up a content handler factory instance
1.713 + * using the <code>setContentHandlerFactory</code> method, the
1.714 + * <code>createContentHandler</code> method of that instance is called
1.715 + * with the content type as an argument; the result is a content
1.716 + * handler for that content type.
1.717 + * <li>If no content handler factory has yet been set up, or if the
1.718 + * factory's <code>createContentHandler</code> method returns
1.719 + * <code>null</code>, then the application loads the class named:
1.720 + * <blockquote><pre>
1.721 + * sun.net.www.content.<<i>contentType</i>>
1.722 + * </pre></blockquote>
1.723 + * where <<i>contentType</i>> is formed by taking the
1.724 + * content-type string, replacing all slash characters with a
1.725 + * <code>period</code> ('.'), and all other non-alphanumeric characters
1.726 + * with the underscore character '<code>_</code>'. The alphanumeric
1.727 + * characters are specifically the 26 uppercase ASCII letters
1.728 + * '<code>A</code>' through '<code>Z</code>', the 26 lowercase ASCII
1.729 + * letters '<code>a</code>' through '<code>z</code>', and the 10 ASCII
1.730 + * digits '<code>0</code>' through '<code>9</code>'. If the specified
1.731 + * class does not exist, or is not a subclass of
1.732 + * <code>ContentHandler</code>, then an
1.733 + * <code>UnknownServiceException</code> is thrown.
1.734 + * </ol>
1.735 + *
1.736 + * @return the object fetched. The <code>instanceof</code> operator
1.737 + * should be used to determine the specific kind of object
1.738 + * returned.
1.739 + * @exception IOException if an I/O error occurs while
1.740 + * getting the content.
1.741 + * @exception UnknownServiceException if the protocol does not support
1.742 + * the content type.
1.743 + * @see java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
1.744 + * @see java.net.URLConnection#getContentType()
1.745 + * @see java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
1.746 + */
1.747 + public Object getContent() throws IOException {
1.748 + // Must call getInputStream before GetHeaderField gets called
1.749 + // so that FileNotFoundException has a chance to be thrown up
1.750 + // from here without being caught.
1.751 + getInputStream();
1.752 + return getContentHandler().getContent(this);
1.753 + }
1.754 +
1.755 + /**
1.756 + * Retrieves the contents of this URL connection.
1.757 + *
1.758 + * @param classes the <code>Class</code> array
1.759 + * indicating the requested types
1.760 + * @return the object fetched that is the first match of the type
1.761 + * specified in the classes array. null if none of
1.762 + * the requested types are supported.
1.763 + * The <code>instanceof</code> operator should be used to
1.764 + * determine the specific kind of object returned.
1.765 + * @exception IOException if an I/O error occurs while
1.766 + * getting the content.
1.767 + * @exception UnknownServiceException if the protocol does not support
1.768 + * the content type.
1.769 + * @see java.net.URLConnection#getContent()
1.770 + * @see java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
1.771 + * @see java.net.URLConnection#getContent(java.lang.Class[])
1.772 + * @see java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
1.773 + * @since 1.3
1.774 + */
1.775 + public Object getContent(Class[] classes) throws IOException {
1.776 + // Must call getInputStream before GetHeaderField gets called
1.777 + // so that FileNotFoundException has a chance to be thrown up
1.778 + // from here without being caught.
1.779 + getInputStream();
1.780 + return getContentHandler().getContent(this, classes);
1.781 + }
1.782 +
1.783 + /**
1.784 + * Returns a permission object representing the permission
1.785 + * necessary to make the connection represented by this
1.786 + * object. This method returns null if no permission is
1.787 + * required to make the connection. By default, this method
1.788 + * returns <code>java.security.AllPermission</code>. Subclasses
1.789 + * should override this method and return the permission
1.790 + * that best represents the permission required to make a
1.791 + * a connection to the URL. For example, a <code>URLConnection</code>
1.792 + * representing a <code>file:</code> URL would return a
1.793 + * <code>java.io.FilePermission</code> object.
1.794 + *
1.795 + * <p>The permission returned may dependent upon the state of the
1.796 + * connection. For example, the permission before connecting may be
1.797 + * different from that after connecting. For example, an HTTP
1.798 + * sever, say foo.com, may redirect the connection to a different
1.799 + * host, say bar.com. Before connecting the permission returned by
1.800 + * the connection will represent the permission needed to connect
1.801 + * to foo.com, while the permission returned after connecting will
1.802 + * be to bar.com.
1.803 + *
1.804 + * <p>Permissions are generally used for two purposes: to protect
1.805 + * caches of objects obtained through URLConnections, and to check
1.806 + * the right of a recipient to learn about a particular URL. In
1.807 + * the first case, the permission should be obtained
1.808 + * <em>after</em> the object has been obtained. For example, in an
1.809 + * HTTP connection, this will represent the permission to connect
1.810 + * to the host from which the data was ultimately fetched. In the
1.811 + * second case, the permission should be obtained and tested
1.812 + * <em>before</em> connecting.
1.813 + *
1.814 + * @return the permission object representing the permission
1.815 + * necessary to make the connection represented by this
1.816 + * URLConnection.
1.817 + *
1.818 + * @exception IOException if the computation of the permission
1.819 + * requires network or file I/O and an exception occurs while
1.820 + * computing it.
1.821 + */
1.822 + public Permission getPermission() throws IOException {
1.823 + return SecurityConstants.ALL_PERMISSION;
1.824 + }
1.825 +
1.826 + /**
1.827 + * Returns an input stream that reads from this open connection.
1.828 + *
1.829 + * A SocketTimeoutException can be thrown when reading from the
1.830 + * returned input stream if the read timeout expires before data
1.831 + * is available for read.
1.832 + *
1.833 + * @return an input stream that reads from this open connection.
1.834 + * @exception IOException if an I/O error occurs while
1.835 + * creating the input stream.
1.836 + * @exception UnknownServiceException if the protocol does not support
1.837 + * input.
1.838 + * @see #setReadTimeout(int)
1.839 + * @see #getReadTimeout()
1.840 + */
1.841 + public InputStream getInputStream() throws IOException {
1.842 + throw new UnknownServiceException("protocol doesn't support input");
1.843 + }
1.844 +
1.845 + /**
1.846 + * Returns an output stream that writes to this connection.
1.847 + *
1.848 + * @return an output stream that writes to this connection.
1.849 + * @exception IOException if an I/O error occurs while
1.850 + * creating the output stream.
1.851 + * @exception UnknownServiceException if the protocol does not support
1.852 + * output.
1.853 + */
1.854 + public OutputStream getOutputStream() throws IOException {
1.855 + throw new UnknownServiceException("protocol doesn't support output");
1.856 + }
1.857 +
1.858 + /**
1.859 + * Returns a <code>String</code> representation of this URL connection.
1.860 + *
1.861 + * @return a string representation of this <code>URLConnection</code>.
1.862 + */
1.863 + public String toString() {
1.864 + return this.getClass().getName() + ":" + url;
1.865 + }
1.866 +
1.867 + /**
1.868 + * Sets the value of the <code>doInput</code> field for this
1.869 + * <code>URLConnection</code> to the specified value.
1.870 + * <p>
1.871 + * A URL connection can be used for input and/or output. Set the DoInput
1.872 + * flag to true if you intend to use the URL connection for input,
1.873 + * false if not. The default is true.
1.874 + *
1.875 + * @param doinput the new value.
1.876 + * @throws IllegalStateException if already connected
1.877 + * @see java.net.URLConnection#doInput
1.878 + * @see #getDoInput()
1.879 + */
1.880 + public void setDoInput(boolean doinput) {
1.881 + if (connected)
1.882 + throw new IllegalStateException("Already connected");
1.883 + doInput = doinput;
1.884 + }
1.885 +
1.886 + /**
1.887 + * Returns the value of this <code>URLConnection</code>'s
1.888 + * <code>doInput</code> flag.
1.889 + *
1.890 + * @return the value of this <code>URLConnection</code>'s
1.891 + * <code>doInput</code> flag.
1.892 + * @see #setDoInput(boolean)
1.893 + */
1.894 + public boolean getDoInput() {
1.895 + return doInput;
1.896 + }
1.897 +
1.898 + /**
1.899 + * Sets the value of the <code>doOutput</code> field for this
1.900 + * <code>URLConnection</code> to the specified value.
1.901 + * <p>
1.902 + * A URL connection can be used for input and/or output. Set the DoOutput
1.903 + * flag to true if you intend to use the URL connection for output,
1.904 + * false if not. The default is false.
1.905 + *
1.906 + * @param dooutput the new value.
1.907 + * @throws IllegalStateException if already connected
1.908 + * @see #getDoOutput()
1.909 + */
1.910 + public void setDoOutput(boolean dooutput) {
1.911 + if (connected)
1.912 + throw new IllegalStateException("Already connected");
1.913 + doOutput = dooutput;
1.914 + }
1.915 +
1.916 + /**
1.917 + * Returns the value of this <code>URLConnection</code>'s
1.918 + * <code>doOutput</code> flag.
1.919 + *
1.920 + * @return the value of this <code>URLConnection</code>'s
1.921 + * <code>doOutput</code> flag.
1.922 + * @see #setDoOutput(boolean)
1.923 + */
1.924 + public boolean getDoOutput() {
1.925 + return doOutput;
1.926 + }
1.927 +
1.928 + /**
1.929 + * Set the value of the <code>allowUserInteraction</code> field of
1.930 + * this <code>URLConnection</code>.
1.931 + *
1.932 + * @param allowuserinteraction the new value.
1.933 + * @throws IllegalStateException if already connected
1.934 + * @see #getAllowUserInteraction()
1.935 + */
1.936 + public void setAllowUserInteraction(boolean allowuserinteraction) {
1.937 + if (connected)
1.938 + throw new IllegalStateException("Already connected");
1.939 + allowUserInteraction = allowuserinteraction;
1.940 + }
1.941 +
1.942 + /**
1.943 + * Returns the value of the <code>allowUserInteraction</code> field for
1.944 + * this object.
1.945 + *
1.946 + * @return the value of the <code>allowUserInteraction</code> field for
1.947 + * this object.
1.948 + * @see #setAllowUserInteraction(boolean)
1.949 + */
1.950 + public boolean getAllowUserInteraction() {
1.951 + return allowUserInteraction;
1.952 + }
1.953 +
1.954 + /**
1.955 + * Sets the default value of the
1.956 + * <code>allowUserInteraction</code> field for all future
1.957 + * <code>URLConnection</code> objects to the specified value.
1.958 + *
1.959 + * @param defaultallowuserinteraction the new value.
1.960 + * @see #getDefaultAllowUserInteraction()
1.961 + */
1.962 + public static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction) {
1.963 + defaultAllowUserInteraction = defaultallowuserinteraction;
1.964 + }
1.965 +
1.966 + /**
1.967 + * Returns the default value of the <code>allowUserInteraction</code>
1.968 + * field.
1.969 + * <p>
1.970 + * Ths default is "sticky", being a part of the static state of all
1.971 + * URLConnections. This flag applies to the next, and all following
1.972 + * URLConnections that are created.
1.973 + *
1.974 + * @return the default value of the <code>allowUserInteraction</code>
1.975 + * field.
1.976 + * @see #setDefaultAllowUserInteraction(boolean)
1.977 + */
1.978 + public static boolean getDefaultAllowUserInteraction() {
1.979 + return defaultAllowUserInteraction;
1.980 + }
1.981 +
1.982 + /**
1.983 + * Sets the value of the <code>useCaches</code> field of this
1.984 + * <code>URLConnection</code> to the specified value.
1.985 + * <p>
1.986 + * Some protocols do caching of documents. Occasionally, it is important
1.987 + * to be able to "tunnel through" and ignore the caches (e.g., the
1.988 + * "reload" button in a browser). If the UseCaches flag on a connection
1.989 + * is true, the connection is allowed to use whatever caches it can.
1.990 + * If false, caches are to be ignored.
1.991 + * The default value comes from DefaultUseCaches, which defaults to
1.992 + * true.
1.993 + *
1.994 + * @param usecaches a <code>boolean</code> indicating whether
1.995 + * or not to allow caching
1.996 + * @throws IllegalStateException if already connected
1.997 + * @see #getUseCaches()
1.998 + */
1.999 + public void setUseCaches(boolean usecaches) {
1.1000 + if (connected)
1.1001 + throw new IllegalStateException("Already connected");
1.1002 + useCaches = usecaches;
1.1003 + }
1.1004 +
1.1005 + /**
1.1006 + * Returns the value of this <code>URLConnection</code>'s
1.1007 + * <code>useCaches</code> field.
1.1008 + *
1.1009 + * @return the value of this <code>URLConnection</code>'s
1.1010 + * <code>useCaches</code> field.
1.1011 + * @see #setUseCaches(boolean)
1.1012 + */
1.1013 + public boolean getUseCaches() {
1.1014 + return useCaches;
1.1015 + }
1.1016 +
1.1017 + /**
1.1018 + * Sets the value of the <code>ifModifiedSince</code> field of
1.1019 + * this <code>URLConnection</code> to the specified value.
1.1020 + *
1.1021 + * @param ifmodifiedsince the new value.
1.1022 + * @throws IllegalStateException if already connected
1.1023 + * @see #getIfModifiedSince()
1.1024 + */
1.1025 + public void setIfModifiedSince(long ifmodifiedsince) {
1.1026 + if (connected)
1.1027 + throw new IllegalStateException("Already connected");
1.1028 + ifModifiedSince = ifmodifiedsince;
1.1029 + }
1.1030 +
1.1031 + /**
1.1032 + * Returns the value of this object's <code>ifModifiedSince</code> field.
1.1033 + *
1.1034 + * @return the value of this object's <code>ifModifiedSince</code> field.
1.1035 + * @see #setIfModifiedSince(long)
1.1036 + */
1.1037 + public long getIfModifiedSince() {
1.1038 + return ifModifiedSince;
1.1039 + }
1.1040 +
1.1041 + /**
1.1042 + * Returns the default value of a <code>URLConnection</code>'s
1.1043 + * <code>useCaches</code> flag.
1.1044 + * <p>
1.1045 + * Ths default is "sticky", being a part of the static state of all
1.1046 + * URLConnections. This flag applies to the next, and all following
1.1047 + * URLConnections that are created.
1.1048 + *
1.1049 + * @return the default value of a <code>URLConnection</code>'s
1.1050 + * <code>useCaches</code> flag.
1.1051 + * @see #setDefaultUseCaches(boolean)
1.1052 + */
1.1053 + public boolean getDefaultUseCaches() {
1.1054 + return defaultUseCaches;
1.1055 + }
1.1056 +
1.1057 + /**
1.1058 + * Sets the default value of the <code>useCaches</code> field to the
1.1059 + * specified value.
1.1060 + *
1.1061 + * @param defaultusecaches the new value.
1.1062 + * @see #getDefaultUseCaches()
1.1063 + */
1.1064 + public void setDefaultUseCaches(boolean defaultusecaches) {
1.1065 + defaultUseCaches = defaultusecaches;
1.1066 + }
1.1067 +
1.1068 + /**
1.1069 + * Sets the general request property. If a property with the key already
1.1070 + * exists, overwrite its value with the new value.
1.1071 + *
1.1072 + * <p> NOTE: HTTP requires all request properties which can
1.1073 + * legally have multiple instances with the same key
1.1074 + * to use a comma-seperated list syntax which enables multiple
1.1075 + * properties to be appended into a single property.
1.1076 + *
1.1077 + * @param key the keyword by which the request is known
1.1078 + * (e.g., "<code>Accept</code>").
1.1079 + * @param value the value associated with it.
1.1080 + * @throws IllegalStateException if already connected
1.1081 + * @throws NullPointerException if key is <CODE>null</CODE>
1.1082 + * @see #getRequestProperty(java.lang.String)
1.1083 + */
1.1084 + public void setRequestProperty(String key, String value) {
1.1085 + if (connected)
1.1086 + throw new IllegalStateException("Already connected");
1.1087 + if (key == null)
1.1088 + throw new NullPointerException ("key is null");
1.1089 +
1.1090 + if (requests == null)
1.1091 + requests = new MessageHeader();
1.1092 +
1.1093 + requests.set(key, value);
1.1094 + }
1.1095 +
1.1096 + /**
1.1097 + * Adds a general request property specified by a
1.1098 + * key-value pair. This method will not overwrite
1.1099 + * existing values associated with the same key.
1.1100 + *
1.1101 + * @param key the keyword by which the request is known
1.1102 + * (e.g., "<code>Accept</code>").
1.1103 + * @param value the value associated with it.
1.1104 + * @throws IllegalStateException if already connected
1.1105 + * @throws NullPointerException if key is null
1.1106 + * @see #getRequestProperties()
1.1107 + * @since 1.4
1.1108 + */
1.1109 + public void addRequestProperty(String key, String value) {
1.1110 + if (connected)
1.1111 + throw new IllegalStateException("Already connected");
1.1112 + if (key == null)
1.1113 + throw new NullPointerException ("key is null");
1.1114 +
1.1115 + if (requests == null)
1.1116 + requests = new MessageHeader();
1.1117 +
1.1118 + requests.add(key, value);
1.1119 + }
1.1120 +
1.1121 +
1.1122 + /**
1.1123 + * Returns the value of the named general request property for this
1.1124 + * connection.
1.1125 + *
1.1126 + * @param key the keyword by which the request is known (e.g., "Accept").
1.1127 + * @return the value of the named general request property for this
1.1128 + * connection. If key is null, then null is returned.
1.1129 + * @throws IllegalStateException if already connected
1.1130 + * @see #setRequestProperty(java.lang.String, java.lang.String)
1.1131 + */
1.1132 + public String getRequestProperty(String key) {
1.1133 + if (connected)
1.1134 + throw new IllegalStateException("Already connected");
1.1135 +
1.1136 + if (requests == null)
1.1137 + return null;
1.1138 +
1.1139 + return requests.findValue(key);
1.1140 + }
1.1141 +
1.1142 + /**
1.1143 + * Returns an unmodifiable Map of general request
1.1144 + * properties for this connection. The Map keys
1.1145 + * are Strings that represent the request-header
1.1146 + * field names. Each Map value is a unmodifiable List
1.1147 + * of Strings that represents the corresponding
1.1148 + * field values.
1.1149 + *
1.1150 + * @return a Map of the general request properties for this connection.
1.1151 + * @throws IllegalStateException if already connected
1.1152 + * @since 1.4
1.1153 + */
1.1154 + public Map<String,List<String>> getRequestProperties() {
1.1155 + if (connected)
1.1156 + throw new IllegalStateException("Already connected");
1.1157 +
1.1158 + if (requests == null)
1.1159 + return Collections.EMPTY_MAP;
1.1160 +
1.1161 + return requests.getHeaders(null);
1.1162 + }
1.1163 +
1.1164 + /**
1.1165 + * Sets the default value of a general request property. When a
1.1166 + * <code>URLConnection</code> is created, it is initialized with
1.1167 + * these properties.
1.1168 + *
1.1169 + * @param key the keyword by which the request is known
1.1170 + * (e.g., "<code>Accept</code>").
1.1171 + * @param value the value associated with the key.
1.1172 + *
1.1173 + * @see java.net.URLConnection#setRequestProperty(java.lang.String,java.lang.String)
1.1174 + *
1.1175 + * @deprecated The instance specific setRequestProperty method
1.1176 + * should be used after an appropriate instance of URLConnection
1.1177 + * is obtained. Invoking this method will have no effect.
1.1178 + *
1.1179 + * @see #getDefaultRequestProperty(java.lang.String)
1.1180 + */
1.1181 + @Deprecated
1.1182 + public static void setDefaultRequestProperty(String key, String value) {
1.1183 + }
1.1184 +
1.1185 + /**
1.1186 + * Returns the value of the default request property. Default request
1.1187 + * properties are set for every connection.
1.1188 + *
1.1189 + * @param key the keyword by which the request is known (e.g., "Accept").
1.1190 + * @return the value of the default request property
1.1191 + * for the specified key.
1.1192 + *
1.1193 + * @see java.net.URLConnection#getRequestProperty(java.lang.String)
1.1194 + *
1.1195 + * @deprecated The instance specific getRequestProperty method
1.1196 + * should be used after an appropriate instance of URLConnection
1.1197 + * is obtained.
1.1198 + *
1.1199 + * @see #setDefaultRequestProperty(java.lang.String, java.lang.String)
1.1200 + */
1.1201 + @Deprecated
1.1202 + public static String getDefaultRequestProperty(String key) {
1.1203 + return null;
1.1204 + }
1.1205 +
1.1206 + /**
1.1207 + * The ContentHandler factory.
1.1208 + */
1.1209 + static ContentHandlerFactory factory;
1.1210 +
1.1211 + /**
1.1212 + * Sets the <code>ContentHandlerFactory</code> of an
1.1213 + * application. It can be called at most once by an application.
1.1214 + * <p>
1.1215 + * The <code>ContentHandlerFactory</code> instance is used to
1.1216 + * construct a content handler from a content type
1.1217 + * <p>
1.1218 + * If there is a security manager, this method first calls
1.1219 + * the security manager's <code>checkSetFactory</code> method
1.1220 + * to ensure the operation is allowed.
1.1221 + * This could result in a SecurityException.
1.1222 + *
1.1223 + * @param fac the desired factory.
1.1224 + * @exception Error if the factory has already been defined.
1.1225 + * @exception SecurityException if a security manager exists and its
1.1226 + * <code>checkSetFactory</code> method doesn't allow the operation.
1.1227 + * @see java.net.ContentHandlerFactory
1.1228 + * @see java.net.URLConnection#getContent()
1.1229 + * @see SecurityManager#checkSetFactory
1.1230 + */
1.1231 + public static synchronized void setContentHandlerFactory(ContentHandlerFactory fac) {
1.1232 + if (factory != null) {
1.1233 + throw new Error("factory already defined");
1.1234 + }
1.1235 + SecurityManager security = System.getSecurityManager();
1.1236 + if (security != null) {
1.1237 + security.checkSetFactory();
1.1238 + }
1.1239 + factory = fac;
1.1240 + }
1.1241 +
1.1242 + private static Hashtable handlers = new Hashtable();
1.1243 +
1.1244 + /**
1.1245 + * Gets the Content Handler appropriate for this connection.
1.1246 + * @param connection the connection to use.
1.1247 + */
1.1248 + synchronized ContentHandler getContentHandler()
1.1249 + throws UnknownServiceException
1.1250 + {
1.1251 + String contentType = stripOffParameters(getContentType());
1.1252 + ContentHandler handler = null;
1.1253 + if (contentType == null)
1.1254 + throw new UnknownServiceException("no content-type");
1.1255 + try {
1.1256 + handler = (ContentHandler) handlers.get(contentType);
1.1257 + if (handler != null)
1.1258 + return handler;
1.1259 + } catch(Exception e) {
1.1260 + }
1.1261 +
1.1262 + if (factory != null)
1.1263 + handler = factory.createContentHandler(contentType);
1.1264 + if (handler == null) {
1.1265 + try {
1.1266 + handler = lookupContentHandlerClassFor(contentType);
1.1267 + } catch(Exception e) {
1.1268 + e.printStackTrace();
1.1269 + handler = UnknownContentHandler.INSTANCE;
1.1270 + }
1.1271 + handlers.put(contentType, handler);
1.1272 + }
1.1273 + return handler;
1.1274 + }
1.1275 +
1.1276 + /*
1.1277 + * Media types are in the format: type/subtype*(; parameter).
1.1278 + * For looking up the content handler, we should ignore those
1.1279 + * parameters.
1.1280 + */
1.1281 + private String stripOffParameters(String contentType)
1.1282 + {
1.1283 + if (contentType == null)
1.1284 + return null;
1.1285 + int index = contentType.indexOf(';');
1.1286 +
1.1287 + if (index > 0)
1.1288 + return contentType.substring(0, index);
1.1289 + else
1.1290 + return contentType;
1.1291 + }
1.1292 +
1.1293 + private static final String contentClassPrefix = "sun.net.www.content";
1.1294 + private static final String contentPathProp = "java.content.handler.pkgs";
1.1295 +
1.1296 + /**
1.1297 + * Looks for a content handler in a user-defineable set of places.
1.1298 + * By default it looks in sun.net.www.content, but users can define a
1.1299 + * vertical-bar delimited set of class prefixes to search through in
1.1300 + * addition by defining the java.content.handler.pkgs property.
1.1301 + * The class name must be of the form:
1.1302 + * <pre>
1.1303 + * {package-prefix}.{major}.{minor}
1.1304 + * e.g.
1.1305 + * YoyoDyne.experimental.text.plain
1.1306 + * </pre>
1.1307 + */
1.1308 + private ContentHandler lookupContentHandlerClassFor(String contentType)
1.1309 + throws InstantiationException, IllegalAccessException, ClassNotFoundException {
1.1310 + String contentHandlerClassName = typeToPackageName(contentType);
1.1311 +
1.1312 + String contentHandlerPkgPrefixes =getContentHandlerPkgPrefixes();
1.1313 +
1.1314 + StringTokenizer packagePrefixIter =
1.1315 + new StringTokenizer(contentHandlerPkgPrefixes, "|");
1.1316 +
1.1317 + while (packagePrefixIter.hasMoreTokens()) {
1.1318 + String packagePrefix = packagePrefixIter.nextToken().trim();
1.1319 +
1.1320 + try {
1.1321 + String clsName = packagePrefix + "." + contentHandlerClassName;
1.1322 + Class cls = null;
1.1323 + try {
1.1324 + cls = Class.forName(clsName);
1.1325 + } catch (ClassNotFoundException e) {
1.1326 + ClassLoader cl = ClassLoader.getSystemClassLoader();
1.1327 + if (cl != null) {
1.1328 + cls = cl.loadClass(clsName);
1.1329 + }
1.1330 + }
1.1331 + if (cls != null) {
1.1332 + ContentHandler handler =
1.1333 + (ContentHandler)cls.newInstance();
1.1334 + return handler;
1.1335 + }
1.1336 + } catch(Exception e) {
1.1337 + }
1.1338 + }
1.1339 +
1.1340 + return UnknownContentHandler.INSTANCE;
1.1341 + }
1.1342 +
1.1343 + /**
1.1344 + * Utility function to map a MIME content type into an equivalent
1.1345 + * pair of class name components. For example: "text/html" would
1.1346 + * be returned as "text.html"
1.1347 + */
1.1348 + private String typeToPackageName(String contentType) {
1.1349 + // make sure we canonicalize the class name: all lower case
1.1350 + contentType = contentType.toLowerCase();
1.1351 + int len = contentType.length();
1.1352 + char nm[] = new char[len];
1.1353 + contentType.getChars(0, len, nm, 0);
1.1354 + for (int i = 0; i < len; i++) {
1.1355 + char c = nm[i];
1.1356 + if (c == '/') {
1.1357 + nm[i] = '.';
1.1358 + } else if (!('A' <= c && c <= 'Z' ||
1.1359 + 'a' <= c && c <= 'z' ||
1.1360 + '0' <= c && c <= '9')) {
1.1361 + nm[i] = '_';
1.1362 + }
1.1363 + }
1.1364 + return new String(nm);
1.1365 + }
1.1366 +
1.1367 +
1.1368 + /**
1.1369 + * Returns a vertical bar separated list of package prefixes for potential
1.1370 + * content handlers. Tries to get the java.content.handler.pkgs property
1.1371 + * to use as a set of package prefixes to search. Whether or not
1.1372 + * that property has been defined, the sun.net.www.content is always
1.1373 + * the last one on the returned package list.
1.1374 + */
1.1375 + private String getContentHandlerPkgPrefixes() {
1.1376 + String packagePrefixList = AccessController.doPrivileged(
1.1377 + new sun.security.action.GetPropertyAction(contentPathProp, ""));
1.1378 +
1.1379 + if (packagePrefixList != "") {
1.1380 + packagePrefixList += "|";
1.1381 + }
1.1382 +
1.1383 + return packagePrefixList + contentClassPrefix;
1.1384 + }
1.1385 +
1.1386 + /**
1.1387 + * Tries to determine the content type of an object, based
1.1388 + * on the specified "file" component of a URL.
1.1389 + * This is a convenience method that can be used by
1.1390 + * subclasses that override the <code>getContentType</code> method.
1.1391 + *
1.1392 + * @param fname a filename.
1.1393 + * @return a guess as to what the content type of the object is,
1.1394 + * based upon its file name.
1.1395 + * @see java.net.URLConnection#getContentType()
1.1396 + */
1.1397 + public static String guessContentTypeFromName(String fname) {
1.1398 + return getFileNameMap().getContentTypeFor(fname);
1.1399 + }
1.1400 +
1.1401 + /**
1.1402 + * Tries to determine the type of an input stream based on the
1.1403 + * characters at the beginning of the input stream. This method can
1.1404 + * be used by subclasses that override the
1.1405 + * <code>getContentType</code> method.
1.1406 + * <p>
1.1407 + * Ideally, this routine would not be needed. But many
1.1408 + * <code>http</code> servers return the incorrect content type; in
1.1409 + * addition, there are many nonstandard extensions. Direct inspection
1.1410 + * of the bytes to determine the content type is often more accurate
1.1411 + * than believing the content type claimed by the <code>http</code> server.
1.1412 + *
1.1413 + * @param is an input stream that supports marks.
1.1414 + * @return a guess at the content type, or <code>null</code> if none
1.1415 + * can be determined.
1.1416 + * @exception IOException if an I/O error occurs while reading the
1.1417 + * input stream.
1.1418 + * @see java.io.InputStream#mark(int)
1.1419 + * @see java.io.InputStream#markSupported()
1.1420 + * @see java.net.URLConnection#getContentType()
1.1421 + */
1.1422 + static public String guessContentTypeFromStream(InputStream is)
1.1423 + throws IOException {
1.1424 + // If we can't read ahead safely, just give up on guessing
1.1425 + if (!is.markSupported())
1.1426 + return null;
1.1427 +
1.1428 + is.mark(16);
1.1429 + int c1 = is.read();
1.1430 + int c2 = is.read();
1.1431 + int c3 = is.read();
1.1432 + int c4 = is.read();
1.1433 + int c5 = is.read();
1.1434 + int c6 = is.read();
1.1435 + int c7 = is.read();
1.1436 + int c8 = is.read();
1.1437 + int c9 = is.read();
1.1438 + int c10 = is.read();
1.1439 + int c11 = is.read();
1.1440 + int c12 = is.read();
1.1441 + int c13 = is.read();
1.1442 + int c14 = is.read();
1.1443 + int c15 = is.read();
1.1444 + int c16 = is.read();
1.1445 + is.reset();
1.1446 +
1.1447 + if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) {
1.1448 + return "application/java-vm";
1.1449 + }
1.1450 +
1.1451 + if (c1 == 0xAC && c2 == 0xED) {
1.1452 + // next two bytes are version number, currently 0x00 0x05
1.1453 + return "application/x-java-serialized-object";
1.1454 + }
1.1455 +
1.1456 + if (c1 == '<') {
1.1457 + if (c2 == '!'
1.1458 + || ((c2 == 'h' && (c3 == 't' && c4 == 'm' && c5 == 'l' ||
1.1459 + c3 == 'e' && c4 == 'a' && c5 == 'd') ||
1.1460 + (c2 == 'b' && c3 == 'o' && c4 == 'd' && c5 == 'y'))) ||
1.1461 + ((c2 == 'H' && (c3 == 'T' && c4 == 'M' && c5 == 'L' ||
1.1462 + c3 == 'E' && c4 == 'A' && c5 == 'D') ||
1.1463 + (c2 == 'B' && c3 == 'O' && c4 == 'D' && c5 == 'Y')))) {
1.1464 + return "text/html";
1.1465 + }
1.1466 +
1.1467 + if (c2 == '?' && c3 == 'x' && c4 == 'm' && c5 == 'l' && c6 == ' ') {
1.1468 + return "application/xml";
1.1469 + }
1.1470 + }
1.1471 +
1.1472 + // big and little (identical) endian UTF-8 encodings, with BOM
1.1473 + if (c1 == 0xef && c2 == 0xbb && c3 == 0xbf) {
1.1474 + if (c4 == '<' && c5 == '?' && c6 == 'x') {
1.1475 + return "application/xml";
1.1476 + }
1.1477 + }
1.1478 +
1.1479 + // big and little endian UTF-16 encodings, with byte order mark
1.1480 + if (c1 == 0xfe && c2 == 0xff) {
1.1481 + if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' &&
1.1482 + c7 == 0 && c8 == 'x') {
1.1483 + return "application/xml";
1.1484 + }
1.1485 + }
1.1486 +
1.1487 + if (c1 == 0xff && c2 == 0xfe) {
1.1488 + if (c3 == '<' && c4 == 0 && c5 == '?' && c6 == 0 &&
1.1489 + c7 == 'x' && c8 == 0) {
1.1490 + return "application/xml";
1.1491 + }
1.1492 + }
1.1493 +
1.1494 + // big and little endian UTF-32 encodings, with BOM
1.1495 + if (c1 == 0x00 && c2 == 0x00 && c3 == 0xfe && c4 == 0xff) {
1.1496 + if (c5 == 0 && c6 == 0 && c7 == 0 && c8 == '<' &&
1.1497 + c9 == 0 && c10 == 0 && c11 == 0 && c12 == '?' &&
1.1498 + c13 == 0 && c14 == 0 && c15 == 0 && c16 == 'x') {
1.1499 + return "application/xml";
1.1500 + }
1.1501 + }
1.1502 +
1.1503 + if (c1 == 0xff && c2 == 0xfe && c3 == 0x00 && c4 == 0x00) {
1.1504 + if (c5 == '<' && c6 == 0 && c7 == 0 && c8 == 0 &&
1.1505 + c9 == '?' && c10 == 0 && c11 == 0 && c12 == 0 &&
1.1506 + c13 == 'x' && c14 == 0 && c15 == 0 && c16 == 0) {
1.1507 + return "application/xml";
1.1508 + }
1.1509 + }
1.1510 +
1.1511 + if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') {
1.1512 + return "image/gif";
1.1513 + }
1.1514 +
1.1515 + if (c1 == '#' && c2 == 'd' && c3 == 'e' && c4 == 'f') {
1.1516 + return "image/x-bitmap";
1.1517 + }
1.1518 +
1.1519 + if (c1 == '!' && c2 == ' ' && c3 == 'X' && c4 == 'P' &&
1.1520 + c5 == 'M' && c6 == '2') {
1.1521 + return "image/x-pixmap";
1.1522 + }
1.1523 +
1.1524 + if (c1 == 137 && c2 == 80 && c3 == 78 &&
1.1525 + c4 == 71 && c5 == 13 && c6 == 10 &&
1.1526 + c7 == 26 && c8 == 10) {
1.1527 + return "image/png";
1.1528 + }
1.1529 +
1.1530 + if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) {
1.1531 + if (c4 == 0xE0) {
1.1532 + return "image/jpeg";
1.1533 + }
1.1534 +
1.1535 + /**
1.1536 + * File format used by digital cameras to store images.
1.1537 + * Exif Format can be read by any application supporting
1.1538 + * JPEG. Exif Spec can be found at:
1.1539 + * http://www.pima.net/standards/it10/PIMA15740/Exif_2-1.PDF
1.1540 + */
1.1541 + if ((c4 == 0xE1) &&
1.1542 + (c7 == 'E' && c8 == 'x' && c9 == 'i' && c10 =='f' &&
1.1543 + c11 == 0)) {
1.1544 + return "image/jpeg";
1.1545 + }
1.1546 +
1.1547 + if (c4 == 0xEE) {
1.1548 + return "image/jpg";
1.1549 + }
1.1550 + }
1.1551 +
1.1552 + if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 &&
1.1553 + c5 == 0xA1 && c6 == 0xB1 && c7 == 0x1A && c8 == 0xE1) {
1.1554 +
1.1555 + /* Above is signature of Microsoft Structured Storage.
1.1556 + * Below this, could have tests for various SS entities.
1.1557 + * For now, just test for FlashPix.
1.1558 + */
1.1559 + if (checkfpx(is)) {
1.1560 + return "image/vnd.fpx";
1.1561 + }
1.1562 + }
1.1563 +
1.1564 + if (c1 == 0x2E && c2 == 0x73 && c3 == 0x6E && c4 == 0x64) {
1.1565 + return "audio/basic"; // .au format, big endian
1.1566 + }
1.1567 +
1.1568 + if (c1 == 0x64 && c2 == 0x6E && c3 == 0x73 && c4 == 0x2E) {
1.1569 + return "audio/basic"; // .au format, little endian
1.1570 + }
1.1571 +
1.1572 + if (c1 == 'R' && c2 == 'I' && c3 == 'F' && c4 == 'F') {
1.1573 + /* I don't know if this is official but evidence
1.1574 + * suggests that .wav files start with "RIFF" - brown
1.1575 + */
1.1576 + return "audio/x-wav";
1.1577 + }
1.1578 + return null;
1.1579 + }
1.1580 +
1.1581 + /**
1.1582 + * Check for FlashPix image data in InputStream is. Return true if
1.1583 + * the stream has FlashPix data, false otherwise. Before calling this
1.1584 + * method, the stream should have already been checked to be sure it
1.1585 + * contains Microsoft Structured Storage data.
1.1586 + */
1.1587 + static private boolean checkfpx(InputStream is) throws IOException {
1.1588 +
1.1589 + /* Test for FlashPix image data in Microsoft Structured Storage format.
1.1590 + * In general, should do this with calls to an SS implementation.
1.1591 + * Lacking that, need to dig via offsets to get to the FlashPix
1.1592 + * ClassID. Details:
1.1593 + *
1.1594 + * Offset to Fpx ClsID from beginning of stream should be:
1.1595 + *
1.1596 + * FpxClsidOffset = rootEntryOffset + clsidOffset
1.1597 + *
1.1598 + * where: clsidOffset = 0x50.
1.1599 + * rootEntryOffset = headerSize + sectorSize*sectDirStart
1.1600 + * + 128*rootEntryDirectory
1.1601 + *
1.1602 + * where: headerSize = 0x200 (always)
1.1603 + * sectorSize = 2 raised to power of uSectorShift,
1.1604 + * which is found in the header at
1.1605 + * offset 0x1E.
1.1606 + * sectDirStart = found in the header at offset 0x30.
1.1607 + * rootEntryDirectory = in general, should search for
1.1608 + * directory labelled as root.
1.1609 + * We will assume value of 0 (i.e.,
1.1610 + * rootEntry is in first directory)
1.1611 + */
1.1612 +
1.1613 + // Mark the stream so we can reset it. 0x100 is enough for the first
1.1614 + // few reads, but the mark will have to be reset and set again once
1.1615 + // the offset to the root directory entry is computed. That offset
1.1616 + // can be very large and isn't know until the stream has been read from
1.1617 + is.mark(0x100);
1.1618 +
1.1619 + // Get the byte ordering located at 0x1E. 0xFE is Intel,
1.1620 + // 0xFF is other
1.1621 + long toSkip = (long)0x1C;
1.1622 + long posn;
1.1623 +
1.1624 + if ((posn = skipForward(is, toSkip)) < toSkip) {
1.1625 + is.reset();
1.1626 + return false;
1.1627 + }
1.1628 +
1.1629 + int c[] = new int[16];
1.1630 + if (readBytes(c, 2, is) < 0) {
1.1631 + is.reset();
1.1632 + return false;
1.1633 + }
1.1634 +
1.1635 + int byteOrder = c[0];
1.1636 +
1.1637 + posn+=2;
1.1638 + int uSectorShift;
1.1639 + if (readBytes(c, 2, is) < 0) {
1.1640 + is.reset();
1.1641 + return false;
1.1642 + }
1.1643 +
1.1644 + if(byteOrder == 0xFE) {
1.1645 + uSectorShift = c[0];
1.1646 + uSectorShift += c[1] << 8;
1.1647 + }
1.1648 + else {
1.1649 + uSectorShift = c[0] << 8;
1.1650 + uSectorShift += c[1];
1.1651 + }
1.1652 +
1.1653 + posn += 2;
1.1654 + toSkip = (long)0x30 - posn;
1.1655 + long skipped = 0;
1.1656 + if ((skipped = skipForward(is, toSkip)) < toSkip) {
1.1657 + is.reset();
1.1658 + return false;
1.1659 + }
1.1660 + posn += skipped;
1.1661 +
1.1662 + if (readBytes(c, 4, is) < 0) {
1.1663 + is.reset();
1.1664 + return false;
1.1665 + }
1.1666 +
1.1667 + int sectDirStart;
1.1668 + if(byteOrder == 0xFE) {
1.1669 + sectDirStart = c[0];
1.1670 + sectDirStart += c[1] << 8;
1.1671 + sectDirStart += c[2] << 16;
1.1672 + sectDirStart += c[3] << 24;
1.1673 + } else {
1.1674 + sectDirStart = c[0] << 24;
1.1675 + sectDirStart += c[1] << 16;
1.1676 + sectDirStart += c[2] << 8;
1.1677 + sectDirStart += c[3];
1.1678 + }
1.1679 + posn += 4;
1.1680 + is.reset(); // Reset back to the beginning
1.1681 +
1.1682 + toSkip = 0x200L + (long)(1<<uSectorShift)*sectDirStart + 0x50L;
1.1683 +
1.1684 + // Sanity check!
1.1685 + if (toSkip < 0) {
1.1686 + return false;
1.1687 + }
1.1688 +
1.1689 + /*
1.1690 + * How far can we skip? Is there any performance problem here?
1.1691 + * This skip can be fairly long, at least 0x4c650 in at least
1.1692 + * one case. Have to assume that the skip will fit in an int.
1.1693 + * Leave room to read whole root dir
1.1694 + */
1.1695 + is.mark((int)toSkip+0x30);
1.1696 +
1.1697 + if ((skipForward(is, toSkip)) < toSkip) {
1.1698 + is.reset();
1.1699 + return false;
1.1700 + }
1.1701 +
1.1702 + /* should be at beginning of ClassID, which is as follows
1.1703 + * (in Intel byte order):
1.1704 + * 00 67 61 56 54 C1 CE 11 85 53 00 AA 00 A1 F9 5B
1.1705 + *
1.1706 + * This is stored from Windows as long,short,short,char[8]
1.1707 + * so for byte order changes, the order only changes for
1.1708 + * the first 8 bytes in the ClassID.
1.1709 + *
1.1710 + * Test against this, ignoring second byte (Intel) since
1.1711 + * this could change depending on part of Fpx file we have.
1.1712 + */
1.1713 +
1.1714 + if (readBytes(c, 16, is) < 0) {
1.1715 + is.reset();
1.1716 + return false;
1.1717 + }
1.1718 +
1.1719 + // intel byte order
1.1720 + if (byteOrder == 0xFE &&
1.1721 + c[0] == 0x00 && c[2] == 0x61 && c[3] == 0x56 &&
1.1722 + c[4] == 0x54 && c[5] == 0xC1 && c[6] == 0xCE &&
1.1723 + c[7] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
1.1724 + c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
1.1725 + c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
1.1726 + is.reset();
1.1727 + return true;
1.1728 + }
1.1729 +
1.1730 + // non-intel byte order
1.1731 + else if (c[3] == 0x00 && c[1] == 0x61 && c[0] == 0x56 &&
1.1732 + c[5] == 0x54 && c[4] == 0xC1 && c[7] == 0xCE &&
1.1733 + c[6] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
1.1734 + c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
1.1735 + c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
1.1736 + is.reset();
1.1737 + return true;
1.1738 + }
1.1739 + is.reset();
1.1740 + return false;
1.1741 + }
1.1742 +
1.1743 + /**
1.1744 + * Tries to read the specified number of bytes from the stream
1.1745 + * Returns -1, If EOF is reached before len bytes are read, returns 0
1.1746 + * otherwise
1.1747 + */
1.1748 + static private int readBytes(int c[], int len, InputStream is)
1.1749 + throws IOException {
1.1750 +
1.1751 + byte buf[] = new byte[len];
1.1752 + if (is.read(buf, 0, len) < len) {
1.1753 + return -1;
1.1754 + }
1.1755 +
1.1756 + // fill the passed in int array
1.1757 + for (int i = 0; i < len; i++) {
1.1758 + c[i] = buf[i] & 0xff;
1.1759 + }
1.1760 + return 0;
1.1761 + }
1.1762 +
1.1763 +
1.1764 + /**
1.1765 + * Skips through the specified number of bytes from the stream
1.1766 + * until either EOF is reached, or the specified
1.1767 + * number of bytes have been skipped
1.1768 + */
1.1769 + static private long skipForward(InputStream is, long toSkip)
1.1770 + throws IOException {
1.1771 +
1.1772 + long eachSkip = 0;
1.1773 + long skipped = 0;
1.1774 +
1.1775 + while (skipped != toSkip) {
1.1776 + eachSkip = is.skip(toSkip - skipped);
1.1777 +
1.1778 + // check if EOF is reached
1.1779 + if (eachSkip <= 0) {
1.1780 + if (is.read() == -1) {
1.1781 + return skipped ;
1.1782 + } else {
1.1783 + skipped++;
1.1784 + }
1.1785 + }
1.1786 + skipped += eachSkip;
1.1787 + }
1.1788 + return skipped;
1.1789 + }
1.1790 +
1.1791 +}
1.1792 +
1.1793 +
1.1794 +class UnknownContentHandler extends ContentHandler {
1.1795 + static final ContentHandler INSTANCE = new UnknownContentHandler();
1.1796 +
1.1797 + public Object getContent(URLConnection uc) throws IOException {
1.1798 + return uc.getInputStream();
1.1799 + }
1.1800 +}