📄 httpurlconnection.java
字号:
* @return the header name, or null if not that many headers.
*/
public String getHeaderFieldKey(int n)
{
if (hdr_keys == null)
fill_hdr_arrays();
if (n >= 0 && n < hdr_keys.length)
return hdr_keys[n];
else
return null;
}
/**
* Gets header value of the n-th header. Calls connect() if not connected.
* The value of 0-th header is the Status-Line (e.g. "HTTP/1.1 200 Ok").
*
* @param n which header to return.
* @return the header value, or null if not that many headers.
*/
public String getHeaderField(int n)
{
if (hdr_values == null)
fill_hdr_arrays();
if (n >= 0 && n < hdr_values.length)
return hdr_values[n];
else
return null;
}
/**
* Cache the list of headers.
*/
private void fill_hdr_arrays()
{
try
{
if (!connected) connect();
// count number of headers
int num = 1;
Enumeration enum = resp.listHeaders();
while (enum.hasMoreElements())
{
num++;
enum.nextElement();
}
// allocate arrays
hdr_keys = new String[num];
hdr_values = new String[num];
// fill arrays
enum = resp.listHeaders();
for (int idx=1; idx<num; idx++)
{
hdr_keys[idx] = (String) enum.nextElement();
hdr_values[idx] = resp.getHeader(hdr_keys[idx]);
}
// the 0'th field is special
hdr_values[0] = resp.getVersion() + " " + resp.getStatusCode() +
" " + resp.getReasonLine();
}
catch (Exception e)
{ hdr_keys = hdr_values = new String[0]; }
}
/**
* Gets an input stream from which the data in the response may be read.
* Calls connect() if not connected.
*
* @return an InputStream
* @exception ProtocolException if input not enabled.
* @see java.net.URLConnection#setDoInput(boolean)
*/
public InputStream getInputStream() throws IOException
{
if (!doInput)
throw new ProtocolException("Input not enabled! (use setDoInput(true))");
if (!connected) connect();
InputStream stream;
try
{
stream = resp.getInputStream();
if (resp.pe != null && resp.getHeader("Content-length") != null)
{
try
{ stream = new sun.net.www.MeteredStream(stream, resp.pe); }
catch (Throwable t)
{
Log.write(Log.URLC, "URLC: (" + urlString +
") error trying to create metered stream: ", t);
}
}
else
// some things expect this stream to support mark/reset
stream = new BufferedInputStream(stream);
}
catch (ModuleException e)
{ throw new IOException(e.toString()); }
return stream;
}
/**
* Returns the error stream if the connection failed
* but the server sent useful data nonetheless.
*
* <P>This method will not cause a connection to be initiated.
*
* @return an InputStream, or null if either the connection hasn't
* been established yet or no error occured
* @see java.net.HttpURLConnection#getErrorStream()
* @since V0.3-1
*/
public InputStream getErrorStream()
{
try
{
if (!doInput || !connected || resp.getStatusCode() < 300 ||
resp.getHeaderAsInt("Content-length") <= 0)
return null;
return resp.getInputStream();
}
catch (Exception e)
{ return null; }
}
/**
* Gets an output stream which can be used send an entity with the
* request. Can be called multiple times, in which case always the
* same stream is returned.
*
* <P>The default request method changes to "POST" when this method is
* called. Cannot be called after connect().
*
* <P>If no Content-type has been set it defaults to
* <var>application/x-www-form-urlencoded</var>. Furthermore, if the
* Content-type is <var>application/x-www-form-urlencoded</var> then all
* output will be collected in a buffer before sending it to the server;
* otherwise an HttpOutputStream is used.
*
* @return an OutputStream
* @exception ProtocolException if already connect()'ed, if output is not
* enabled or if the request method does not
* support output.
* @see java.net.URLConnection#setDoOutput(boolean)
* @see HTTPClient.HttpOutputStream
*/
public synchronized OutputStream getOutputStream() throws IOException
{
if (connected)
throw new ProtocolException("Already connected!");
if (!doOutput)
throw new ProtocolException("Output not enabled! (use setDoOutput(true))");
if (!method_set)
method = "POST";
else if (method.equals("HEAD") || method.equals("GET") ||
method.equals("TRACE"))
throw new ProtocolException("Method "+method+" does not support output!");
if (getRequestProperty("Content-type") == null)
setRequestProperty("Content-type", "application/x-www-form-urlencoded");
if (output_stream == null)
{
Log.write(Log.URLC, "URLC: (" + urlString + ") creating output stream");
String cl = getRequestProperty("Content-Length");
if (cl != null)
output_stream = new HttpOutputStream(Integer.parseInt(cl.trim()));
else
{
// Hack: because of restrictions when using true output streams
// and because form-data is usually quite limited in size, we
// first collect all data before sending it if this is
// form-data.
if (getRequestProperty("Content-type").equals(
"application/x-www-form-urlencoded"))
output_stream = new ByteArrayOutputStream(300);
else
output_stream = new HttpOutputStream();
}
if (output_stream instanceof HttpOutputStream)
connect();
}
return output_stream;
}
/**
* Gets the url for this connection. If we're connect()'d and the request
* was redirected then the url returned is that of the final request.
*
* @return the final url, or null if any exception occured.
*/
public URL getURL()
{
if (connected)
{
try
{
if (resp.getEffectiveURL() != null)
return resp.getEffectiveURL();
}
catch (Exception e)
{ return null; }
}
return url;
}
/**
* Sets the <var>If-Modified-Since</var> header.
*
* @param time the number of milliseconds since 1970.
*/
public void setIfModifiedSince(long time)
{
super.setIfModifiedSince(time);
setRequestProperty("If-Modified-Since", Util.httpDate(new Date(time)));
}
/**
* Sets an arbitrary request header.
*
* @param name the name of the header.
* @param value the value for the header.
*/
public void setRequestProperty(String name, String value)
{
Log.write(Log.URLC, "URLC: (" + urlString + ") Setting request property: " +
name + " : " + value);
int idx;
for (idx=0; idx<headers.length; idx++)
{
if (headers[idx].getName().equalsIgnoreCase(name))
break;
}
if (idx == headers.length)
headers = Util.resizeArray(headers, idx+1);
headers[idx] = new NVPair(name, value);
}
/**
* Gets the value of a given request header.
*
* @param name the name of the header.
* @return the value part of the header, or null if no such header.
*/
public String getRequestProperty(String name)
{
for (int idx=0; idx<headers.length; idx++)
{
if (headers[idx].getName().equalsIgnoreCase(name))
return headers[idx].getValue();
}
return null;
}
/**
* Sets an arbitrary default request header. All headers set here are
* automatically sent with each request.
*
* @param name the name of the header.
* @param value the value for the header.
*/
public static void setDefaultRequestProperty(String name, String value)
{
Log.write(Log.URLC, "URLC: Setting default request property: " +
name + " : " + value);
int idx;
for (idx=0; idx<default_headers.length; idx++)
{
if (default_headers[idx].getName().equalsIgnoreCase(name))
break;
}
if (idx == default_headers.length)
default_headers = Util.resizeArray(default_headers, idx+1);
default_headers[idx] = new NVPair(name, value);
}
/**
* Gets the value for a given default request header.
*
* @param name the name of the header.
* @return the value part of the header, or null if no such header.
*/
public static String getDefaultRequestProperty(String name)
{
for (int idx=0; idx<default_headers.length; idx++)
{
if (default_headers[idx].getName().equalsIgnoreCase(name))
return default_headers[idx].getValue();
}
return null;
}
/**
* Enables or disables the automatic handling of redirection responses
* for this instance only. Cannot be called after <code>connect()</code>.
*
* @param set enables automatic redirection handling if true.
*/
public void setInstanceFollowRedirects(boolean set)
{
if (connected)
throw new IllegalStateException("Already connected!");
do_redir = set;
}
/**
* @return true if automatic redirection handling for this instance is
* enabled.
*/
public boolean getInstanceFollowRedirects()
{
return do_redir;
}
/**
* Connects to the server (if connection not still kept alive) and
* issues the request.
*/
public synchronized void connect() throws IOException
{
if (connected) return;
Log.write(Log.URLC, "URLC: (" + urlString + ") Connecting ...");
// useCaches TBD!!!
synchronized(con)
{
con.setAllowUserInteraction(allowUserInteraction);
if (do_redir)
con.addModule(redir_mod, 2);
else
con.removeModule(redir_mod);
try
{
if (output_stream instanceof ByteArrayOutputStream)
resp = con.ExtensionMethod(method, resource,
((ByteArrayOutputStream) output_stream).toByteArray(),
headers);
else
resp = con.ExtensionMethod(method, resource,
(HttpOutputStream) output_stream, headers);
}
catch (ModuleException e)
{ throw new IOException(e.toString()); }
}
connected = true;
try
{ resp.setProgressEntry(new sun.net.ProgressEntry(url.getFile(), null)); }
catch (Throwable t)
{
Log.write(Log.URLC, "URLC: (" + urlString +
") error trying to create and set progress entry: ", t);
}
}
/**
* Closes all the connections to this server.
*/
public void disconnect()
{
Log.write(Log.URLC, "URLC: (" + urlString + ") Disconnecting ...");
con.stop();
if (resp != null)
resp.unsetProgressEntry();
}
public void finalize()
{
if (resp != null)
resp.unsetProgressEntry();
super.finalize();
}
/**
* Shows if request are being made through an http proxy or directly.
*
* @return true if an http proxy is being used.
*/
public boolean usingProxy()
{
return (con.getProxyHost() != null);
}
/**
* produces a string.
* @return a string containing the HttpURLConnection
*/
public String toString()
{
return getClass().getName() + "[" + url + "]";
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -