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

📄 protocol.java

📁 用于移动设备上的java虚拟机源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        reqLine.append(HTTP_VERSION);        reqLine.append("\r\n");        /*         * HTTP 1/1 requests require the Host header to distinguish         * virtual host locations.         */                setRequestField("Host", url.authority);        if (chunkedOut) {            /*             * Signal the server that the body is chunked             * by setting the Transfer-Encoding property to "chunked".             */            setRequestField("Transfer-Encoding", "chunked");        }        /*         * Setup the various http header field/values defined and/or         * required.         */        numberOfKeys = reqProperties.size();        for (int i = 0; i < numberOfKeys; i++) {            String key = (String)reqProperties.getKeyAt(i);                        if (key.equals("Content-Length")) {                /*                 * If its CHUNK data - no content-length: size required.                 */                if (chunkedOut) {                    continue;                                         } else {                    /*                     * Check that the output stream has been opened.                     */                    if (writebuf == null) {                        reqLine.append("Content-Length: 0");                    } else {                        reqLine.append("Content-Length: ");                        reqLine.append(bytesToWrite);                    }                    reqLine.append("\r\n");                }            } else {                reqLine.append(key);                reqLine.append(": ");                reqLine.append(reqProperties.getValueAt(i));                reqLine.append("\r\n");            }        }                reqLine.append("\r\n");        streamOutput.write(reqLine.toString().getBytes());    }    /**     * Write the http request body bytes to the output stream.     *     * @exception IOException      */    protected void sendRequestBody() throws IOException {        int start;        int endOfData;        int length;        if ((writebuf == null) || (bytesToWrite == 0)) {            return;        }        start = HTTP_OUTPUT_DATA_OFFSET;        endOfData = HTTP_OUTPUT_DATA_OFFSET + bytesToWrite;        length = bytesToWrite;        /*         * If a CHUNKed session then write out the chunk size first          * with a trailing CRLF.         *         * reference: RFC2616 - section 3 protocol parameters         * 3.6 transfer coding:         * 3.6.1 chunked transfer coding:         * chunk-body = chunk / last chunk / trailer / CRLF         *       * chunk =      chunk-size / chunk-data / CRLF         *         last_chunk = "0" / CRLF         *         trailer    = " " / CRLF         * *indicates its done here.         */        if (chunkedOut) {            /*             * For CHUNKed write out the chunk size with CRLF.             * Put this before the data in write buffer.             */            String temp = Integer.toHexString(bytesToWrite);            int tempLen = temp.length();            writebuf[--start] = (byte)'\n';            writebuf[--start] = (byte)'\r';            for (int i = tempLen - 1; i >= 0; i--) {                writebuf[--start] = (byte)temp.charAt(i);            }            length += tempLen + 2;            /*             * If a CHUNKed session then write out another CRLF and flush().             * Put this after the data in the write bufffer.             */            writebuf[endOfData++] = (byte)'\r';            writebuf[endOfData++] = (byte)'\n';            length += 2;        }                   streamOutput.write(writebuf, start, length);        bytesToWrite = 0;    }    /**     * Finish the http request and reads the response headers.     *     * @exception IOException is thrown, if an I/O error occurs for final     *            stream output or on reading the response message line     */    protected void finishRequestGetResponseHeader() throws IOException {        // Even if we get an exception this request is finished        requestFinished = true;        /*         * if this is a CHUNKed session write out the last set of CRLF         */        if (chunkedOut) {            /*             * reference: RFC2616 - section 3 protocol parameters             * 3.6 transfer coding:             * 3.6.1 chunked transfer coding:             * chunk-body = chunk / last chunk / trailer / CRLF             *         chunk =      chunk-size / chunk-data / CRLF             *       * last_chunk = "0" / CRLF             *       * trailer    = " " / CRLF             * * indicates its done here.             */                        /*             * write the last chunk (size=0 / CRLF) and the dummy trailer              */            streamOutput.write("0\r\n\r\n".getBytes());         }        streamOutput.flush();        readResponseMessage(streamInput);        readHeaders(streamInput);                /*         * Ignore a continuation header and read the true headers again.         * (Bug# 4382226 discovered with Jetty HTTP 1.1 web server.         */        if (responseCode == 100) {            readResponseMessage(streamInput);            readHeaders(streamInput);        }    }    /**     * Connect to the underlying network TCP transport.     * If the proxy is configured, connect to it as tunnel first.     * <p>     * Warning: A subclass that implements this method, should not call this     * method and should implement the disconnect method.     *     * @return network stream connection     * @exception IOException is thrown if the connection cannot be opened     */    protected StreamConnection connect() throws IOException {        com.sun.midp.io.j2me.socket.Protocol conn;        verifyPermissionCheck();        conn = new com.sun.midp.io.j2me.socket.Protocol();        if (http_proxy == null) {            conn.openPrim(classSecurityToken, "//" + hostAndPort);            // Do not delay request since this delays the response.            conn.setSocketOption(SocketConnection.DELAY, 0);            return conn;        }              conn.openPrim(classSecurityToken, "//" + http_proxy);        // Do not delay request since this delays the response.        conn.setSocketOption(SocketConnection.DELAY, 0);        // openData*Stream cannot be call twice, so save them for later        streamOutput = conn.openDataOutputStream();        streamInput = conn.openDataInputStream();        try {            doTunnelHandshake(streamOutput, streamInput);        } catch (IOException ioe) {            String response = ioe.getMessage();            try {                disconnect(conn, streamInput, streamOutput);            } catch (Exception e) {                // do not over throw the handshake exception            }            streamOutput = null;            streamInput = null;            if ((response != null) && (response.indexOf(" 500 ") > -1)) {                throw new ConnectionNotFoundException(response);            } else {                throw ioe;            }        }        return conn;    }    /**     * Connects to the SSL tunnel and completes the intialization of the     * tunnel (handshake). The handshake based on the Internet-Draft     *  "A. Luotonen, Tunneling TCP based protocols through Web proxy servers,     *  February 1999".     * @param os output stream for secure handshake     * @param is input stream for secure handshake     * @exception IOException is thrown if an error occurs in the SSL handshake     */     protected void doTunnelHandshake(OutputStream os, InputStream is) throws            IOException {        String required;        String optional;        String endOfLine = "\r\n";        String emptyLine = endOfLine;        int numberOfKeys;        StringBuffer temp;        boolean newline;        String response;        /*         * request = required *optional emptyLine         * required = "CONNECT" SP HOST ":" PORT SP HTTP_VERSION endOfLine         * optional = HTTP_HEADER endOfLine ; proxy dependent: most likely         *                                  ; used for authorization.         * emptyLine = endOfLine         * endOfLine = *1CR LF         *         * example:         * CONNECT home.acme.com:443 HTTP/1.0         * Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==         *         */        required = "CONNECT " + hostAndPort + " " + HTTP_VERSION + endOfLine;        os.write(required.getBytes());        numberOfKeys = proxyHeaders.size();        for (int i = 0; i < numberOfKeys; i++) {            optional = proxyHeaders.getKeyAt(i) + ": " +                       proxyHeaders.getValueAt(i) + endOfLine;            os.write(optional.getBytes());        }        os.write(emptyLine.getBytes());        os.flush();        /*         * response = status *optional emptyLine         * status = HTTP_VERSION SP STATUSCODE STATUS_MESSAGE *1CR LF         * optional = HTTP_HEADER *1CR LF         * emptyLine = *1CR LF         *         * example:         * HTTP/1.0 200 Connection established         *         */        // Read in response until an empty line is found (1*CR LF 1*CR LF)        temp = new StringBuffer();        newline = false;        while (true) {            int c = is.read();            if (c == -1) {                break;            } else if (c == '\n') {                if (newline) {                    break;                }                newline = true;            } else if (c != '\r') {                newline = false;            }            temp.append((char)c);        }        if (temp.length() == 0) {            temp.append("none");        }        response = temp.toString();        if (response.indexOf(" 200 ") == -1) {            throw new                IOException("Error initializing HTTP tunnel connection: \n"                            + response);        }    }        /**      * Check the initial response message looking for the      * appropriate HTTP version string. Parse the response      * code for easy application branching on condition codes.     *     * @param in input stream where the response headers are read     * @exception IOException  is thrown if the header response can      *                         not be parsed     */    private void readResponseMessage(InputStream in) throws IOException {        String line = null;        responseCode = -1;        responseMsg = null;        line = readLine(in);        /*         * REFERENCE: HTTP1.1 document          * SECTION: 3.6.1 Chunked Transfer Coding         * in some cases there may be an OPTIONAL trailer containing          * entity-header fields. since we don't support the available()         * method for inputstreams and for performance reasons we         * do not attempt to clean up the previous connections input         * stream. the first thing we do here is read the stream and          * discard it.         */        if (line != null && line.length() == 0) {            line = readLine(in);        }                    int httpEnd, codeEnd;                responseCode = -1;        responseMsg = null;        if (line == null) {            throw new IOException("response empty");        }        httpEnd = line.indexOf(' ');        if (httpEnd < 0) {            if (line.length() > 10) {                // only put the first 10 chars in the exception                line = line.substring(0, 10);            }            throw new IOException("cannot find status code in response: " +                line);        }            String temp = line.substring(0, httpEnd);        if (!temp.startsWith("HTTP")) {            if (httpEnd > 10) {                // only put the first 10 chars in the exception                temp = temp.substring(0, 10);            }            throw new IOException("response does not start with HTTP " +                 "it starts with: " + temp);        }        httpVer = temp;        if (line.length() <= httpEnd) {            throw new IOException("status line ends after HTTP version");        }            codeEnd = line.substring(httpEnd + 1).indexOf(' ');        if (codeEnd < 0) {            throw new IOException("cannot find reason phrase in response");        }        codeEnd += (httpEnd + 1);        if (line.length() <= codeEnd) {            throw new IOException("status line end after status code");        }            try {            responseCode = Integer.parseInt(line.substring(httpEnd+1,                                                                codeEnd));        } catch (NumberFormatException nfe) {            throw new IOException("status code in response is not a number");        }            responseMsg = line.substring(codeEnd + 1);    }    /**      * Read the response message headers.     * Parse the response headers name value pairs for easy application use.     *     * @param in input stream where the response headers are read     * @exception IOException  is throw

⌨️ 快捷键说明

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