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

📄 httpresponse.java

📁 SMS SDK classes.This is the archive that must be included in the classpath.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * @(#)HTTPResponse.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.ByteArrayInputStream;
import java.net.URL;
import java.util.Date;
import java.util.Enumeration;

import sun.net.ProgressEntry;


/**
 * This defines the http-response class returned by the requests. It's
 * basically a wrapper around the Response class which first lets all
 * the modules handle the response before finally giving the info to
 * the user.
 *
 * @version	0.3-3  18/06/1999
 * @author	Ronald Tschal鋜
 * @since	0.3
 */

public class HTTPResponse implements GlobalConstants, HTTPClientModuleConstants
{
    /** the list of modules */
    private HTTPClientModule[]  modules;

    /** the timeout for reads */
    private int          timeout;

    /** the request */
    private Request      request = null;

    /** the current response */
            Response     response = null;

    /** the HttpOutputStream to synchronize on */
    private HttpOutputStream out_stream = null;

    /** our input stream from the stream demux */
    private InputStream  inp_stream;

    /** the status code returned. */
    private int          StatusCode;

    /** the reason line associated with the status code. */
    private String       ReasonLine;

    /** the HTTP version of the response. */
    private String       Version;

    /** the original URI used. */
    private URI          OriginalURI = null;

    /** the final URI of the document. */
    private URI          EffectiveURI = null;

    /** any headers which were received and do not fit in the above list. */
    private CIHashtable  Headers = null;

    /** any trailers which were received and do not fit in the above list. */
    private CIHashtable  Trailers = null;

    /** the ContentLength of the data. */
    private int          ContentLength = -1;

    /** the data (body) returned. */
    private byte[]       Data = null;

    /** signals if we have got and parsed the headers yet? */
    private boolean      initialized = false;

    /** signals if we have got the trailers yet? */
    private boolean      got_trailers = false;

    /** marks this response as aborted (stop() in HTTPConnection) */
    private boolean      aborted = false;

    /** should the request be retried by the application? */
    private boolean      retry = false;

    /** the method used in the request */
    private String       method = null;


    // Constructors

    /**
     * Creates a new HTTPResponse.
     *
     * @param modules the list of modules handling this response
     * @param timeout the timeout to be used on stream read()'s
     */
    HTTPResponse(HTTPClientModule[] modules, int timeout, Request orig)
    {
	this.modules = modules;
	this.timeout = timeout;
	try
	{
	    int qp = orig.getRequestURI().indexOf('?');
	    this.OriginalURI = new URI(orig.getConnection().getProtocol(),
				       null,
				       orig.getConnection().getHost(),
				       orig.getConnection().getPort(),
				       qp < 0 ? orig.getRequestURI() :
					 orig.getRequestURI().substring(0, qp),
				       qp < 0 ? null :
					 orig.getRequestURI().substring(qp+1),
				       null);
	}
	catch (ParseException pe)
	    { }
	this.method = orig.getMethod();
    }


    /**
     * @param req the request
     * @param resp the response
     */
    void set(Request req, Response resp)
    {
	this.request   = req;
	this.response  = resp;
	resp.http_resp = this;
	resp.timeout   = timeout;
	this.aborted   = resp.final_resp;
    }


    /**
     * @param req the request
     * @param resp the response
     */
    void set(Request req, HttpOutputStream out_stream)
    {
	this.request    = req;
	this.out_stream = out_stream;
    }


    // Methods

    /**
     * Give the status code for this request. These are grouped as follows:
     * <UL>
     *   <LI> 1xx - Informational (new in HTTP/1.1)
     *   <LI> 2xx - Success
     *   <LI> 3xx - Redirection
     *   <LI> 4xx - Client Error
     *   <LI> 5xx - Server Error
     * </UL>
     *
     * @exception IOException if any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public final int getStatusCode()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	return StatusCode;
    }

    /**
     * Give the reason line associated with the status code.
     *
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public final String getReasonLine()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	return ReasonLine;
    }

    /**
     * Get the HTTP version used for the response.
     *
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public final String getVersion()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	return Version;
    }

    /**
     * Get the name and type of server.
     *
     * @deprecated This method is a remnant of V0.1; use
     *             <code>getHeader("Server")</code> instead.
     * @see #getHeader(java.lang.String)
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public final String getServer()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	return getHeader("Server");
    }


    /**
     * Get the original URI used in the request.
     *
     * @return the URI used in primary request
     */
    public final URI getOriginalURI()
    {
	return OriginalURI;
    }


    /**
     * Get the final URL of the document. This is set if the original
     * request was deferred via the "moved" (301, 302, or 303) return
     * status.
     *
     * @return the effective URL, or null if no redirection occured
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     * @deprecated use getEffectiveURI() instead
     * @see #getEffectiveURI
     */
    public final URL getEffectiveURL()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	if (EffectiveURI != null)
	    return EffectiveURI.toURL();
	return null;
    }


    /**
     * Get the final URI of the document. If the request was redirected
     * via the "moved" (301, 302, 303, or 307) return status this returns
     * the URI used in the last redirection; otherwise it returns the
     * original URI.
     *
     * @return the effective URI
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public final URI getEffectiveURI()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	if (EffectiveURI != null)
	    return EffectiveURI;
	return OriginalURI;
    }


    /**
     * Retrieves the value for a given header.
     *
     * @param  hdr the header name.
     * @return the value for the header, or null if non-existent.
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public String getHeader(String hdr)  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	return (String) Headers.get(hdr.trim());
    }

    /**
     * Retrieves the value for a given header. The value is parsed as an
     * int.
     *
     * @param  hdr the header name.
     * @return the value for the header if the header exists
     * @exception NumberFormatException if the header's value is not a number
     *                                  or if the header does not exist.
     * @exception IOException if any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public int getHeaderAsInt(String hdr)
		throws IOException, ModuleException, NumberFormatException
    {
	String val = getHeader(hdr);
	if (val == null)
	    throw new NumberFormatException("null");
	return Integer.parseInt(val);
    }

    /**
     * Retrieves the value for a given header. The value is parsed as a
     * date; if this fails it is parsed as a long representing the number
     * of seconds since 12:00 AM, Jan 1st, 1970. If this also fails an
     * exception is thrown.
     * <br>Note: When sending dates use Util.httpDate().
     *
     * @param  hdr the header name.
     * @return the value for the header, or null if non-existent.
     * @exception IllegalArgumentException if the header's value is neither a
     *            legal date nor a number.
     * @exception IOException if any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public Date getHeaderAsDate(String hdr)
		throws IOException, IllegalArgumentException, ModuleException
    {
	String raw_date = getHeader(hdr);
	if (raw_date == null) return null;

	// asctime() format is missing an explicit GMT specifier
	if (raw_date.toUpperCase().indexOf("GMT") == -1  &&
	    raw_date.indexOf(' ') > 0)
	    raw_date += " GMT";

	Date   date;

	try
	    { date = Util.parseHttpDate(raw_date); }
	catch (IllegalArgumentException iae)
	{
	    // some servers erroneously send a number, so let's try that
	    long time;
	    try
		{ time = Long.parseLong(raw_date); }
	    catch (NumberFormatException nfe)
		{ throw iae; }	// give up
	    if (time < 0)  time = 0;
	    date = new Date(time * 1000L);
	}

	return date;
    }

    /**
     * Returns an enumeration of all the headers available via getHeader().
     *
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public Enumeration listHeaders()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();
	return Headers.keys();
    }


    /**
     * Retrieves the value for a given trailer. This should not be invoked
     * until all response data has been read. If invoked before it will
     * call <code>getData()</code> to force the data to be read.
     *
     * @param  trailer the trailer name.
     * @return the value for the trailer, or null if non-existent.
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     * @see #getData()
     */
    public String getTrailer(String trailer) throws IOException, ModuleException
    {
	if (!got_trailers)  getTrailers();
	return (String) Trailers.get(trailer.trim());
    }

    /**
     * Retrieves the value for a given tailer. The value is parsed as an
     * int.
     *
     * @param  trailer the tailer name.
     * @return the value for the trailer if the trailer exists
     * @exception NumberFormatException if the trailer's value is not a number
     *                                  or if the trailer does not exist.
     * @exception IOException if any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public int getTrailerAsInt(String trailer)
		throws IOException, ModuleException, NumberFormatException
    {
	String val = getTrailer(trailer);
	if (val == null)
	    throw new NumberFormatException("null");
	return Integer.parseInt(val);
    }

    /**
     * Retrieves the value for a given trailer. The value is parsed as a
     * date; if this fails it is parsed as a long representing the number
     * of seconds since 12:00 AM, Jan 1st, 1970. If this also fails an
     * IllegalArgumentException is thrown.
     * <br>Note: When sending dates use Util.httpDate().
     *
     * @param  trailer the trailer name.
     * @return the value for the trailer, or null if non-existent.
     * @exception IllegalArgumentException if the trailer's value is neither a
     *            legal date nor a number.
     * @exception IOException if any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public Date getTrailerAsDate(String trailer)
		throws IOException, IllegalArgumentException, ModuleException
    {
	String raw_date = getTrailer(trailer);
	if (raw_date == null) return null;

	// asctime() format is missing an explicit GMT specifier
	if (raw_date.toUpperCase().indexOf("GMT") == -1  &&
	    raw_date.indexOf(' ') > 0)
	    raw_date += " GMT";

	Date   date;

	try
	    { date = Util.parseHttpDate(raw_date); }
	catch (IllegalArgumentException iae)
	{
	    // some servers erroneously send a number, so let's try that
	    long time;
	    try
		{ time = Long.parseLong(raw_date); }
	    catch (NumberFormatException nfe)
		{ throw iae; }	// give up
	    if (time < 0)  time = 0;
	    date = new Date(time * 1000L);
	}

	return date;
    }

    /**
     * Returns an enumeration of all the trailers available via getTrailer().
     *
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public Enumeration listTrailers()  throws IOException, ModuleException
    {
	if (!got_trailers)  getTrailers();
	return Trailers.keys();
    }


    /**
     * Reads all the response data into a byte array. Note that this method
     * won't return until <em>all</em> the data has been received (so for
     * instance don't invoke this method if the server is doing a server
     * push). If <code>getInputStream()</code> had been previously invoked
     * then this method only returns any unread data remaining on the stream
     * and then closes it.
     *
     * <P>Note to the unwarry: code like
     *    <code>System.out.println("The data: " + resp.getData())</code>
     * will probably not do what you want - use
     *    <code>System.out.println("The data: " + new String(resp.getData()))</code>
     * instead.
     *

⌨️ 快捷键说明

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