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

📄 httpresponse.java

📁 SMS SDK classes.This is the archive that must be included in the classpath.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     * @see #getInputStream()
     * @return an array containing the data (body) returned. If no data
     *         was returned then it's set to a zero-length array.
     * @exception IOException If any io exception occured while reading
     *			      the data
     * @exception ModuleException if any module encounters an exception.
     */
    public synchronized byte[] getData()  throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();

	if (Data == null)
	{
	    try
		{ readResponseData(inp_stream); }
	    catch (InterruptedIOException ie)		// don't intercept
	    {
		throw ie;
	    }
	    catch (IOException ioe)
	    {
		Log.write(Log.RESP, "HResp: (\"" + method + " " +
				    OriginalURI.getPathAndQuery() + "\")");
		Log.write(Log.RESP, "       ", ioe);

		try { inp_stream.close(); } catch (Exception e) { }
		throw ioe;
	    }

	    inp_stream.close();
	}

	return Data;
    }

    /**
     * Gets an input stream from which the returned data can be read. Note
     * that if <code>getData()</code> had been previously invoked it will
     * actually return a ByteArrayInputStream created from that data.
     *
     * @see #getData()
     * @return the InputStream.
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public synchronized InputStream getInputStream()
	    throws IOException, ModuleException
    {
	if (!initialized)  handleResponse();

	if (Data == null)
	    return inp_stream;
	else
	{
	    getData();		// ensure complete data is read
	    return new ByteArrayInputStream(Data);
	}
    }


    /**
     * Should the request be retried by the application? If the application
     * used an <var>HttpOutputStream</var> in the request then various
     * modules (such as the redirection and authorization modules) are not
     * able to resend the request themselves. Instead, it becomes the
     * application's responsibility.
     *
     * <P>If the application resends the request then it <strong>must</strong>
     * use the same <var>HttpOutputStream</var> instance. This is because the
     * modules use this to recognize the retried request and to perform the
     * necessary work on the request before it's sent.
     *
     * <P>Here is a skeleton example of usage:
     * <PRE>
     *     OutputStream out = new HttpOutputStream(1234);
     *     do
     *     {
     *         rsp = con.Post("/cgi-bin/my_cgi", out);
     *         out.write(...);
     *         out.close();
     *     } while (rsp.retryRequest());
     *
     *     if (rsp.getStatusCode() >= 300)
     *         ...
     * </PRE>
     *
     * @return true if the request should be retried.
     * @exception IOException If any exception occurs on the socket.
     * @exception ModuleException if any module encounters an exception.
     */
    public boolean retryRequest()  throws IOException, ModuleException
    {
	if (!initialized)
	{
	    try
		{ handleResponse(); }
	    catch (RetryException re)
		{ this.retry = response.retry; }
	}
	return retry;
    }


    /**
     * produces a full list of headers and their values, one per line.
     *
     * @return a string containing the headers
     */
    public String toString()
    {
	if (!initialized)
	{
	    try
		{ handleResponse(); }
	    catch (Exception e)
	    {
		if (!(e instanceof InterruptedIOException))
		{
		    Log.write(Log.RESP, "HResp: (\"" + method + " " +
				        OriginalURI.getPathAndQuery() + "\")");
		    Log.write(Log.RESP, "       ", e);
		}
		return "Failed to read headers: " + e;
	    }
	}

	String nl = System.getProperty("line.separator", "\n");

	StringBuffer str = new StringBuffer(Version);
	str.append(' ');
	str.append(StatusCode);
	str.append(' ');
	str.append(ReasonLine);
	str.append(nl);

	if (EffectiveURI != null)
	{
	    str.append("Effective-URI: ");
	    str.append(EffectiveURI);
	    str.append(nl);
	}

	Enumeration hdr_list = Headers.keys();
	while (hdr_list.hasMoreElements())
	{
	    String hdr = (String) hdr_list.nextElement();
	    str.append(hdr);
	    str.append(": ");
	    str.append(Headers.get(hdr));
	    str.append(nl);
	}

	return str.toString();
    }


    // Helper Methods


    HTTPClientModule[] getModules()
    {
	return modules;
    }


    /**
     * Processes a Response. This is done by calling the response handler
     * in each module. When all is done, the various fields of this instance
     * are intialized from the last Response.
     *
     * @exception IOException if any handler throws an IOException.
     * @exception ModuleException if any module encounters an exception.
     * @return true if a new request was generated. This is used for internal
     *         subrequests only
     */
    synchronized boolean handleResponse()  throws IOException, ModuleException
    {
	if (initialized)  return false;


	/* first get the response if necessary */

	if (out_stream != null)
	{
	    response           = out_stream.getResponse();
	    response.http_resp = this;
	    out_stream         = null;
	}


	/* go through modules and handle them */

	doModules: while (true)
	{

	Phase1: for (int idx=0; idx<modules.length && !aborted; idx++)
	{
	    try
		{ modules[idx].responsePhase1Handler(response, request); }
	    catch (RetryException re)
	    {
		if (re.restart)
		    continue doModules;
		else
		    throw re;
	    }
	}

	Phase2: for (int idx=0; idx<modules.length && !aborted; idx++)
	{
            int sts = modules[idx].responsePhase2Handler(response, request);
            switch (sts)
            {
                case RSP_CONTINUE:	// continue processing
                    break;

                case RSP_RESTART:	// restart response processing
                    idx = -1;
		    continue doModules;

                case RSP_SHORTCIRC:	// stop processing and return
                    break doModules;

                case RSP_REQUEST:	// go to phase 1
                case RSP_NEWCON_REQ:	// process the request using a new con
		    response.getInputStream().close();
		    if (handle_trailers) invokeTrailerHandlers(true);
		    if (request.internal_subrequest)  return true;
		    request.getConnection().
				handleRequest(request, this, response, true);
		    if (initialized)  break doModules;

                    idx = -1;
		    continue doModules;

                case RSP_SEND:		// send the request immediately
                case RSP_NEWCON_SND:	// send the request using a new con
		    response.getInputStream().close();
		    if (handle_trailers) invokeTrailerHandlers(true);
		    if (request.internal_subrequest)  return true;
		    request.getConnection().
				handleRequest(request, this, response, false);
                    idx = -1;
		    continue doModules;

                default:                // not valid
                    throw new Error("HTTPClient Internal Error: invalid status"+
                                    " " + sts + " returned by module " +
                                    modules[idx].getClass().getName());
	    }
	}

	Phase3: for (int idx=0; idx<modules.length && !aborted; idx++)
	{
            modules[idx].responsePhase3Handler(response, request);
	}

	break doModules;
	}

	/* force a read on the response in case none of the modules did */
	response.getStatusCode();

	/* all done, so copy data */
	if (!request.internal_subrequest)
	    init(response);

	if (handle_trailers)
	    invokeTrailerHandlers(false);

	return false;
    }


    /**
     * Copies the relevant fields from Response and marks this as initialized.
     *
     * @param resp the Response class to copy from
     */
    void init(Response resp)
    {
	if (initialized)  return;

	this.StatusCode    = resp.StatusCode;
	this.ReasonLine    = resp.ReasonLine;
	this.Version       = resp.Version;
	this.EffectiveURI  = resp.EffectiveURI;
	this.ContentLength = resp.ContentLength;
	this.Headers       = resp.Headers;
	this.inp_stream    = resp.inp_stream;
	this.Data          = resp.Data;
	this.retry         = resp.retry;
	initialized        = true;

	// for HotJava (or anybody else)
	try
	{
	    if (pe != null  &&  ContentLength != -1)
	    {
		pe.setType(Util.getPath(request.getRequestURI()),
			   getHeader("Content-type"));
		sun.net.ProgressData.pdata.register(pe);
		pe.update(0, ContentLength);
	    }
	}
	catch (Throwable t)
	{
	    Log.write(Log.RESP, "Resp: ", t);
	}
    }


    private boolean handle_trailers  = false;
    private boolean trailers_handled = false;

    /**
     * This is invoked by the RespInputStream when it is close()'d. It
     * just invokes the trailer handler in each module.
     *
     * @param force invoke the handlers even if not initialized yet?
     * @exception IOException     if thrown by any module
     * @exception ModuleException if thrown by any module
     */
    void invokeTrailerHandlers(boolean force)
	    throws IOException, ModuleException
    {
	if (trailers_handled)  return;

	if (!force  &&  !initialized)
	{
	    handle_trailers = true;
	    return;
	}

	for (int idx=0; idx<modules.length && !aborted; idx++)
	{
            modules[idx].trailerHandler(response, request);
	}

	trailers_handled = true;
    }


    ProgressEntry pe = null;

    /**
     * The ProgressEntry is used by HotJava to monitor the loading progress.
     * HttpURLConnection sets this.
     *
     * @param pe a ProgressEntry
     */
    void setProgressEntry(ProgressEntry pe)
    {
	this.pe = pe;
    }


    /**
     * Unset and unregister any ProgressEntry.
     *
     * @see #setProgressEntry(sun.net.ProgressEntry)
     */
    void unsetProgressEntry()
    {
	if (pe != null)
	{
	    try
		{ sun.net.ProgressData.pdata.unregister(pe); }
	    catch (Throwable t)
		{ }
	    pe = null;
	}
    }


    /**
     * Mark this request as having been aborted. It's invoked by
     * HTTPConnection.stop().
     */
    void markAborted()
    {
	aborted = true;
    }


    /**
     * Gets any trailers from the response if we haven't already done so.
     */
    private synchronized void getTrailers()  throws IOException, ModuleException
    {
	if (got_trailers)  return;
	if (!initialized)  handleResponse();

	response.getTrailer("Any");
	Trailers = response.Trailers;
	got_trailers = true;

	invokeTrailerHandlers(false);
    }


    /**
     * Reads the response data received. Does not return until either
     * Content-Length bytes have been read or EOF is reached.
     *
     * @inp       the input stream from which to read the data
     * @exception IOException if any read on the input stream fails
     */
    private void readResponseData(InputStream inp)
	    throws IOException, ModuleException
    {
	if (ContentLength == 0)
	    return;

	if (Data == null)
	    Data = new byte[0];


	// read response data

	int off = Data.length;

	try
	{
	    // check Content-length header in case CE-Module removed it
	    if (getHeader("Content-Length") != null)
	    {
		int rcvd = 0;
		Data = new byte[ContentLength];

		do
		{
		    off  += rcvd;
		    rcvd  = inp.read(Data, off, ContentLength-off);
		} while (rcvd != -1  &&  off+rcvd < ContentLength);

                /* Don't do this!
		 * If we do, then getData() won't work after a getInputStream()
		 * because we'll never get all the expected data. Instead, let
		 * the underlying RespInputStream throw the EOF.
		if (rcvd == -1)	// premature EOF
		{
		    throw new EOFException("Encountered premature EOF while " +
					    "reading headers: received " + off +
					    " bytes instead of the expected " +
					    ContentLength + " bytes");
		}
		*/
	    }
	    else
	    {
		int inc  = 1000,
		    rcvd = 0;

		do
		{
		    off  += rcvd;
		    Data  = Util.resizeArray(Data, off+inc);
		} while ((rcvd = inp.read(Data, off, inc)) != -1);

		Data = Util.resizeArray(Data, off);
	    }
	}
	catch (IOException ioe)
	{
	    Data = Util.resizeArray(Data, off);
	    throw ioe;
	}
	finally
	{
	    try
		{ inp.close(); }
	    catch (IOException ioe)
		{ }
	}
    }


    int getTimeout()
    {
	return timeout;
    }
}

⌨️ 快捷键说明

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