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

📄 httpinputstreamreader.java

📁 [linux.rar] - 嵌入式linux开发教程
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package wjhk.jupload2.upload.helper;

import java.io.IOException;
import java.io.PushbackInputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.SSLSocket;

import wjhk.jupload2.exception.JUploadException;
import wjhk.jupload2.policies.UploadPolicy;

/**
 * A helper, to read the response coming from the server.
 * 
 * @author etienne_sf
 */
public class HTTPInputStreamReader {
    // //////////////////////////////////////////////////////////////////////////////
    // //////////////////// Main attributes
    // //////////////////////////////////////////////////////////////////////////////

    /**
     * The current upload policy, always useful.
     */
    private UploadPolicy uploadPolicy = null;

    private HTTPConnectionHelper httpConnectionHelper = null;

    /**
     * Contains the HTTP response body, that is: the server response, without
     * the headers.
     */
    String responseBody = null;

    /**
     * The headers of the HTTP response.
     */
    String responseHeaders = null;

    /**
     * The status message from the first line of the response (e.g. "200 OK").
     */
    String responseMsg = null;

    // ////////////////////////////////////////////////////////////////////////////////////
    // /////////////////// ATTRIBUTE CONTAINING DATA COMING FROM THE RESPONSE
    // ////////////////////////////////////////////////////////////////////////////////////

    private CookieJar cookies = new CookieJar();

    boolean gotClose = false;

    private boolean gotChunked = false;

    private boolean gotContentLength = false;

    private int clen = 0;

    /**
     * The server HTTP response. Should be 200, in case of success.
     */
    private int httpStatusCode = 0;

    private String line = "";

    private byte[] body = new byte[0];

    private String charset = "ISO-8859-1";

    // ////////////////////////////////////////////////////////////////////////////////////
    // /////////////////// CONSTANTS USED TO CONTROL THE HTTP INTPUT
    // ////////////////////////////////////////////////////////////////////////////////////
    private final static int CHUNKBUF_SIZE = 4096;

    private final byte chunkbuf[] = new byte[CHUNKBUF_SIZE];

    private final static Pattern pChunked = Pattern.compile(
            "^Transfer-Encoding:\\s+chunked", Pattern.CASE_INSENSITIVE);

    private final static Pattern pClose = Pattern.compile(
            "^Connection:\\s+close", Pattern.CASE_INSENSITIVE);

    private final static Pattern pProxyClose = Pattern.compile(
            "^Proxy-Connection:\\s+close", Pattern.CASE_INSENSITIVE);

    private final static Pattern pHttpStatus = Pattern
            .compile("^HTTP/\\d\\.\\d\\s+((\\d+)\\s+.*)$");

    private final static Pattern pContentLen = Pattern.compile(
            "^Content-Length:\\s+(\\d+)$", Pattern.CASE_INSENSITIVE);

    private final static Pattern pContentTypeCs = Pattern.compile(
            "^Content-Type:\\s+.*;\\s*charset=([^;\\s]+).*$",
            Pattern.CASE_INSENSITIVE);

    private final static Pattern pSetCookie = Pattern.compile(
            "^Set-Cookie:\\s+(.*)$", Pattern.CASE_INSENSITIVE);

    /**
     * The standard constructor: does nothing ! Oh yes, it initialize some
     * attribute from the given parameter... :-)
     * 
     * @param httpConnectionHelper The connection helper, associated with this
     *            instance.
     * @param uploadPolicy The current upload policy.
     */
    public HTTPInputStreamReader(HTTPConnectionHelper httpConnectionHelper,
            UploadPolicy uploadPolicy) {
        this.httpConnectionHelper = httpConnectionHelper;
        this.uploadPolicy = uploadPolicy;
    }

    /**
     * Return the last read http response (200, in case of success).
     * 
     * @return The last read http response
     */
    public int gethttpStatusCode() {
        return this.httpStatusCode;
    }

    /**
     * Get the last response body.
     * 
     * @return The last read response body.
     */
    public String getResponseBody() {
        return this.responseBody;
    }

    /**
     * Get the headers of the HTTP response.
     * 
     * @return The HTTP headers.
     */
    public String getResponseHeaders() {
        return this.responseHeaders;
    }

    /**
     * Get the last response message.
     * 
     * @return The response message from the first line of the response (e.g.
     *         "200 OK").
     */
    public String getResponseMsg() {
        return this.responseMsg;
    }

    /**
     * The main method: reads the response in the input stream.
     * 
     * @return The response status (e.g.: 200 if everything was ok)
     * @throws JUploadException
     */
    public int readHttpResponse() throws JUploadException {
        PushbackInputStream httpDataIn = this.httpConnectionHelper
                .getInputStream();

        try {
            // If the user requested abort, we are not going to send
            // anymore, so shutdown the outgoing half of the socket.
            // This helps the server to speed up with it's response.
            if (this.httpConnectionHelper.gotStopped()
                    && !(this.httpConnectionHelper.getSocket() instanceof SSLSocket))
                this.httpConnectionHelper.getSocket().shutdownOutput();

            // We first read the headers,
            readHeaders(httpDataIn);

            // then the body.
            // If we're in a HEAD request ... we're not interested in the body!
            if (this.httpConnectionHelper.getMethod().equals("HEAD")) {
                this.uploadPolicy.displayDebug(
                        "This is a HEAD request: we don't care about the body",
                        70);
                this.responseBody = "";
            } else {
                readBody(httpDataIn);
            }
        } catch (Exception e) {
            throw new JUploadException(e);
        }

        return this.httpStatusCode;
    }

    // //////////////////////////////////////////////////////////////////////////////////////
    // //////////////////// Various utilities
    // //////////////////////////////////////////////////////////////////////////////////////

    /**
     * Concatenates two byte arrays.
     * 
     * @param buf1 The first array
     * @param buf2 The second array
     * @return A byte array, containing buf2 appended to buf2
     */
    static byte[] byteAppend(byte[] buf1, byte[] buf2) {
        byte[] ret = new byte[buf1.length + buf2.length];
        System.arraycopy(buf1, 0, ret, 0, buf1.length);
        System.arraycopy(buf2, 0, ret, buf1.length, buf2.length);
        return ret;
    }

    /**
     * Concatenates two byte arrays.
     * 
     * @param buf1 The first array
     * @param buf2 The second array
     * @param len Number of bytes to copy from buf2
     * @return A byte array, containing buf2 appended to buf2
     */
    static byte[] byteAppend(byte[] buf1, byte[] buf2, int len) {
        if (len > buf2.length)
            len = buf2.length;
        byte[] ret = new byte[buf1.length + len];
        System.arraycopy(buf1, 0, ret, 0, buf1.length);
        System.arraycopy(buf2, 0, ret, buf1.length, len);
        return ret;
    }

    /**
     * Similar like BufferedInputStream#readLine() but operates on raw bytes.
     * Line-Ending is <b>always</b> "\r\n".
     * 
     * @param inputStream
     * 
     * @param charset The input charset of the stream.
     * @param includeCR Set to true, if the terminating CR/LF should be included
     *            in the returned byte array.
     * @return The line, encoded from the input stream with the given charset
     * @throws IOException
     */
    public static String readLine(PushbackInputStream inputStream,
            String charset, boolean includeCR) throws IOException {
        byte[] line = readLine(inputStream, includeCR);
        return (null == line) ? null : new String(line, charset);
    }

    /**
     * Similar like BufferedInputStream#readLine() but operates on raw bytes.
     * According to RFC 2616, and of line may be CR (13), LF (10) or CRLF.
     * Line-Ending is <b>always</b> "\r\n" in header, but not in text bodies.
     * Update done by TedA (sourceforge account: tedaaa). Allows to manage
     * response from web server that send LF instead of CRLF ! Here is a part of
     * the RFC: <I>"we recommend that applications, when parsing such headers,
     * recognize a single LF as a line terminator and ignore the leading
     * CR"</I>. <BR>
     * Corrected again to manage line finished by CR only. This is not allowed
     * in headers, but this method is also used to read lines in the body.
     * 
     * @param inputStream
     * 
     * @param includeCR Set to true, if the terminating CR/LF should be included
     *            in the returned byte array. In this case, CR/LF is always
     *            returned to the caller, whether the input stream got CR, LF or
     *            CRLF.
     * @return The byte array from the input stream, with or without a trailing
     *         CRLF
     * @throws IOException
     */
    public static byte[] readLine(PushbackInputStream inputStream,
            boolean includeCR) throws IOException {
        final byte EOS = -1;
        final byte CR = 13;
        final byte LF = 10;
        int len = 0;
        int buflen = 128; // average line length
        byte[] buf = new byte[buflen];
        byte[] ret = null;
        int b;
        boolean lineRead = false;

⌨️ 快捷键说明

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