2007-12-01 00:00:00 +00:00
/ *
2016-01-06 10:15:37 -08:00
* Copyright ( c ) 1995 , 2016 , Oracle and / or its affiliates . All rights reserved .
2007-12-01 00:00:00 +00:00
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
2010-05-25 15:58:33 -07:00
* published by the Free Software Foundation . Oracle designates this
2007-12-01 00:00:00 +00:00
* particular file as subject to the " Classpath " exception as provided
2010-05-25 15:58:33 -07:00
* by Oracle in the LICENSE file that accompanied this code .
2007-12-01 00:00:00 +00:00
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
2010-05-25 15:58:33 -07:00
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
2007-12-01 00:00:00 +00:00
* /
package java.net ;
import java.io.IOException ;
import java.io.InputStream ;
import java.io.OutputStream ;
2015-07-10 16:40:12 +01:00
import java.security.PrivilegedAction ;
2007-12-01 00:00:00 +00:00
import java.util.Hashtable ;
2017-01-12 18:02:48 +00:00
import java.util.concurrent.ConcurrentHashMap ;
2007-12-01 00:00:00 +00:00
import java.util.Date ;
2015-07-10 16:40:12 +01:00
import java.util.Iterator ;
2017-01-12 18:02:48 +00:00
import java.util.Locale ;
2015-11-11 22:38:15 -05:00
import java.util.Objects ;
2015-07-10 16:40:12 +01:00
import java.util.ServiceConfigurationError ;
import java.util.ServiceLoader ;
2007-12-01 00:00:00 +00:00
import java.util.StringTokenizer ;
import java.util.Collections ;
import java.util.Map ;
import java.util.List ;
import java.security.Permission ;
import java.security.AccessController ;
import sun.security.util.SecurityConstants ;
import sun.net.www.MessageHeader ;
2016-04-21 13:39:53 +02:00
import sun.security.action.GetPropertyAction ;
2007-12-01 00:00:00 +00:00
/ * *
2013-07-30 11:04:19 -07:00
* The abstract class { @ code URLConnection } is the superclass
2007-12-01 00:00:00 +00:00
* of all classes that represent a communications link between the
* application and a URL . Instances of this class can be used both to
* read from and to write to the resource referenced by the URL . In
* general , creating a connection to a URL is a multistep process :
2013-10-22 17:02:08 -04:00
*
2017-04-27 09:47:40 -07:00
* < div style = " text-align:center " > < table style = " margin:0 auto " border = 2 summary = " Describes the process of creating a connection to a URL: openConnection() and connect() over time. " >
2013-07-30 11:04:19 -07:00
* < tr > < th > { @code openConnection ( ) } < / th >
* < th > { @code connect ( ) } < / th > < / tr >
2007-12-01 00:00:00 +00:00
* < tr > < td > Manipulate parameters that affect the connection to the remote
* resource . < / td >
* < td > Interact with the resource ; query header fields and
* contents . < / td > < / tr >
* < / table >
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - & gt ;
2017-04-27 09:47:40 -07:00
* < br > time < / div >
2007-12-01 00:00:00 +00:00
*
* < ol >
* < li > The connection object is created by invoking the
2013-07-30 11:04:19 -07:00
* { @code openConnection } method on a URL .
2007-12-01 00:00:00 +00:00
* < li > The setup parameters and general request properties are manipulated .
* < li > The actual connection to the remote object is made , using the
2013-07-30 11:04:19 -07:00
* { @code connect } method .
2007-12-01 00:00:00 +00:00
* < li > The remote object becomes available . The header fields and the contents
* of the remote object can be accessed .
* < / ol >
* < p >
* The setup parameters are modified using the following methods :
* < ul >
2013-07-30 11:04:19 -07:00
* < li > { @code setAllowUserInteraction }
* < li > { @code setDoInput }
* < li > { @code setDoOutput }
* < li > { @code setIfModifiedSince }
* < li > { @code setUseCaches }
2007-12-01 00:00:00 +00:00
* < / ul >
* < p >
* and the general request properties are modified using the method :
* < ul >
2013-07-30 11:04:19 -07:00
* < li > { @code setRequestProperty }
2007-12-01 00:00:00 +00:00
* < / ul >
* < p >
2013-07-30 11:04:19 -07:00
* Default values for the { @code AllowUserInteraction } and
* { @code UseCaches } parameters can be set using the methods
* { @code setDefaultAllowUserInteraction } and
* { @code setDefaultUseCaches } .
2007-12-01 00:00:00 +00:00
* < p >
2013-07-30 11:04:19 -07:00
* Each of the above { @code set } methods has a corresponding
* { @code get } method to retrieve the value of the parameter or
2007-12-01 00:00:00 +00:00
* general request property . The specific parameters and general
* request properties that are applicable are protocol specific .
* < p >
* The following methods are used to access the header fields and
* the contents after the connection is made to the remote object :
* < ul >
2013-07-30 11:04:19 -07:00
* < li > { @code getContent }
* < li > { @code getHeaderField }
* < li > { @code getInputStream }
* < li > { @code getOutputStream }
2007-12-01 00:00:00 +00:00
* < / ul >
* < p >
* Certain header fields are accessed frequently . The methods :
* < ul >
2013-07-30 11:04:19 -07:00
* < li > { @code getContentEncoding }
* < li > { @code getContentLength }
* < li > { @code getContentType }
* < li > { @code getDate }
* < li > { @code getExpiration }
2015-07-10 16:40:12 +01:00
* < li > { @code getLastModified }
2007-12-01 00:00:00 +00:00
* < / ul >
* < p >
* provide convenient access to these fields . The
2013-07-30 11:04:19 -07:00
* { @code getContentType } method is used by the
* { @code getContent } method to determine the type of the remote
2007-12-01 00:00:00 +00:00
* object ; subclasses may find it convenient to override the
2013-07-30 11:04:19 -07:00
* { @code getContentType } method .
2007-12-01 00:00:00 +00:00
* < p >
* In the common case , all of the pre - connection parameters and
* general request properties can be ignored : the pre - connection
* parameters and request properties default to sensible values . For
* most clients of this interface , there are only two interesting
2013-07-30 11:04:19 -07:00
* methods : { @code getInputStream } and { @code getContent } ,
* which are mirrored in the { @code URL } class by convenience methods .
2007-12-01 00:00:00 +00:00
* < p >
* More information on the request properties and header fields of
2013-07-30 11:04:19 -07:00
* an { @code http } connection can be found at :
2007-12-01 00:00:00 +00:00
* < blockquote > < pre >
* < a href = " http://www.ietf.org/rfc/rfc2616.txt " > http : //www.ietf.org/rfc/rfc2616.txt</a>
* < / pre > < / blockquote >
*
2013-07-30 11:04:19 -07:00
* Invoking the { @code close ( ) } methods on the { @code InputStream } or { @code OutputStream } of an
* { @code URLConnection } after a request may free network resources associated with this
2007-12-01 00:00:00 +00:00
* instance , unless particular protocol specifications specify different behaviours
* for it .
*
* @author James Gosling
* @see java . net . URL # openConnection ( )
* @see java . net . URLConnection # connect ( )
* @see java . net . URLConnection # getContent ( )
* @see java . net . URLConnection # getContentEncoding ( )
* @see java . net . URLConnection # getContentLength ( )
* @see java . net . URLConnection # getContentType ( )
* @see java . net . URLConnection # getDate ( )
* @see java . net . URLConnection # getExpiration ( )
* @see java . net . URLConnection # getHeaderField ( int )
* @see java . net . URLConnection # getHeaderField ( java . lang . String )
* @see java . net . URLConnection # getInputStream ( )
* @see java . net . URLConnection # getLastModified ( )
* @see java . net . URLConnection # getOutputStream ( )
* @see java . net . URLConnection # setAllowUserInteraction ( boolean )
* @see java . net . URLConnection # setDefaultUseCaches ( boolean )
* @see java . net . URLConnection # setDoInput ( boolean )
* @see java . net . URLConnection # setDoOutput ( boolean )
* @see java . net . URLConnection # setIfModifiedSince ( long )
* @see java . net . URLConnection # setRequestProperty ( java . lang . String , java . lang . String )
* @see java . net . URLConnection # setUseCaches ( boolean )
2014-06-10 16:18:54 -07:00
* @since 1 . 0
2007-12-01 00:00:00 +00:00
* /
public abstract class URLConnection {
/ * *
* The URL represents the remote object on the World Wide Web to
* which this connection is opened .
* < p >
* The value of this field can be accessed by the
2013-07-30 11:04:19 -07:00
* { @code getURL } method .
2007-12-01 00:00:00 +00:00
* < p >
* The default value of this variable is the value of the URL
2013-07-30 11:04:19 -07:00
* argument in the { @code URLConnection } constructor .
2007-12-01 00:00:00 +00:00
*
* @see java . net . URLConnection # getURL ( )
* @see java . net . URLConnection # url
* /
protected URL url ;
/ * *
2013-07-30 11:04:19 -07:00
* This variable is set by the { @code setDoInput } method . Its
* value is returned by the { @code getDoInput } method .
2007-12-01 00:00:00 +00:00
* < p >
* A URL connection can be used for input and / or output . Setting the
2013-07-30 11:04:19 -07:00
* { @code doInput } flag to { @code true } indicates that
2007-12-01 00:00:00 +00:00
* the application intends to read data from the URL connection .
* < p >
2013-07-30 11:04:19 -07:00
* The default value of this field is { @code true } .
2007-12-01 00:00:00 +00:00
*
* @see java . net . URLConnection # getDoInput ( )
* @see java . net . URLConnection # setDoInput ( boolean )
* /
protected boolean doInput = true ;
/ * *
2013-07-30 11:04:19 -07:00
* This variable is set by the { @code setDoOutput } method . Its
* value is returned by the { @code getDoOutput } method .
2007-12-01 00:00:00 +00:00
* < p >
* A URL connection can be used for input and / or output . Setting the
2013-07-30 11:04:19 -07:00
* { @code doOutput } flag to { @code true } indicates
2007-12-01 00:00:00 +00:00
* that the application intends to write data to the URL connection .
* < p >
2013-07-30 11:04:19 -07:00
* The default value of this field is { @code false } .
2007-12-01 00:00:00 +00:00
*
* @see java . net . URLConnection # getDoOutput ( )
* @see java . net . URLConnection # setDoOutput ( boolean )
* /
protected boolean doOutput = false ;
private static boolean defaultAllowUserInteraction = false ;
/ * *
2013-07-30 11:04:19 -07:00
* If { @code true } , this { @code URL } is being examined in
2007-12-01 00:00:00 +00:00
* a context in which it makes sense to allow user interactions such
2013-07-30 11:04:19 -07:00
* as popping up an authentication dialog . If { @code false } ,
2007-12-01 00:00:00 +00:00
* then no user interaction is allowed .
* < p >
* The value of this field can be set by the
2013-07-30 11:04:19 -07:00
* { @code setAllowUserInteraction } method .
2007-12-01 00:00:00 +00:00
* Its value is returned by the
2013-07-30 11:04:19 -07:00
* { @code getAllowUserInteraction } method .
2007-12-01 00:00:00 +00:00
* Its default value is the value of the argument in the last invocation
2013-07-30 11:04:19 -07:00
* of the { @code setDefaultAllowUserInteraction } method .
2007-12-01 00:00:00 +00:00
*
* @see java . net . URLConnection # getAllowUserInteraction ( )
* @see java . net . URLConnection # setAllowUserInteraction ( boolean )
* @see java . net . URLConnection # setDefaultAllowUserInteraction ( boolean )
* /
protected boolean allowUserInteraction = defaultAllowUserInteraction ;
2017-01-12 18:02:48 +00:00
private static volatile boolean defaultUseCaches = true ;
2007-12-01 00:00:00 +00:00
/ * *
2013-07-30 11:04:19 -07:00
* If { @code true } , the protocol is allowed to use caching
* whenever it can . If { @code false } , the protocol must always
2007-12-01 00:00:00 +00:00
* try to get a fresh copy of the object .
* < p >
2013-07-30 11:04:19 -07:00
* This field is set by the { @code setUseCaches } method . Its
* value is returned by the { @code getUseCaches } method .
2007-12-01 00:00:00 +00:00
* < p >
* Its default value is the value given in the last invocation of the
2013-07-30 11:04:19 -07:00
* { @code setDefaultUseCaches } method .
2017-01-12 18:02:48 +00:00
* < p >
* The default setting may be overridden per protocol with
* { @link # setDefaultUseCaches ( String , boolean ) } .
2007-12-01 00:00:00 +00:00
*
* @see java . net . URLConnection # setUseCaches ( boolean )
* @see java . net . URLConnection # getUseCaches ( )
* @see java . net . URLConnection # setDefaultUseCaches ( boolean )
* /
2017-01-12 18:02:48 +00:00
protected boolean useCaches ;
private static final ConcurrentHashMap < String , Boolean > defaultCaching =
new ConcurrentHashMap < > ( ) ;
2007-12-01 00:00:00 +00:00
/ * *
* Some protocols support skipping the fetching of the object unless
* the object has been modified more recently than a certain time .
* < p >
* A nonzero value gives a time as the number of milliseconds since
* January 1 , 1970 , GMT . The object is fetched only if it has been
* modified more recently than that time .
* < p >
2013-07-30 11:04:19 -07:00
* This variable is set by the { @code setIfModifiedSince }
2007-12-01 00:00:00 +00:00
* method . Its value is returned by the
2013-07-30 11:04:19 -07:00
* { @code getIfModifiedSince } method .
2007-12-01 00:00:00 +00:00
* < p >
2013-07-30 11:04:19 -07:00
* The default value of this field is { @code 0 } , indicating
2007-12-01 00:00:00 +00:00
* that the fetching must always occur .
*
* @see java . net . URLConnection # getIfModifiedSince ( )
* @see java . net . URLConnection # setIfModifiedSince ( long )
* /
protected long ifModifiedSince = 0 ;
/ * *
2013-07-30 11:04:19 -07:00
* If { @code false } , this connection object has not created a
* communications link to the specified URL . If { @code true } ,
2007-12-01 00:00:00 +00:00
* the communications link has been established .
* /
protected boolean connected = false ;
/ * *
* @since 1 . 5
* /
private int connectTimeout ;
private int readTimeout ;
/ * *
* @since 1 . 6
* /
private MessageHeader requests ;
/ * *
2014-06-10 16:18:54 -07:00
* @since 1 . 1
2007-12-01 00:00:00 +00:00
* /
2016-08-08 13:57:51 -07:00
private static volatile FileNameMap fileNameMap ;
2007-12-01 00:00:00 +00:00
/ * *
* Loads filename map ( a mimetable ) from a data file . It will
* first try to load the user - specific table , defined
* by & quot ; content . types . user . table & quot ; property . If that fails ,
2012-12-15 15:07:35 +00:00
* it tries to load the default built - in table .
2007-12-01 00:00:00 +00:00
*
* @return the FileNameMap
* @since 1 . 2
* @see # setFileNameMap ( java . net . FileNameMap )
* /
2016-08-08 13:57:51 -07:00
public static FileNameMap getFileNameMap ( ) {
FileNameMap map = fileNameMap ;
if ( map = = null ) {
fileNameMap = map = new FileNameMap ( ) {
private FileNameMap internalMap =
sun . net . www . MimeTable . loadTable ( ) ;
public String getContentTypeFor ( String fileName ) {
return internalMap . getContentTypeFor ( fileName ) ;
}
} ;
2007-12-01 00:00:00 +00:00
}
2016-08-08 13:57:51 -07:00
return map ;
2007-12-01 00:00:00 +00:00
}
/ * *
* Sets the FileNameMap .
* < p >
* If there is a security manager , this method first calls
2013-07-30 11:04:19 -07:00
* the security manager ' s { @code checkSetFactory } method
2007-12-01 00:00:00 +00:00
* to ensure the operation is allowed .
* This could result in a SecurityException .
*
* @param map the FileNameMap to be set
* @exception SecurityException if a security manager exists and its
2013-07-30 11:04:19 -07:00
* { @code checkSetFactory } method doesn ' t allow the operation .
2007-12-01 00:00:00 +00:00
* @see SecurityManager # checkSetFactory
* @see # getFileNameMap ( )
* @since 1 . 2
* /
public static void setFileNameMap ( FileNameMap map ) {
SecurityManager sm = System . getSecurityManager ( ) ;
if ( sm ! = null ) sm . checkSetFactory ( ) ;
fileNameMap = map ;
}
/ * *
* Opens a communications link to the resource referenced by this
* URL , if such a connection has not already been established .
* < p >
2013-07-30 11:04:19 -07:00
* If the { @code connect } method is called when the connection
* has already been opened ( indicated by the { @code connected }
* field having the value { @code true } ) , the call is ignored .
2007-12-01 00:00:00 +00:00
* < p >
* URLConnection objects go through two phases : first they are
* created , then they are connected . After being created , and
* before being connected , various options can be specified
* ( e . g . , doInput and UseCaches ) . After connecting , it is an
* error to try to set them . Operations that depend on being
* connected , like getContentLength , will implicitly perform the
* connection , if necessary .
*
* @throws SocketTimeoutException if the timeout expires before
* the connection can be established
* @exception IOException if an I / O error occurs while opening the
* connection .
* @see java . net . URLConnection # connected
* @see # getConnectTimeout ( )
* @see # setConnectTimeout ( int )
* /
2015-09-15 21:56:04 -07:00
public abstract void connect ( ) throws IOException ;
2007-12-01 00:00:00 +00:00
/ * *
* Sets a specified timeout value , in milliseconds , to be used
* when opening a communications link to the resource referenced
* by this URLConnection . If the timeout expires before the
* connection can be established , a
* java . net . SocketTimeoutException is raised . A timeout of zero is
* interpreted as an infinite timeout .
2013-10-29 17:01:06 +04:00
* < p > Some non - standard implementation of this method may ignore
2007-12-01 00:00:00 +00:00
* the specified timeout . To see the connect timeout set , please
* call getConnectTimeout ( ) .
*
2013-07-30 11:04:19 -07:00
* @param timeout an { @code int } that specifies the connect
2007-12-01 00:00:00 +00:00
* timeout value in milliseconds
* @throws IllegalArgumentException if the timeout parameter is negative
*
* @see # getConnectTimeout ( )
* @see # connect ( )
* @since 1 . 5
* /
public void setConnectTimeout ( int timeout ) {
if ( timeout < 0 ) {
throw new IllegalArgumentException ( " timeout can not be negative " ) ;
}
connectTimeout = timeout ;
}
/ * *
* Returns setting for connect timeout .
* < p >
* 0 return implies that the option is disabled
* ( i . e . , timeout of infinity ) .
*
2013-07-30 11:04:19 -07:00
* @return an { @code int } that indicates the connect timeout
2007-12-01 00:00:00 +00:00
* value in milliseconds
* @see # setConnectTimeout ( int )
* @see # connect ( )
* @since 1 . 5
* /
public int getConnectTimeout ( ) {
return connectTimeout ;
}
/ * *
* Sets the read timeout to a specified timeout , in
* milliseconds . A non - zero value specifies the timeout when
* reading from Input stream when a connection is established to a
* resource . If the timeout expires before there is data available
* for read , a java . net . SocketTimeoutException is raised . A
* timeout of zero is interpreted as an infinite timeout .
*
* < p > Some non - standard implementation of this method ignores the
* specified timeout . To see the read timeout set , please call
* getReadTimeout ( ) .
*
2013-07-30 11:04:19 -07:00
* @param timeout an { @code int } that specifies the timeout
2007-12-01 00:00:00 +00:00
* value to be used in milliseconds
* @throws IllegalArgumentException if the timeout parameter is negative
*
* @see # getReadTimeout ( )
* @see InputStream # read ( )
* @since 1 . 5
* /
public void setReadTimeout ( int timeout ) {
if ( timeout < 0 ) {
throw new IllegalArgumentException ( " timeout can not be negative " ) ;
}
readTimeout = timeout ;
}
/ * *
* Returns setting for read timeout . 0 return implies that the
* option is disabled ( i . e . , timeout of infinity ) .
*
2013-07-30 11:04:19 -07:00
* @return an { @code int } that indicates the read timeout
2007-12-01 00:00:00 +00:00
* value in milliseconds
*
* @see # setReadTimeout ( int )
* @see InputStream # read ( )
* @since 1 . 5
* /
public int getReadTimeout ( ) {
return readTimeout ;
}
/ * *
* Constructs a URL connection to the specified URL . A connection to
* the object referenced by the URL is not created .
*
* @param url the specified URL .
* /
protected URLConnection ( URL url ) {
this . url = url ;
2017-01-12 18:02:48 +00:00
if ( url = = null ) {
this . useCaches = defaultUseCaches ;
} else {
this . useCaches = getDefaultUseCaches ( url . getProtocol ( ) ) ;
}
2007-12-01 00:00:00 +00:00
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of this { @code URLConnection } ' s { @code URL }
2007-12-01 00:00:00 +00:00
* field .
*
2013-07-30 11:04:19 -07:00
* @return the value of this { @code URLConnection } ' s { @code URL }
2007-12-01 00:00:00 +00:00
* field .
* @see java . net . URLConnection # url
* /
public URL getURL ( ) {
return url ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code content - length } header field .
2007-12-01 00:00:00 +00:00
* < P >
* < B > Note < / B > : { @link # getContentLengthLong ( ) getContentLengthLong ( ) }
* should be preferred over this method , since it returns a { @code long }
* instead and is therefore more portable . < / P >
*
* @return the content length of the resource that this connection ' s URL
* references , { @code - 1 } if the content length is not known ,
* or if the content length is greater than Integer . MAX_VALUE .
* /
public int getContentLength ( ) {
long l = getContentLengthLong ( ) ;
if ( l > Integer . MAX_VALUE )
return - 1 ;
return ( int ) l ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code content - length } header field as a
2007-12-01 00:00:00 +00:00
* long .
*
* @return the content length of the resource that this connection ' s URL
2013-07-30 11:04:19 -07:00
* references , or { @code - 1 } if the content length is
2007-12-01 00:00:00 +00:00
* not known .
2014-06-10 16:18:54 -07:00
* @since 1 . 7
2007-12-01 00:00:00 +00:00
* /
public long getContentLengthLong ( ) {
return getHeaderFieldLong ( " content-length " , - 1 ) ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code content - type } header field .
2007-12-01 00:00:00 +00:00
*
* @return the content type of the resource that the URL references ,
2013-07-30 11:04:19 -07:00
* or { @code null } if not known .
2007-12-01 00:00:00 +00:00
* @see java . net . URLConnection # getHeaderField ( java . lang . String )
* /
public String getContentType ( ) {
return getHeaderField ( " content-type " ) ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code content - encoding } header field .
2007-12-01 00:00:00 +00:00
*
* @return the content encoding of the resource that the URL references ,
2013-07-30 11:04:19 -07:00
* or { @code null } if not known .
2007-12-01 00:00:00 +00:00
* @see java . net . URLConnection # getHeaderField ( java . lang . String )
* /
public String getContentEncoding ( ) {
return getHeaderField ( " content-encoding " ) ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code expires } header field .
2007-12-01 00:00:00 +00:00
*
* @return the expiration date of the resource that this URL references ,
* or 0 if not known . The value is the number of milliseconds since
* January 1 , 1970 GMT .
* @see java . net . URLConnection # getHeaderField ( java . lang . String )
* /
public long getExpiration ( ) {
return getHeaderFieldDate ( " expires " , 0 ) ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code date } header field .
2007-12-01 00:00:00 +00:00
*
* @return the sending date of the resource that the URL references ,
2013-07-30 11:04:19 -07:00
* or { @code 0 } if not known . The value returned is the
2007-12-01 00:00:00 +00:00
* number of milliseconds since January 1 , 1970 GMT .
* @see java . net . URLConnection # getHeaderField ( java . lang . String )
* /
public long getDate ( ) {
return getHeaderFieldDate ( " date " , 0 ) ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code last - modified } header field .
2007-12-01 00:00:00 +00:00
* The result is the number of milliseconds since January 1 , 1970 GMT .
*
* @return the date the resource referenced by this
2013-07-30 11:04:19 -07:00
* { @code URLConnection } was last modified , or 0 if not known .
2007-12-01 00:00:00 +00:00
* @see java . net . URLConnection # getHeaderField ( java . lang . String )
* /
public long getLastModified ( ) {
return getHeaderFieldDate ( " last-modified " , 0 ) ;
}
/ * *
* Returns the value of the named header field .
* < p >
* If called on a connection that sets the same header multiple times
* with possibly different values , only the last value is returned .
*
*
* @param name the name of a header field .
2013-07-30 11:04:19 -07:00
* @return the value of the named header field , or { @code null }
2007-12-01 00:00:00 +00:00
* if there is no such field in the header .
* /
public String getHeaderField ( String name ) {
return null ;
}
/ * *
* Returns an unmodifiable Map of the header fields .
* The Map keys are Strings that represent the
* response - header field names . Each Map value is an
* unmodifiable List of Strings that represents
* the corresponding field values .
*
* @return a Map of header fields
* @since 1 . 4
* /
public Map < String , List < String > > getHeaderFields ( ) {
2011-09-16 12:09:04 -07:00
return Collections . emptyMap ( ) ;
2007-12-01 00:00:00 +00:00
}
/ * *
* Returns the value of the named field parsed as a number .
* < p >
2013-07-30 11:04:19 -07:00
* This form of { @code getHeaderField } exists because some
* connection types ( e . g . , { @code http - ng } ) have pre - parsed
2007-12-01 00:00:00 +00:00
* headers . Classes for that connection type can override this method
* and short - circuit the parsing .
*
* @param name the name of the header field .
* @param Default the default value .
* @return the value of the named field , parsed as an integer . The
2013-07-30 11:04:19 -07:00
* { @code Default } value is returned if the field is
2007-12-01 00:00:00 +00:00
* missing or malformed .
* /
public int getHeaderFieldInt ( String name , int Default ) {
String value = getHeaderField ( name ) ;
try {
return Integer . parseInt ( value ) ;
} catch ( Exception e ) { }
return Default ;
}
/ * *
* Returns the value of the named field parsed as a number .
* < p >
2013-07-30 11:04:19 -07:00
* This form of { @code getHeaderField } exists because some
* connection types ( e . g . , { @code http - ng } ) have pre - parsed
2007-12-01 00:00:00 +00:00
* headers . Classes for that connection type can override this method
* and short - circuit the parsing .
*
* @param name the name of the header field .
* @param Default the default value .
* @return the value of the named field , parsed as a long . The
2013-07-30 11:04:19 -07:00
* { @code Default } value is returned if the field is
2007-12-01 00:00:00 +00:00
* missing or malformed .
2014-06-10 16:18:54 -07:00
* @since 1 . 7
2007-12-01 00:00:00 +00:00
* /
public long getHeaderFieldLong ( String name , long Default ) {
String value = getHeaderField ( name ) ;
try {
return Long . parseLong ( value ) ;
} catch ( Exception e ) { }
return Default ;
}
/ * *
* Returns the value of the named field parsed as date .
* The result is the number of milliseconds since January 1 , 1970 GMT
* represented by the named field .
* < p >
2013-07-30 11:04:19 -07:00
* This form of { @code getHeaderField } exists because some
* connection types ( e . g . , { @code http - ng } ) have pre - parsed
2007-12-01 00:00:00 +00:00
* headers . Classes for that connection type can override this method
* and short - circuit the parsing .
*
* @param name the name of the header field .
* @param Default a default value .
* @return the value of the field , parsed as a date . The value of the
2013-07-30 11:04:19 -07:00
* { @code Default } argument is returned if the field is
2007-12-01 00:00:00 +00:00
* missing or malformed .
* /
2011-09-16 12:09:04 -07:00
@SuppressWarnings ( " deprecation " )
2007-12-01 00:00:00 +00:00
public long getHeaderFieldDate ( String name , long Default ) {
String value = getHeaderField ( name ) ;
try {
return Date . parse ( value ) ;
} catch ( Exception e ) { }
return Default ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the key for the { @code n } < sup > th < / sup > header field .
* It returns { @code null } if there are fewer than { @code n + 1 } fields .
2007-12-01 00:00:00 +00:00
*
2013-06-10 12:58:32 +01:00
* @param n an index , where { @code n > = 0 }
2013-07-30 11:04:19 -07:00
* @return the key for the { @code n } < sup > th < / sup > header field ,
* or { @code null } if there are fewer than { @code n + 1 }
2007-12-01 00:00:00 +00:00
* fields .
* /
public String getHeaderFieldKey ( int n ) {
return null ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value for the { @code n } < sup > th < / sup > header field .
* It returns { @code null } if there are fewer than
* { @code n + 1 } fields .
2007-12-01 00:00:00 +00:00
* < p >
* This method can be used in conjunction with the
* { @link # getHeaderFieldKey ( int ) getHeaderFieldKey } method to iterate through all
* the headers in the message .
*
2013-06-10 12:58:32 +01:00
* @param n an index , where { @code n > = 0 }
2013-07-30 11:04:19 -07:00
* @return the value of the { @code n } < sup > th < / sup > header field
* or { @code null } if there are fewer than { @code n + 1 } fields
2007-12-01 00:00:00 +00:00
* @see java . net . URLConnection # getHeaderFieldKey ( int )
* /
public String getHeaderField ( int n ) {
return null ;
}
/ * *
* Retrieves the contents of this URL connection .
* < p >
* This method first determines the content type of the object by
2013-07-30 11:04:19 -07:00
* calling the { @code getContentType } method . If this is
2007-12-01 00:00:00 +00:00
* the first time that the application has seen that specific content
2015-07-10 16:40:12 +01:00
* type , a content handler for that content type is created .
* < p > This is done as follows :
2007-12-01 00:00:00 +00:00
* < ol >
* < li > If the application has set up a content handler factory instance
2013-07-30 11:04:19 -07:00
* using the { @code setContentHandlerFactory } method , the
* { @code createContentHandler } method of that instance is called
2007-12-01 00:00:00 +00:00
* with the content type as an argument ; the result is a content
* handler for that content type .
2015-07-10 16:40:12 +01:00
* < li > If no { @code ContentHandlerFactory } has yet been set up ,
* or if the factory ' s { @code createContentHandler } method
* returns { @code null } , then the { @linkplain java . util . ServiceLoader
* ServiceLoader } mechanism is used to locate { @linkplain
* java . net . ContentHandlerFactory ContentHandlerFactory }
* implementations using the system class
* loader . The order that factories are located is implementation
* specific , and an implementation is free to cache the located
* factories . A { @linkplain java . util . ServiceConfigurationError
* ServiceConfigurationError } , { @code Error } or { @code RuntimeException }
* thrown from the { @code createContentHandler } , if encountered , will
* be propagated to the calling thread . The { @code
* createContentHandler } method of each factory , if instantiated , is
* invoked , with the content type , until a factory returns non - null ,
* or all factories have been exhausted .
* < li > Failing that , this method tries to load a content handler
2014-05-02 19:38:33 +01:00
* class as defined by { @link java . net . ContentHandler ContentHandler } .
* If the class does not exist , or is not a subclass of { @code
* ContentHandler } , then an { @code UnknownServiceException } is thrown .
2007-12-01 00:00:00 +00:00
* < / ol >
*
2013-07-30 11:04:19 -07:00
* @return the object fetched . The { @code instanceof } operator
2007-12-01 00:00:00 +00:00
* should be used to determine the specific kind of object
* returned .
* @exception IOException if an I / O error occurs while
* getting the content .
* @exception UnknownServiceException if the protocol does not support
* the content type .
* @see java . net . ContentHandlerFactory # createContentHandler ( java . lang . String )
* @see java . net . URLConnection # getContentType ( )
* @see java . net . URLConnection # setContentHandlerFactory ( java . net . ContentHandlerFactory )
* /
public Object getContent ( ) throws IOException {
// Must call getInputStream before GetHeaderField gets called
// so that FileNotFoundException has a chance to be thrown up
// from here without being caught.
getInputStream ( ) ;
return getContentHandler ( ) . getContent ( this ) ;
}
/ * *
* Retrieves the contents of this URL connection .
*
2013-07-30 11:04:19 -07:00
* @param classes the { @code Class } array
2007-12-01 00:00:00 +00:00
* indicating the requested types
* @return the object fetched that is the first match of the type
* specified in the classes array . null if none of
* the requested types are supported .
2013-07-30 11:04:19 -07:00
* The { @code instanceof } operator should be used to
2007-12-01 00:00:00 +00:00
* determine the specific kind of object returned .
* @exception IOException if an I / O error occurs while
* getting the content .
* @exception UnknownServiceException if the protocol does not support
* the content type .
* @see java . net . URLConnection # getContent ( )
* @see java . net . ContentHandlerFactory # createContentHandler ( java . lang . String )
* @see java . net . URLConnection # getContent ( java . lang . Class [ ] )
* @see java . net . URLConnection # setContentHandlerFactory ( java . net . ContentHandlerFactory )
* @since 1 . 3
* /
2014-01-07 09:58:16 -08:00
public Object getContent ( Class < ? > [ ] classes ) throws IOException {
2007-12-01 00:00:00 +00:00
// Must call getInputStream before GetHeaderField gets called
// so that FileNotFoundException has a chance to be thrown up
// from here without being caught.
getInputStream ( ) ;
return getContentHandler ( ) . getContent ( this , classes ) ;
}
/ * *
* Returns a permission object representing the permission
* necessary to make the connection represented by this
* object . This method returns null if no permission is
* required to make the connection . By default , this method
2013-07-30 11:04:19 -07:00
* returns { @code java . security . AllPermission } . Subclasses
2007-12-01 00:00:00 +00:00
* should override this method and return the permission
* that best represents the permission required to make a
2013-07-30 11:04:19 -07:00
* a connection to the URL . For example , a { @code URLConnection }
* representing a { @code file : } URL would return a
* { @code java . io . FilePermission } object .
2007-12-01 00:00:00 +00:00
*
* < p > The permission returned may dependent upon the state of the
* connection . For example , the permission before connecting may be
* different from that after connecting . For example , an HTTP
* sever , say foo . com , may redirect the connection to a different
* host , say bar . com . Before connecting the permission returned by
* the connection will represent the permission needed to connect
* to foo . com , while the permission returned after connecting will
* be to bar . com .
*
* < p > Permissions are generally used for two purposes : to protect
* caches of objects obtained through URLConnections , and to check
* the right of a recipient to learn about a particular URL . In
* the first case , the permission should be obtained
* < em > after < / em > the object has been obtained . For example , in an
* HTTP connection , this will represent the permission to connect
* to the host from which the data was ultimately fetched . In the
* second case , the permission should be obtained and tested
* < em > before < / em > connecting .
*
* @return the permission object representing the permission
* necessary to make the connection represented by this
* URLConnection .
*
* @exception IOException if the computation of the permission
* requires network or file I / O and an exception occurs while
* computing it .
* /
public Permission getPermission ( ) throws IOException {
return SecurityConstants . ALL_PERMISSION ;
}
/ * *
* Returns an input stream that reads from this open connection .
*
* A SocketTimeoutException can be thrown when reading from the
* returned input stream if the read timeout expires before data
* is available for read .
*
* @return an input stream that reads from this open connection .
* @exception IOException if an I / O error occurs while
* creating the input stream .
* @exception UnknownServiceException if the protocol does not support
* input .
* @see # setReadTimeout ( int )
* @see # getReadTimeout ( )
* /
public InputStream getInputStream ( ) throws IOException {
throw new UnknownServiceException ( " protocol doesn't support input " ) ;
}
/ * *
* Returns an output stream that writes to this connection .
*
* @return an output stream that writes to this connection .
* @exception IOException if an I / O error occurs while
* creating the output stream .
* @exception UnknownServiceException if the protocol does not support
* output .
* /
public OutputStream getOutputStream ( ) throws IOException {
throw new UnknownServiceException ( " protocol doesn't support output " ) ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns a { @code String } representation of this URL connection .
2007-12-01 00:00:00 +00:00
*
2013-07-30 11:04:19 -07:00
* @return a string representation of this { @code URLConnection } .
2007-12-01 00:00:00 +00:00
* /
public String toString ( ) {
return this . getClass ( ) . getName ( ) + " : " + url ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Sets the value of the { @code doInput } field for this
* { @code URLConnection } to the specified value .
2007-12-01 00:00:00 +00:00
* < p >
* A URL connection can be used for input and / or output . Set the DoInput
* flag to true if you intend to use the URL connection for input ,
* false if not . The default is true .
*
* @param doinput the new value .
* @throws IllegalStateException if already connected
* @see java . net . URLConnection # doInput
* @see # getDoInput ( )
* /
public void setDoInput ( boolean doinput ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
doInput = doinput ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of this { @code URLConnection } ' s
* { @code doInput } flag .
2007-12-01 00:00:00 +00:00
*
2013-07-30 11:04:19 -07:00
* @return the value of this { @code URLConnection } ' s
* { @code doInput } flag .
2007-12-01 00:00:00 +00:00
* @see # setDoInput ( boolean )
* /
public boolean getDoInput ( ) {
return doInput ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Sets the value of the { @code doOutput } field for this
* { @code URLConnection } to the specified value .
2007-12-01 00:00:00 +00:00
* < p >
* A URL connection can be used for input and / or output . Set the DoOutput
* flag to true if you intend to use the URL connection for output ,
* false if not . The default is false .
*
* @param dooutput the new value .
* @throws IllegalStateException if already connected
* @see # getDoOutput ( )
* /
public void setDoOutput ( boolean dooutput ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
doOutput = dooutput ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of this { @code URLConnection } ' s
* { @code doOutput } flag .
2007-12-01 00:00:00 +00:00
*
2013-07-30 11:04:19 -07:00
* @return the value of this { @code URLConnection } ' s
* { @code doOutput } flag .
2007-12-01 00:00:00 +00:00
* @see # setDoOutput ( boolean )
* /
public boolean getDoOutput ( ) {
return doOutput ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Set the value of the { @code allowUserInteraction } field of
* this { @code URLConnection } .
2007-12-01 00:00:00 +00:00
*
* @param allowuserinteraction the new value .
* @throws IllegalStateException if already connected
* @see # getAllowUserInteraction ( )
* /
public void setAllowUserInteraction ( boolean allowuserinteraction ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
allowUserInteraction = allowuserinteraction ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of the { @code allowUserInteraction } field for
2007-12-01 00:00:00 +00:00
* this object .
*
2013-07-30 11:04:19 -07:00
* @return the value of the { @code allowUserInteraction } field for
2007-12-01 00:00:00 +00:00
* this object .
* @see # setAllowUserInteraction ( boolean )
* /
public boolean getAllowUserInteraction ( ) {
return allowUserInteraction ;
}
/ * *
* Sets the default value of the
2013-07-30 11:04:19 -07:00
* { @code allowUserInteraction } field for all future
* { @code URLConnection } objects to the specified value .
2007-12-01 00:00:00 +00:00
*
* @param defaultallowuserinteraction the new value .
* @see # getDefaultAllowUserInteraction ( )
* /
public static void setDefaultAllowUserInteraction ( boolean defaultallowuserinteraction ) {
defaultAllowUserInteraction = defaultallowuserinteraction ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the default value of the { @code allowUserInteraction }
2007-12-01 00:00:00 +00:00
* field .
* < p >
* Ths default is " sticky " , being a part of the static state of all
* URLConnections . This flag applies to the next , and all following
* URLConnections that are created .
*
2013-07-30 11:04:19 -07:00
* @return the default value of the { @code allowUserInteraction }
2007-12-01 00:00:00 +00:00
* field .
* @see # setDefaultAllowUserInteraction ( boolean )
* /
public static boolean getDefaultAllowUserInteraction ( ) {
return defaultAllowUserInteraction ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Sets the value of the { @code useCaches } field of this
* { @code URLConnection } to the specified value .
2007-12-01 00:00:00 +00:00
* < p >
* Some protocols do caching of documents . Occasionally , it is important
* to be able to " tunnel through " and ignore the caches ( e . g . , the
* " reload " button in a browser ) . If the UseCaches flag on a connection
* is true , the connection is allowed to use whatever caches it can .
* If false , caches are to be ignored .
* The default value comes from DefaultUseCaches , which defaults to
2017-01-12 18:02:48 +00:00
* true . A default value can also be set per - protocol using
* { @link # setDefaultUseCaches ( String , boolean ) } .
2007-12-01 00:00:00 +00:00
*
2013-07-30 11:04:19 -07:00
* @param usecaches a { @code boolean } indicating whether
2007-12-01 00:00:00 +00:00
* or not to allow caching
* @throws IllegalStateException if already connected
* @see # getUseCaches ( )
* /
public void setUseCaches ( boolean usecaches ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
useCaches = usecaches ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of this { @code URLConnection } ' s
* { @code useCaches } field .
2007-12-01 00:00:00 +00:00
*
2013-07-30 11:04:19 -07:00
* @return the value of this { @code URLConnection } ' s
* { @code useCaches } field .
2007-12-01 00:00:00 +00:00
* @see # setUseCaches ( boolean )
* /
public boolean getUseCaches ( ) {
return useCaches ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Sets the value of the { @code ifModifiedSince } field of
* this { @code URLConnection } to the specified value .
2007-12-01 00:00:00 +00:00
*
* @param ifmodifiedsince the new value .
* @throws IllegalStateException if already connected
* @see # getIfModifiedSince ( )
* /
public void setIfModifiedSince ( long ifmodifiedsince ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
ifModifiedSince = ifmodifiedsince ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the value of this object ' s { @code ifModifiedSince } field .
2007-12-01 00:00:00 +00:00
*
2013-07-30 11:04:19 -07:00
* @return the value of this object ' s { @code ifModifiedSince } field .
2007-12-01 00:00:00 +00:00
* @see # setIfModifiedSince ( long )
* /
public long getIfModifiedSince ( ) {
return ifModifiedSince ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Returns the default value of a { @code URLConnection } ' s
* { @code useCaches } flag .
2007-12-01 00:00:00 +00:00
* < p >
2017-01-12 18:02:48 +00:00
* This default is " sticky " , being a part of the static state of all
2007-12-01 00:00:00 +00:00
* URLConnections . This flag applies to the next , and all following
2017-01-12 18:02:48 +00:00
* URLConnections that are created . This default value can be over - ridden
* per protocol using { @link # setDefaultUseCaches ( String , boolean ) }
2007-12-01 00:00:00 +00:00
*
2013-07-30 11:04:19 -07:00
* @return the default value of a { @code URLConnection } ' s
* { @code useCaches } flag .
2007-12-01 00:00:00 +00:00
* @see # setDefaultUseCaches ( boolean )
* /
public boolean getDefaultUseCaches ( ) {
return defaultUseCaches ;
}
/ * *
2013-07-30 11:04:19 -07:00
* Sets the default value of the { @code useCaches } field to the
2017-01-12 18:02:48 +00:00
* specified value . This default value can be over - ridden
* per protocol using { @link # setDefaultUseCaches ( String , boolean ) }
2007-12-01 00:00:00 +00:00
*
* @param defaultusecaches the new value .
* @see # getDefaultUseCaches ( )
* /
public void setDefaultUseCaches ( boolean defaultusecaches ) {
defaultUseCaches = defaultusecaches ;
}
2017-01-12 18:02:48 +00:00
/ * *
* Sets the default value of the { @code useCaches } field for the named
* protocol to the given value . This value overrides any default setting
* set by { @link # setDefaultUseCaches ( boolean ) } for the given protocol .
* Successive calls to this method change the setting and affect the
* default value for all future connections of that protocol . The protocol
* name is case insensitive .
*
* @param protocol the protocol to set the default for
* @param defaultVal whether caching is enabled by default for the given protocol
* @since 9
* /
public static void setDefaultUseCaches ( String protocol , boolean defaultVal ) {
protocol = protocol . toLowerCase ( Locale . US ) ;
defaultCaching . put ( protocol , defaultVal ) ;
}
/ * *
* Returns the default value of the { @code useCaches } flag for the given protocol . If
* { @link # setDefaultUseCaches ( String , boolean ) } was called for the given protocol ,
* then that value is returned . Otherwise , if { @link # setDefaultUseCaches ( boolean ) }
* was called , then that value is returned . If neither method was called ,
* the return value is { @code true } . The protocol name is case insensitive .
*
* @param protocol the protocol whose defaultUseCaches setting is required
* @return the default value of the { @code useCaches } flag for the given protocol .
* @since 9
* /
public static boolean getDefaultUseCaches ( String protocol ) {
Boolean protoDefault = defaultCaching . get ( protocol . toLowerCase ( Locale . US ) ) ;
if ( protoDefault ! = null ) {
return protoDefault . booleanValue ( ) ;
} else {
return defaultUseCaches ;
}
}
2007-12-01 00:00:00 +00:00
/ * *
* Sets the general request property . If a property with the key already
* exists , overwrite its value with the new value .
*
* < p > NOTE : HTTP requires all request properties which can
* legally have multiple instances with the same key
2013-10-29 17:01:06 +04:00
* to use a comma - separated list syntax which enables multiple
2007-12-01 00:00:00 +00:00
* properties to be appended into a single property .
*
* @param key the keyword by which the request is known
2013-07-30 11:04:19 -07:00
* ( e . g . , " {@code Accept} " ) .
2007-12-01 00:00:00 +00:00
* @param value the value associated with it .
* @throws IllegalStateException if already connected
2015-07-10 16:40:12 +01:00
* @throws NullPointerException if key is { @code null }
2007-12-01 00:00:00 +00:00
* @see # getRequestProperty ( java . lang . String )
* /
public void setRequestProperty ( String key , String value ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
if ( key = = null )
throw new NullPointerException ( " key is null " ) ;
if ( requests = = null )
requests = new MessageHeader ( ) ;
requests . set ( key , value ) ;
}
/ * *
* Adds a general request property specified by a
* key - value pair . This method will not overwrite
* existing values associated with the same key .
*
* @param key the keyword by which the request is known
2013-07-30 11:04:19 -07:00
* ( e . g . , " {@code Accept} " ) .
2007-12-01 00:00:00 +00:00
* @param value the value associated with it .
* @throws IllegalStateException if already connected
* @throws NullPointerException if key is null
* @see # getRequestProperties ( )
* @since 1 . 4
* /
public void addRequestProperty ( String key , String value ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
if ( key = = null )
throw new NullPointerException ( " key is null " ) ;
if ( requests = = null )
requests = new MessageHeader ( ) ;
requests . add ( key , value ) ;
}
/ * *
* Returns the value of the named general request property for this
* connection .
*
2008-03-07 11:51:27 +00:00
* @param key the keyword by which the request is known ( e . g . , " Accept " ) .
2007-12-01 00:00:00 +00:00
* @return the value of the named general request property for this
* connection . If key is null , then null is returned .
* @throws IllegalStateException if already connected
* @see # setRequestProperty ( java . lang . String , java . lang . String )
* /
public String getRequestProperty ( String key ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
if ( requests = = null )
return null ;
return requests . findValue ( key ) ;
}
/ * *
* Returns an unmodifiable Map of general request
* properties for this connection . The Map keys
* are Strings that represent the request - header
* field names . Each Map value is a unmodifiable List
* of Strings that represents the corresponding
* field values .
*
* @return a Map of the general request properties for this connection .
* @throws IllegalStateException if already connected
* @since 1 . 4
* /
public Map < String , List < String > > getRequestProperties ( ) {
2015-07-10 16:40:12 +01:00
checkConnected ( ) ;
2007-12-01 00:00:00 +00:00
if ( requests = = null )
2011-09-16 12:09:04 -07:00
return Collections . emptyMap ( ) ;
2007-12-01 00:00:00 +00:00
return requests . getHeaders ( null ) ;
}
/ * *
* Sets the default value of a general request property . When a
2013-07-30 11:04:19 -07:00
* { @code URLConnection } is created , it is initialized with
2007-12-01 00:00:00 +00:00
* these properties .
*
* @param key the keyword by which the request is known
2013-07-30 11:04:19 -07:00
* ( e . g . , " {@code Accept} " ) .
2007-12-01 00:00:00 +00:00
* @param value the value associated with the key .
*
* @see java . net . URLConnection # setRequestProperty ( java . lang . String , java . lang . String )
*
* @deprecated The instance specific setRequestProperty method
* should be used after an appropriate instance of URLConnection
* is obtained . Invoking this method will have no effect .
*
* @see # getDefaultRequestProperty ( java . lang . String )
* /
@Deprecated
public static void setDefaultRequestProperty ( String key , String value ) {
}
/ * *
* Returns the value of the default request property . Default request
* properties are set for every connection .
*
2008-03-07 11:51:27 +00:00
* @param key the keyword by which the request is known ( e . g . , " Accept " ) .
2007-12-01 00:00:00 +00:00
* @return the value of the default request property
* for the specified key .
*
* @see java . net . URLConnection # getRequestProperty ( java . lang . String )
*
* @deprecated The instance specific getRequestProperty method
* should be used after an appropriate instance of URLConnection
* is obtained .
*
* @see # setDefaultRequestProperty ( java . lang . String , java . lang . String )
* /
@Deprecated
public static String getDefaultRequestProperty ( String key ) {
return null ;
}
/ * *
* The ContentHandler factory .
* /
2015-07-10 16:40:12 +01:00
private static volatile ContentHandlerFactory factory ;
2007-12-01 00:00:00 +00:00
/ * *
2013-07-30 11:04:19 -07:00
* Sets the { @code ContentHandlerFactory } of an
2007-12-01 00:00:00 +00:00
* application . It can be called at most once by an application .
* < p >
2013-07-30 11:04:19 -07:00
* The { @code ContentHandlerFactory } instance is used to
2007-12-01 00:00:00 +00:00
* construct a content handler from a content type
* < p >
* If there is a security manager , this method first calls
2013-07-30 11:04:19 -07:00
* the security manager ' s { @code checkSetFactory } method
2007-12-01 00:00:00 +00:00
* to ensure the operation is allowed .
* This could result in a SecurityException .
*
* @param fac the desired factory .
* @exception Error if the factory has already been defined .
* @exception SecurityException if a security manager exists and its
2013-07-30 11:04:19 -07:00
* { @code checkSetFactory } method doesn ' t allow the operation .
2007-12-01 00:00:00 +00:00
* @see java . net . ContentHandlerFactory
* @see java . net . URLConnection # getContent ( )
* @see SecurityManager # checkSetFactory
* /
public static synchronized void setContentHandlerFactory ( ContentHandlerFactory fac ) {
if ( factory ! = null ) {
throw new Error ( " factory already defined " ) ;
}
SecurityManager security = System . getSecurityManager ( ) ;
if ( security ! = null ) {
security . checkSetFactory ( ) ;
}
factory = fac ;
}
2015-07-10 16:40:12 +01:00
private static final Hashtable < String , ContentHandler > handlers = new Hashtable < > ( ) ;
2007-12-01 00:00:00 +00:00
/ * *
* Gets the Content Handler appropriate for this connection .
* /
2015-07-10 16:40:12 +01:00
private ContentHandler getContentHandler ( ) throws UnknownServiceException {
2007-12-01 00:00:00 +00:00
String contentType = stripOffParameters ( getContentType ( ) ) ;
2015-07-10 16:40:12 +01:00
if ( contentType = = null ) {
2007-12-01 00:00:00 +00:00
throw new UnknownServiceException ( " no content-type " ) ;
2015-07-10 16:40:12 +01:00
}
ContentHandler handler = handlers . get ( contentType ) ;
if ( handler ! = null )
return handler ;
if ( factory ! = null ) {
handler = factory . createContentHandler ( contentType ) ;
2007-12-01 00:00:00 +00:00
if ( handler ! = null )
return handler ;
}
2015-07-10 16:40:12 +01:00
handler = lookupContentHandlerViaProvider ( contentType ) ;
if ( handler ! = null ) {
ContentHandler h = handlers . putIfAbsent ( contentType , handler ) ;
2015-11-11 22:38:15 -05:00
return Objects . requireNonNullElse ( h , handler ) ;
2015-07-10 16:40:12 +01:00
}
try {
handler = lookupContentHandlerClassFor ( contentType ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
handler = UnknownContentHandler . INSTANCE ;
2007-12-01 00:00:00 +00:00
}
2015-07-10 16:40:12 +01:00
assert handler ! = null ;
ContentHandler h = handlers . putIfAbsent ( contentType , handler ) ;
2015-11-11 22:38:15 -05:00
return Objects . requireNonNullElse ( h , handler ) ;
2007-12-01 00:00:00 +00:00
}
/ *
* Media types are in the format : type / subtype * ( ; parameter ) .
* For looking up the content handler , we should ignore those
* parameters .
* /
private String stripOffParameters ( String contentType )
{
if ( contentType = = null )
return null ;
int index = contentType . indexOf ( ';' ) ;
if ( index > 0 )
return contentType . substring ( 0 , index ) ;
else
return contentType ;
}
private static final String contentClassPrefix = " sun.net.www.content " ;
private static final String contentPathProp = " java.content.handler.pkgs " ;
/ * *
2015-07-10 16:40:12 +01:00
* Looks for a content handler in a user - definable set of places .
* By default it looks in { @value # contentClassPrefix } , but users can define
* a vertical - bar delimited set of class prefixes to search through in
* addition by defining the { @value # contentPathProp } property .
2007-12-01 00:00:00 +00:00
* The class name must be of the form :
* < pre >
* { package - prefix } . { major } . { minor }
* e . g .
* YoyoDyne . experimental . text . plain
* < / pre >
* /
2015-07-10 16:40:12 +01:00
private ContentHandler lookupContentHandlerClassFor ( String contentType ) {
2007-12-01 00:00:00 +00:00
String contentHandlerClassName = typeToPackageName ( contentType ) ;
2015-07-10 16:40:12 +01:00
String contentHandlerPkgPrefixes = getContentHandlerPkgPrefixes ( ) ;
2007-12-01 00:00:00 +00:00
StringTokenizer packagePrefixIter =
new StringTokenizer ( contentHandlerPkgPrefixes , " | " ) ;
while ( packagePrefixIter . hasMoreTokens ( ) ) {
String packagePrefix = packagePrefixIter . nextToken ( ) . trim ( ) ;
try {
String clsName = packagePrefix + " . " + contentHandlerClassName ;
2011-09-16 12:09:04 -07:00
Class < ? > cls = null ;
2007-12-01 00:00:00 +00:00
try {
cls = Class . forName ( clsName ) ;
} catch ( ClassNotFoundException e ) {
ClassLoader cl = ClassLoader . getSystemClassLoader ( ) ;
if ( cl ! = null ) {
cls = cl . loadClass ( clsName ) ;
}
}
if ( cls ! = null ) {
2016-05-03 10:40:54 -07:00
@SuppressWarnings ( " deprecation " )
Object tmp = cls . newInstance ( ) ;
return ( ContentHandler ) tmp ;
2007-12-01 00:00:00 +00:00
}
2015-07-10 16:40:12 +01:00
} catch ( Exception ignored ) { }
2007-12-01 00:00:00 +00:00
}
2009-05-26 17:47:57 -07:00
return UnknownContentHandler . INSTANCE ;
2007-12-01 00:00:00 +00:00
}
2015-07-10 16:40:12 +01:00
private ContentHandler lookupContentHandlerViaProvider ( String contentType ) {
return AccessController . doPrivileged (
new PrivilegedAction < > ( ) {
@Override
public ContentHandler run ( ) {
ClassLoader cl = ClassLoader . getSystemClassLoader ( ) ;
ServiceLoader < ContentHandlerFactory > sl =
ServiceLoader . load ( ContentHandlerFactory . class , cl ) ;
Iterator < ContentHandlerFactory > iterator = sl . iterator ( ) ;
ContentHandler handler = null ;
while ( iterator . hasNext ( ) ) {
ContentHandlerFactory f ;
try {
f = iterator . next ( ) ;
} catch ( ServiceConfigurationError e ) {
if ( e . getCause ( ) instanceof SecurityException ) {
continue ;
}
throw e ;
}
handler = f . createContentHandler ( contentType ) ;
if ( handler ! = null ) {
break ;
}
}
return handler ;
}
} ) ;
}
2007-12-01 00:00:00 +00:00
/ * *
* Utility function to map a MIME content type into an equivalent
* pair of class name components . For example : " text/html " would
* be returned as " text.html "
* /
private String typeToPackageName ( String contentType ) {
// make sure we canonicalize the class name: all lower case
contentType = contentType . toLowerCase ( ) ;
int len = contentType . length ( ) ;
char nm [ ] = new char [ len ] ;
contentType . getChars ( 0 , len , nm , 0 ) ;
for ( int i = 0 ; i < len ; i + + ) {
char c = nm [ i ] ;
if ( c = = '/' ) {
nm [ i ] = '.' ;
} else if ( ! ( 'A' < = c & & c < = 'Z' | |
'a' < = c & & c < = 'z' | |
'0' < = c & & c < = '9' ) ) {
nm [ i ] = '_' ;
}
}
return new String ( nm ) ;
}
/ * *
* Returns a vertical bar separated list of package prefixes for potential
* content handlers . Tries to get the java . content . handler . pkgs property
* to use as a set of package prefixes to search . Whether or not
2015-07-10 16:40:12 +01:00
* that property has been defined , the { @value # contentClassPrefix }
* is always the last one on the returned package list.
2007-12-01 00:00:00 +00:00
* /
private String getContentHandlerPkgPrefixes ( ) {
2016-04-21 13:39:53 +02:00
String packagePrefixList =
2016-05-03 15:50:54 +02:00
GetPropertyAction . privilegedGetProperty ( contentPathProp , " " ) ;
2007-12-01 00:00:00 +00:00
if ( packagePrefixList ! = " " ) {
packagePrefixList + = " | " ;
}
return packagePrefixList + contentClassPrefix ;
}
/ * *
* Tries to determine the content type of an object , based
* on the specified " file " component of a URL .
* This is a convenience method that can be used by
2013-07-30 11:04:19 -07:00
* subclasses that override the { @code getContentType } method .
2007-12-01 00:00:00 +00:00
*
* @param fname a filename .
* @return a guess as to what the content type of the object is ,
* based upon its file name .
* @see java . net . URLConnection # getContentType ( )
* /
public static String guessContentTypeFromName ( String fname ) {
return getFileNameMap ( ) . getContentTypeFor ( fname ) ;
}
/ * *
* Tries to determine the type of an input stream based on the
* characters at the beginning of the input stream . This method can
* be used by subclasses that override the
2013-07-30 11:04:19 -07:00
* { @code getContentType } method .
2007-12-01 00:00:00 +00:00
* < p >
* Ideally , this routine would not be needed . But many
2013-07-30 11:04:19 -07:00
* { @code http } servers return the incorrect content type ; in
2007-12-01 00:00:00 +00:00
* addition , there are many nonstandard extensions . Direct inspection
* of the bytes to determine the content type is often more accurate
2013-07-30 11:04:19 -07:00
* than believing the content type claimed by the { @code http } server .
2007-12-01 00:00:00 +00:00
*
* @param is an input stream that supports marks .
2013-07-30 11:04:19 -07:00
* @return a guess at the content type , or { @code null } if none
2007-12-01 00:00:00 +00:00
* can be determined .
* @exception IOException if an I / O error occurs while reading the
* input stream .
* @see java . io . InputStream # mark ( int )
* @see java . io . InputStream # markSupported ( )
* @see java . net . URLConnection # getContentType ( )
* /
2015-09-15 21:56:04 -07:00
public static String guessContentTypeFromStream ( InputStream is )
2007-12-01 00:00:00 +00:00
throws IOException {
// If we can't read ahead safely, just give up on guessing
if ( ! is . markSupported ( ) )
return null ;
2011-03-11 08:57:14 +00:00
is . mark ( 16 ) ;
2007-12-01 00:00:00 +00:00
int c1 = is . read ( ) ;
int c2 = is . read ( ) ;
int c3 = is . read ( ) ;
int c4 = is . read ( ) ;
int c5 = is . read ( ) ;
int c6 = is . read ( ) ;
int c7 = is . read ( ) ;
int c8 = is . read ( ) ;
int c9 = is . read ( ) ;
int c10 = is . read ( ) ;
int c11 = is . read ( ) ;
2011-03-11 08:57:14 +00:00
int c12 = is . read ( ) ;
int c13 = is . read ( ) ;
int c14 = is . read ( ) ;
int c15 = is . read ( ) ;
int c16 = is . read ( ) ;
2007-12-01 00:00:00 +00:00
is . reset ( ) ;
if ( c1 = = 0xCA & & c2 = = 0xFE & & c3 = = 0xBA & & c4 = = 0xBE ) {
return " application/java-vm " ;
}
if ( c1 = = 0xAC & & c2 = = 0xED ) {
// next two bytes are version number, currently 0x00 0x05
return " application/x-java-serialized-object " ;
}
if ( c1 = = '<' ) {
if ( c2 = = '!'
| | ( ( c2 = = 'h' & & ( c3 = = 't' & & c4 = = 'm' & & c5 = = 'l' | |
c3 = = 'e' & & c4 = = 'a' & & c5 = = 'd' ) | |
( c2 = = 'b' & & c3 = = 'o' & & c4 = = 'd' & & c5 = = 'y' ) ) ) | |
( ( c2 = = 'H' & & ( c3 = = 'T' & & c4 = = 'M' & & c5 = = 'L' | |
c3 = = 'E' & & c4 = = 'A' & & c5 = = 'D' ) | |
( c2 = = 'B' & & c3 = = 'O' & & c4 = = 'D' & & c5 = = 'Y' ) ) ) ) {
return " text/html " ;
}
if ( c2 = = '?' & & c3 = = 'x' & & c4 = = 'm' & & c5 = = 'l' & & c6 = = ' ' ) {
return " application/xml " ;
}
}
2011-03-11 08:57:14 +00:00
// big and little (identical) endian UTF-8 encodings, with BOM
if ( c1 = = 0xef & & c2 = = 0xbb & & c3 = = 0xbf ) {
if ( c4 = = '<' & & c5 = = '?' & & c6 = = 'x' ) {
return " application/xml " ;
}
}
2007-12-01 00:00:00 +00:00
// big and little endian UTF-16 encodings, with byte order mark
if ( c1 = = 0xfe & & c2 = = 0xff ) {
if ( c3 = = 0 & & c4 = = '<' & & c5 = = 0 & & c6 = = '?' & &
c7 = = 0 & & c8 = = 'x' ) {
return " application/xml " ;
}
}
if ( c1 = = 0xff & & c2 = = 0xfe ) {
if ( c3 = = '<' & & c4 = = 0 & & c5 = = '?' & & c6 = = 0 & &
c7 = = 'x' & & c8 = = 0 ) {
return " application/xml " ;
}
}
2011-03-11 08:57:14 +00:00
// big and little endian UTF-32 encodings, with BOM
if ( c1 = = 0x00 & & c2 = = 0x00 & & c3 = = 0xfe & & c4 = = 0xff ) {
if ( c5 = = 0 & & c6 = = 0 & & c7 = = 0 & & c8 = = '<' & &
c9 = = 0 & & c10 = = 0 & & c11 = = 0 & & c12 = = '?' & &
c13 = = 0 & & c14 = = 0 & & c15 = = 0 & & c16 = = 'x' ) {
return " application/xml " ;
}
}
if ( c1 = = 0xff & & c2 = = 0xfe & & c3 = = 0x00 & & c4 = = 0x00 ) {
if ( c5 = = '<' & & c6 = = 0 & & c7 = = 0 & & c8 = = 0 & &
c9 = = '?' & & c10 = = 0 & & c11 = = 0 & & c12 = = 0 & &
c13 = = 'x' & & c14 = = 0 & & c15 = = 0 & & c16 = = 0 ) {
return " application/xml " ;
}
}
2007-12-01 00:00:00 +00:00
if ( c1 = = 'G' & & c2 = = 'I' & & c3 = = 'F' & & c4 = = '8' ) {
return " image/gif " ;
}
if ( c1 = = '#' & & c2 = = 'd' & & c3 = = 'e' & & c4 = = 'f' ) {
return " image/x-bitmap " ;
}
if ( c1 = = '!' & & c2 = = ' ' & & c3 = = 'X' & & c4 = = 'P' & &
c5 = = 'M' & & c6 = = '2' ) {
return " image/x-pixmap " ;
}
if ( c1 = = 137 & & c2 = = 80 & & c3 = = 78 & &
c4 = = 71 & & c5 = = 13 & & c6 = = 10 & &
c7 = = 26 & & c8 = = 10 ) {
return " image/png " ;
}
if ( c1 = = 0xFF & & c2 = = 0xD8 & & c3 = = 0xFF ) {
2015-12-25 16:45:15 +03:00
if ( c4 = = 0xE0 | | c4 = = 0xEE ) {
2007-12-01 00:00:00 +00:00
return " image/jpeg " ;
}
/ * *
* File format used by digital cameras to store images .
* Exif Format can be read by any application supporting
* JPEG . Exif Spec can be found at :
* http : //www.pima.net/standards/it10/PIMA15740/Exif_2-1.PDF
* /
if ( ( c4 = = 0xE1 ) & &
( c7 = = 'E' & & c8 = = 'x' & & c9 = = 'i' & & c10 = = 'f' & &
c11 = = 0 ) ) {
return " image/jpeg " ;
}
}
2016-01-06 10:15:37 -08:00
if ( ( c1 = = 0x49 & & c2 = = 0x49 & & c3 = = 0x2a & & c4 = = 0x00 )
| | ( c1 = = 0x4d & & c2 = = 0x4d & & c3 = = 0x00 & & c4 = = 0x2a ) ) {
return " image/tiff " ;
}
2007-12-01 00:00:00 +00:00
if ( c1 = = 0xD0 & & c2 = = 0xCF & & c3 = = 0x11 & & c4 = = 0xE0 & &
c5 = = 0xA1 & & c6 = = 0xB1 & & c7 = = 0x1A & & c8 = = 0xE1 ) {
/ * Above is signature of Microsoft Structured Storage .
* Below this , could have tests for various SS entities .
* For now , just test for FlashPix .
* /
if ( checkfpx ( is ) ) {
return " image/vnd.fpx " ;
}
}
if ( c1 = = 0x2E & & c2 = = 0x73 & & c3 = = 0x6E & & c4 = = 0x64 ) {
return " audio/basic " ; // .au format, big endian
}
if ( c1 = = 0x64 & & c2 = = 0x6E & & c3 = = 0x73 & & c4 = = 0x2E ) {
return " audio/basic " ; // .au format, little endian
}
if ( c1 = = 'R' & & c2 = = 'I' & & c3 = = 'F' & & c4 = = 'F' ) {
/ * I don ' t know if this is official but evidence
* suggests that . wav files start with " RIFF " - brown
* /
return " audio/x-wav " ;
}
return null ;
}
/ * *
* Check for FlashPix image data in InputStream is . Return true if
* the stream has FlashPix data , false otherwise . Before calling this
* method , the stream should have already been checked to be sure it
* contains Microsoft Structured Storage data .
* /
2015-09-15 21:56:04 -07:00
private static boolean checkfpx ( InputStream is ) throws IOException {
2007-12-01 00:00:00 +00:00
/ * Test for FlashPix image data in Microsoft Structured Storage format .
* In general , should do this with calls to an SS implementation .
* Lacking that , need to dig via offsets to get to the FlashPix
* ClassID . Details :
*
* Offset to Fpx ClsID from beginning of stream should be :
*
* FpxClsidOffset = rootEntryOffset + clsidOffset
*
* where : clsidOffset = 0x50 .
* rootEntryOffset = headerSize + sectorSize * sectDirStart
* + 128 * rootEntryDirectory
*
* where : headerSize = 0x200 ( always )
* sectorSize = 2 raised to power of uSectorShift ,
* which is found in the header at
* offset 0x1E .
* sectDirStart = found in the header at offset 0x30 .
* rootEntryDirectory = in general , should search for
* directory labelled as root .
* We will assume value of 0 ( i . e . ,
* rootEntry is in first directory )
* /
// Mark the stream so we can reset it. 0x100 is enough for the first
// few reads, but the mark will have to be reset and set again once
// the offset to the root directory entry is computed. That offset
// can be very large and isn't know until the stream has been read from
is . mark ( 0x100 ) ;
// Get the byte ordering located at 0x1E. 0xFE is Intel,
// 0xFF is other
long toSkip = ( long ) 0x1C ;
long posn ;
if ( ( posn = skipForward ( is , toSkip ) ) < toSkip ) {
is . reset ( ) ;
return false ;
}
int c [ ] = new int [ 16 ] ;
if ( readBytes ( c , 2 , is ) < 0 ) {
is . reset ( ) ;
return false ;
}
int byteOrder = c [ 0 ] ;
posn + = 2 ;
int uSectorShift ;
if ( readBytes ( c , 2 , is ) < 0 ) {
is . reset ( ) ;
return false ;
}
if ( byteOrder = = 0xFE ) {
uSectorShift = c [ 0 ] ;
uSectorShift + = c [ 1 ] < < 8 ;
}
else {
uSectorShift = c [ 0 ] < < 8 ;
uSectorShift + = c [ 1 ] ;
}
posn + = 2 ;
toSkip = ( long ) 0x30 - posn ;
long skipped = 0 ;
if ( ( skipped = skipForward ( is , toSkip ) ) < toSkip ) {
is . reset ( ) ;
return false ;
}
posn + = skipped ;
if ( readBytes ( c , 4 , is ) < 0 ) {
is . reset ( ) ;
return false ;
}
int sectDirStart ;
if ( byteOrder = = 0xFE ) {
sectDirStart = c [ 0 ] ;
sectDirStart + = c [ 1 ] < < 8 ;
sectDirStart + = c [ 2 ] < < 16 ;
sectDirStart + = c [ 3 ] < < 24 ;
} else {
sectDirStart = c [ 0 ] < < 24 ;
sectDirStart + = c [ 1 ] < < 16 ;
sectDirStart + = c [ 2 ] < < 8 ;
sectDirStart + = c [ 3 ] ;
}
posn + = 4 ;
is . reset ( ) ; // Reset back to the beginning
toSkip = 0x200L + ( long ) ( 1 < < uSectorShift ) * sectDirStart + 0x50L ;
// Sanity check!
if ( toSkip < 0 ) {
return false ;
}
/ *
* How far can we skip ? Is there any performance problem here ?
* This skip can be fairly long , at least 0x4c650 in at least
* one case . Have to assume that the skip will fit in an int .
* Leave room to read whole root dir
* /
is . mark ( ( int ) toSkip + 0x30 ) ;
if ( ( skipForward ( is , toSkip ) ) < toSkip ) {
is . reset ( ) ;
return false ;
}
/ * should be at beginning of ClassID , which is as follows
* ( in Intel byte order ) :
* 00 67 61 56 54 C1 CE 11 85 53 00 AA 00 A1 F9 5B
*
* This is stored from Windows as long , short , short , char [ 8 ]
* so for byte order changes , the order only changes for
* the first 8 bytes in the ClassID .
*
* Test against this , ignoring second byte ( Intel ) since
* this could change depending on part of Fpx file we have .
* /
if ( readBytes ( c , 16 , is ) < 0 ) {
is . reset ( ) ;
return false ;
}
// intel byte order
if ( byteOrder = = 0xFE & &
c [ 0 ] = = 0x00 & & c [ 2 ] = = 0x61 & & c [ 3 ] = = 0x56 & &
c [ 4 ] = = 0x54 & & c [ 5 ] = = 0xC1 & & c [ 6 ] = = 0xCE & &
c [ 7 ] = = 0x11 & & c [ 8 ] = = 0x85 & & c [ 9 ] = = 0x53 & &
c [ 10 ] = = 0x00 & & c [ 11 ] = = 0xAA & & c [ 12 ] = = 0x00 & &
c [ 13 ] = = 0xA1 & & c [ 14 ] = = 0xF9 & & c [ 15 ] = = 0x5B ) {
is . reset ( ) ;
return true ;
}
// non-intel byte order
else if ( c [ 3 ] = = 0x00 & & c [ 1 ] = = 0x61 & & c [ 0 ] = = 0x56 & &
c [ 5 ] = = 0x54 & & c [ 4 ] = = 0xC1 & & c [ 7 ] = = 0xCE & &
c [ 6 ] = = 0x11 & & c [ 8 ] = = 0x85 & & c [ 9 ] = = 0x53 & &
c [ 10 ] = = 0x00 & & c [ 11 ] = = 0xAA & & c [ 12 ] = = 0x00 & &
c [ 13 ] = = 0xA1 & & c [ 14 ] = = 0xF9 & & c [ 15 ] = = 0x5B ) {
is . reset ( ) ;
return true ;
}
is . reset ( ) ;
return false ;
}
/ * *
* Tries to read the specified number of bytes from the stream
* Returns - 1 , If EOF is reached before len bytes are read , returns 0
* otherwise
* /
2015-09-15 21:56:04 -07:00
private static int readBytes ( int c [ ] , int len , InputStream is )
2007-12-01 00:00:00 +00:00
throws IOException {
byte buf [ ] = new byte [ len ] ;
if ( is . read ( buf , 0 , len ) < len ) {
return - 1 ;
}
// fill the passed in int array
for ( int i = 0 ; i < len ; i + + ) {
c [ i ] = buf [ i ] & 0xff ;
}
return 0 ;
}
/ * *
* Skips through the specified number of bytes from the stream
* until either EOF is reached , or the specified
* number of bytes have been skipped
* /
2015-09-15 21:56:04 -07:00
private static long skipForward ( InputStream is , long toSkip )
2007-12-01 00:00:00 +00:00
throws IOException {
long eachSkip = 0 ;
long skipped = 0 ;
while ( skipped ! = toSkip ) {
eachSkip = is . skip ( toSkip - skipped ) ;
// check if EOF is reached
if ( eachSkip < = 0 ) {
if ( is . read ( ) = = - 1 ) {
return skipped ;
} else {
skipped + + ;
}
}
skipped + = eachSkip ;
}
return skipped ;
}
2015-07-10 16:40:12 +01:00
private void checkConnected ( ) {
if ( connected )
throw new IllegalStateException ( " Already connected " ) ;
}
2007-12-01 00:00:00 +00:00
}
class UnknownContentHandler extends ContentHandler {
2009-05-26 17:47:57 -07:00
static final ContentHandler INSTANCE = new UnknownContentHandler ( ) ;
2007-12-01 00:00:00 +00:00
public Object getContent ( URLConnection uc ) throws IOException {
return uc . getInputStream ( ) ;
}
}