⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpurlconnection.java

📁 SMS SDK classes.This is the archive that must be included in the classpath.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * @(#)HttpURLConnection.java				0.3-3 18/06/1999
 *
 *  This file is part of the HTTPClient package
 *  Copyright (C) 1996-2001 Ronald Tschal鋜
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA 02111-1307, USA
 *
 *  For questions, suggestions, bug-reports, enhancement-requests etc.
 *  I may be contacted at:
 *
 *  ronald@innovation.ch
 *
 *  The HTTPClient's home page is located at:
 *
 *  http://www.innovation.ch/java/HTTPClient/ 
 *
 */

package HTTPClient;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.net.ProtocolException;
import java.util.Date;
import java.util.Hashtable;
import java.util.Enumeration;


/**
 * This class is a wrapper around HTTPConnection providing the interface
 * defined by java.net.URLConnection and java.net.HttpURLConnection.
 *
 * <P>This class is a hacked version of the HttpURLConnection class for use
 * with HotJava 1.1.x. It extends sun.net.www.protocol.http.HttpURLConnection
 * instead of java.net.HttpURLConnection, because the HotJava uses the
 * setInstanceFollowRedirect() method which is defined in the
 * sun.*.HttpURLConnection class, but only if this is an instance of the
 * sun.*.HttpURLConnection class (or a subclass).
 *
 * <P>One difference between Sun's HttpClient and this one is that this
 * one will provide you with a real output stream if possible. This leads
 * to two changes: you should set the request property "Content-Length",
 * if possible, before invoking getOutputStream(); and in many cases
 * getOutputStream() implies connect(). This should be transparent, though,
 * apart from the fact that you can't change any headers or other settings
 * anymore once you've gotten the output stream.
 * So, for large data do:
 * <PRE>
 *   HttpURLConnection con = (HttpURLConnection) url.openConnection();
 *
 *   con.setDoOutput(true);
 *   con.setRequestProperty("Content-Length", ...);
 *   OutputStream out = con.getOutputStream();
 *
 *   out.write(...);
 *   out.close();
 *
 *   if (con.getResponseCode() != 200)
 *       ...
 * </PRE>
 *
 * <P>The HTTPClient will send the request data using the chunked transfer
 * encoding when no Content-Length is specified and the server is HTTP/1.1
 * compatible. Because cgi-scripts can't usually handle this, you may
 * experience problems trying to POST data. For this reason, whenever
 * the Content-Type is application/x-www-form-urlencoded getOutputStream()
 * will buffer the data before sending it so as prevent chunking. If you
 * are sending requests with a different Content-Type and are experiencing
 * problems then you may want to try setting the system property
 * <var>HTTPClient.dontChunkRequests</var> to <var>true</var> (this needs
 * to be done either on the command line or somewhere in the code before
 * the first URLConnection.openConnection() is invoked).
 *
 * <P>A second potential incompatibility is that the HTTPClient aggresively
 * resuses connections, and can do so more often that Sun's client. This
 * can cause problems if you send multiple requests, and the first one has
 * a long response. In this case (assuming the server allows the connection
 * to be used for multiple requests) the responses to second, third, etc
 * request won't be received until the first response has been completely
 * read. With Sun's client on the other hand you may not experience this,
 * as it may not be able to keep the connection open and there may create
 * multiple connections for the requests. This allows the responses to the
 * second, third, etc requests to be read before the first response has
 * completed. <strong>Note:</strong> whether this will happen depends on
 * details of the resource being requested and the server. In many cases
 * the HTTPClient and Sun's client will exhibit the same behaviour. Also,
 * applications which depend on being able to read the second response
 * before the first one has completed must be considered broken, because
 * A) this behaviour cannot be relied upon even in Sun's current client,
 * and B) Sun's implementation will exhibit the same problem if they ever
 * switch to HTTP/1.1.
 *
 * @version	0.3-3  18/06/1999
 * @author	Ronald Tschal鋜
 * @since	V0.3
 */

public class HttpURLConnection
		extends sun.net.www.protocol.http.HttpURLConnection
		implements GlobalConstants
{
    /** a list of HTTPConnections */
    private static Hashtable  connections = new Hashtable();

    /** the current connection */
    private HTTPConnection    con;

    /** the cached url.toString() */
    private String            urlString;

    /** the resource */
    private String            resource;

    /** the current method */
    private String            method;

    /** has the current method been set via setRequestMethod()? */
    private boolean           method_set;

    /** the default request headers */
    private static NVPair[]   default_headers = new NVPair[0];

    /** the request headers */
    private NVPair[]          headers;

    /** the response */
    private HTTPResponse      resp;

    /** is the redirection module activated for this instance? */
    private boolean           do_redir;

    /** the RedirectionModule class */
    private static Class      redir_mod;

    /** the output stream used for POST and PUT */
    private OutputStream      output_stream;

    /** HotJava hacks */
    private static boolean    in_hotjava = false;


    static
    {
	try
	{
	    String browser = System.getProperty("browser");
	    if (browser != null  &&  browser.equals("HotJava"))
		in_hotjava = true;
	}
	catch (SecurityException se)
	    { }

	// The default allowUserAction in java.net.URLConnection is
	// false.
	try
	{
	    if (Boolean.getBoolean("HTTPClient.HttpURLConnection.AllowUI")  ||
		in_hotjava)
		setDefaultAllowUserInteraction(true);
	}
	catch (SecurityException se)
	    { }

	// get the RedirectionModule class
	try
	    { redir_mod = Class.forName("HTTPClient.RedirectionModule"); }
	catch (ClassNotFoundException cnfe)
	    { throw new NoClassDefFoundError(cnfe.getMessage()); }

	// Set the User-Agent if the http.agent property is set
	try
	{
	    String agent = System.getProperty("http.agent");
	    if (agent != null)
		setDefaultRequestProperty("User-Agent", agent);
	}
	catch (SecurityException se)
	    { }
    }


    // Constructors

    private static String non_proxy_hosts = "";
    private static String proxy_host = "";
    private static int    proxy_port = -1;

    /**
     * Construct a connection to the specified url. A cache of
     * HTTPConnections is used to maximize the reuse of these across
     * multiple HttpURLConnections.
     *
     * <BR>The default method is "GET".
     *
     * @param url the url of the request
     * @exception ProtocolNotSuppException if the protocol is not supported
     */
    public HttpURLConnection(URL url)
	    throws ProtocolNotSuppException, IOException
    {
	super(url, null);

	// first read proxy properties and set
        try
        {
            String hosts = System.getProperty("http.nonProxyHosts", "");
	    if (!hosts.equalsIgnoreCase(non_proxy_hosts))
	    {
		connections.clear();
		non_proxy_hosts = hosts;
		String[] list = Util.splitProperty(hosts);
		for (int idx=0; idx<list.length; idx++)
		    HTTPConnection.dontProxyFor(list[idx]);
	    }
        }
        catch (ParseException pe)
	    { throw new IOException(pe.toString()); }
        catch (SecurityException se)
            { }

	try
	{
	    String host = System.getProperty("http.proxyHost", "");
	    int port = Integer.getInteger("http.proxyPort", -1).intValue();
	    if (!host.equalsIgnoreCase(proxy_host)  ||  port != proxy_port)
	    {
		connections.clear();
		proxy_host = host;
		proxy_port = port;
		HTTPConnection.setProxyServer(host, port);
	    }
	}
	catch (SecurityException se)
	    { }

	// now setup stuff
	con           = getConnection(url);
	method        = "GET";
	method_set    = false;
	resource      = url.getFile();
	headers       = default_headers;
	do_redir      = getFollowRedirects();
	output_stream = null;

	urlString     = url.toString();
    }


    /**
     * Returns an HTTPConnection. A cache of connections is kept and first
     * consulted; only when the cache lookup fails is a new one created
     * and added to the cache.
     *
     * @param url the url
     * @return an HTTPConnection
     * @exception ProtocolNotSuppException if the protocol is not supported
     */
    private HTTPConnection getConnection(URL url)
	    throws ProtocolNotSuppException
    {
	// try the cache, using the host name

	String php = url.getProtocol() + ":" + url.getHost() + ":" +
		     ((url.getPort() != -1) ? url.getPort() :
					URI.defaultPort(url.getProtocol()));
	php = php.toLowerCase();

	HTTPConnection con = (HTTPConnection) connections.get(php);
	if (con != null)  return con;


	// Not in cache, so create new one and cache it

	con = new HTTPConnection(url);
	connections.put(php, con);

	return con;
    }


    // Methods

    /**
     * Sets the request method (e.g. "PUT" or "HEAD"). Can only be set
     * before connect() is called.
     *
     * @param method the http method.
     * @exception ProtocolException if already connected.
     */
    public void setRequestMethod(String method)  throws ProtocolException
    {
	if (connected)
	    throw new ProtocolException("Already connected!");

	Log.write(Log.URLC, "URLC:  (" + urlString + ") Setting request method: " +
			    method);

	this.method = method.trim().toUpperCase();
	method_set  = true;
    }


    /**
     * Return the request method used.
     *
     * @return the http method.
     */
    public String getRequestMethod()
    {
	return method;
    }


    /**
     * Get the response code. Calls connect() if not connected.
     *
     * @return the http response code returned.
     */
    public int getResponseCode()  throws IOException
    {
	if (!connected)  connect();

	try
	{
	    if (in_hotjava  &&  resp.getStatusCode() >= 300)
	    {
		try
		    { resp.getData(); }	// force response stream to be read
		catch (InterruptedIOException iioe)
		    { disconnect(); }
	    }
	    return resp.getStatusCode();
	}
	catch (ModuleException me)
	    { throw new IOException(me.toString()); }
    }


    /**
     * Get the response message describing the response code. Calls connect()
     * if not connected.
     *
     * @return the http response message returned with the response code.
     */
    public String getResponseMessage()  throws IOException
    {
	if (!connected)  connect();

	try
	    { return resp.getReasonLine(); }
	catch (ModuleException me)
	    { throw new IOException(me.toString()); }
    }


    /**
     * Get the value part of a header. Calls connect() if not connected.
     *
     * @param  name the of the header.
     * @return the value of the header, or null if no such header was returned.
     */
    public String getHeaderField(String name)
    {
	try
	{
	    if (!connected)  connect();
	    return resp.getHeader(name);
	}
	catch (Exception e)
	    { return null; }
    }


    /**
     * Get the value part of a header and converts it to an int. If the
     * header does not exist or if its value could not be converted to an
     * int then the default is returned. Calls connect() if not connected.
     *
     * @param  name the of the header.
     * @param  def  the default value to return in case of an error.
     * @return the value of the header, or null if no such header was returned.
     */
    public int getHeaderFieldInt(String name, int def)
    {
	try
	{
	    if (!connected)  connect();
	    return resp.getHeaderAsInt(name);
	}
	catch (Exception e)
	    { return def; }
    }


    /**
     * Get the value part of a header, interprets it as a date and converts
     * it to a long representing the number of milliseconds since 1970. If
     * the header does not exist or if its value could not be converted to a
     * date then the default is returned. Calls connect() if not connected.
     *
     * @param  name the of the header.
     * @param  def  the default value to return in case of an error.
     * @return the value of the header, or def in case of an error.
     */
    public long getHeaderFieldDate(String name, long def)
    {
	try
	{
	    if (!connected)  connect();
	    return resp.getHeaderAsDate(name).getTime();
	}
	catch (Exception e)
	    { return def; }
    }


    private String[] hdr_keys, hdr_values;

    /**
     * Gets header name of the n-th header. Calls connect() if not connected.
     * The name of the 0-th header is <var>null</var>, even though it the
     * 0-th header has a value.
     *
     * @param n which header to return.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -