📄 httpresponse.java
字号:
/* * @(#)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 + -