<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    9910

    單飛

       :: 首頁 :: 聯系 :: 聚合  :: 管理
    rfc2616

    對于返回是chunked格式的字節流的處理

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    /**
     * http response chunked transfer type input stream
     * 
    @author jeffrey.ship
     *
     
    */
    public class ChunkedInputStream {

        
    public static final int CR = 13// <US-ASCII CR, carriage return (13)>

        
    public static final int LF = 10// <US-ASCII LF, linefeed (10)>

        
    public static final int SP = 32// <US-ASCII SP, space (32)>

        
    public static final int HT = 9// <US-ASCII HT, horizontal-tab (9)>

        
    private InputStream is;

        
    private StringBuffer stringbuffer;// share buffer

        
    private Map<String, String> headerFields;

        
    private int responseCode;

        
    private String responseMsg;

        
    private int bytesleft; // Number of bytes left in current chunk

        
    private int bytesread; // Number of bytes read since the stream was opened

        
    private boolean chunked; // True if Transfer-Encoding: chunked

        
    private boolean eof; // True if EOF seen

        
    public ChunkedInputStream(InputStream is) {
            
    this.is = is;
            headerFields 
    = new HashMap<String, String>();
            stringbuffer 
    = new StringBuffer(32);
        }

        
    public void init() throws Exception {
            readResponseMessage(is);
            readHeaders(is);

            
    // Determine if this is a chunked datatransfer and setup
            String te = (String) headerFields.get("transfer-encoding");
            
    if (te != null && te.equals("chunked")) {
                chunked 
    = true;
                bytesleft 
    = readChunkSize();
                eof 
    = (bytesleft == 0);
            }
        }

        
    private void readResponseMessage(InputStream in) throws IOException {
            String line 
    = readLine(in);
            
    int httpEnd, codeEnd;

            responseCode 
    = -1;
            responseMsg 
    = null;

            malformed: {
                
    if (line == null)
                    
    break malformed;

                httpEnd 
    = line.indexOf(' ');

                
    if (httpEnd < 0)
                    
    break malformed;

                String httpVer 
    = line.substring(0, httpEnd);

                
    if (!httpVer.startsWith("HTTP"))
                    
    break malformed;

                
    if (line.length() <= httpEnd)
                    
    break malformed;

                codeEnd 
    = line.substring(httpEnd + 1).indexOf(' ');

                
    if (codeEnd < 0)
                    
    break malformed;

                codeEnd 
    += (httpEnd + 1);

                
    if (line.length() <= codeEnd)
                    
    break malformed;

                
    try {
                    responseCode 
    = Integer.parseInt(line.substring(httpEnd + 1, codeEnd));
                } 
    catch (NumberFormatException nfe) {
                    
    break malformed;
                }

                responseMsg 
    = line.substring(codeEnd + 1);
                
    return;
            }

            
    throw new IOException("malformed response message");
        }
        
        

        
    public int getResponseCode() {
            
    return responseCode;
        }

        
    public String getResponseMsg() {
            
    return responseMsg;
        }

        
    private void readHeaders(InputStream in) throws IOException {
            String line, key, value;
            
    int index;

            
    for (;;) {
                line 
    = readLine(in);

                
    if (line == null || line.equals(""))
                    
    return;

                index 
    = line.indexOf(':');

                
    if (index < 0)
                    
    throw new IOException("malformed header field");

                key 
    = line.substring(0, index);

                
    if (key.length() == 0)
                    
    throw new IOException("malformed header field");

                
    if (line.length() <= index + 2) {
                    value 
    = "";
                } 
    else {
                    value 
    = line.substring(index + 2);
                }

                headerFields.put(toLowerCase(key), value);
            }
        }

        
    public String getResponseHeaders() {
            Set
    <String> keys = headerFields.keySet();
            StringBuffer headers 
    = new StringBuffer();
            
    for (String key : keys) {
                String value 
    = headerFields.get(key);
                headers.append(key 
    + ":" + value + "\r\n");
            }
            
    return headers.toString();
        }

        
    public String getHeaderField(String name) {
            
    return (String) headerFields.get(toLowerCase(name));
        }

        
    /** */
        
    /**
         * Reads the next byte of data from the input stream. The value byte is
         * returned as an <code>int</code> in the range <code>0</code> to
         * <code>255</code>. If no byte is available because the end of the
         * stream has been reached, the value <code>-1</code> is returned. This
         * method blocks until input data is available, the end of the stream is
         * detected, or an exception is thrown.
         * 
         * <p>
         * A subclass must provide an implementation of this method.
         * 
         * 
    @return the next byte of data, or <code>-1</code> if the end of the
         *         stream is reached.
         * 
    @exception IOException
         *                if an I/O error occurs.
         
    */
        
    public int read() throws IOException {

            
    // Be consistent about returning EOF once encountered.
            if (eof) {
                
    return -1;
            }

            
    /**//*
                 * If all the current chunk has been read and this is a chunked
                 * transfer then read the next chunk length.
                 
    */
            
    if (bytesleft <= 0 && chunked) {
                readCRLF(); 
    // Skip trailing

                bytesleft 
    = readChunkSize();
                
    if (bytesleft == 0) {
                    eof 
    = true;
                    
    return -1;
                }
            }

            
    int ch = is.read();
            eof 
    = (ch == -1);
            bytesleft
    --;
            bytesread
    ++;
            
    return ch;
        }

        
    /** */
        
    /**
         * Reads some number of bytes from the input stream and stores them into the
         * buffer array <code>b</code>. The number of bytes actually read is
         * returned as an integer. This method blocks until input data is available,
         * end of file is detected, or an exception is thrown. (For HTTP requests
         * where the content length has been specified in the response headers, the
         * size of the read may be reduced if there are fewer bytes left than the
         * size of the supplied input buffer.)
         * 
         * 
    @param b
         *            the buffer into which the data is read.
         * 
    @return the total number of bytes read into the buffer, or
         *         <code>-1</code> is there is no more data because the end of the
         *         stream has been reached.
         * 
    @exception IOException
         *                if an I/O error occurs.
         * 
    @see java.io.InputStream#read(byte[])
         
    */
        
    public int read(byte[] b) throws IOException {
            
    long len = getLength();

            
    if (len != -1) {
                
    // More bytes are expected
                len -= bytesread;
            } 
    else {
                
    // Buffered reading in chunks
                len = b.length;
            }

            
    if (len == 0) {
                eof 
    = true;
                
    // All expected bytes have been read
                return -1;
            }

            
    return read(b, 0, (int) (len < b.length ? len : b.length));
        }

        
    public int read(byte b[], int off, int len) throws IOException {
            
    if (b == null) {
                
    throw new NullPointerException();
            } 
    else if (off < 0 || len < 0 || len > b.length - off) {
                
    throw new IndexOutOfBoundsException();
            } 
    else if (len == 0) {
                
    return 0;
            }

            
    int c = read();
            
    if (c == -1) {
                
    return -1;
            }
            b[off] 
    = (byte) c;

            
    int i = 1;
            
    try {
                
    for (; i < len; i++) {
                    c 
    = read();
                    
    if (c == -1) {
                        
    break;
                    }
                    b[off 
    + i] = (byte) c;
                }
            } 
    catch (IOException ee) {
            }
            
    return i;
        }

        
    public long getLength() {
            
    return getHeaderFieldInt("content-length"-1);
        }

        
    public int getHeaderFieldInt(String name, int def) {
            
    try {
                
    return Integer.parseInt(getHeaderField(name));
            } 
    catch (Throwable t) {
            }

            
    return def;
        }

        
    /**
         * Returns the number of bytes that can be read (or skipped over) from this
         * input stream without blocking by the next caller of a method for this
         * input stream.
         * 
         * This method simply returns the number of bytes left from a chunked
         * response from an HTTP 1.1 server.
         
    */
        
    public int available() throws IOException {
            
    return bytesleft;
        }

        
    /**//*
             * Read <cr><lf> from the InputStream. 
    @exception IOException is thrown
             * if either <CR> or <LF> is missing.
             
    */
        
    private void readCRLF() throws IOException {
            
    int ch;

            ch 
    = is.read();
            
    if (ch != CR) {
                
    throw new IOException("missing CRLF");
            }

            ch 
    = is.read();
            
    if (ch != LF) {
                
    throw new IOException("missing CRLF");
            }
        }

        
    public void close() throws IOException {
            is.close();
        }

        
    private String toLowerCase(String string) {

            
    // Uses the shared stringbuffer to create a lower case string.
            stringbuffer.setLength(0);

            
    for (int i = 0; i < string.length(); i++) {
                stringbuffer.append(Character.toLowerCase(string.charAt(i)));
            }

            
    return stringbuffer.toString();
        }

        
    /**//*
             * Uses the shared stringbuffer to read a line terminated by <cr><lf>
             * and return it as string.
             
    */
        
    private String readLine(InputStream in) {
            
    int c;
            StringBuffer stringbuffer 
    = new StringBuffer();
            stringbuffer.setLength(
    0);

            
    for (;;) {
                
    try {
                    c 
    = in.read();
                    
    if (c < 0) {
                        
    return null;
                    }
                } 
    catch (IOException ioe) {
                    
    return null;
                }

                
    if (isEnd(c)) {
                    
    try {
                        
    // LF
                        in.read();
                    } 
    catch (IOException e) {
                        e.printStackTrace();
                    }
                    
    break;
                }
                stringbuffer.append((
    char) c);

            }

            
    return stringbuffer.toString();
        }

        
    public static boolean isEnd(int ch) {
            
    return ch == CR || ch == LF;
        }

        
    /**//*
             * Read the chunk size from the input. It is a hex length followed by
             * optional headers (ignored) and terminated with <cr><lf>.
             
    */
        
    private int readChunkSize() throws IOException {
            
    int size = -1;
            
    try {
                String chunk 
    = readLine(is);
                
    if (chunk == null) {
                    
    throw new IOException("No Chunk Size");
                }

                
    int i;
                
    for (i = 0; i < chunk.length(); i++) {
                    
    char ch = chunk.charAt(i);
                    
    if (Character.digit(ch, 16== -1)
                        
    break;
                }

                
    /**//* look at extensions?. */
                size 
    = Integer.parseInt(chunk.substring(0, i), 16);

            } 
    catch (NumberFormatException e) {
                
    throw new IOException("Bogus chunk size");
            }

            
    return size;
        }
    }

    posted on 2009-11-05 14:45 單飛 閱讀(372) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 成人a免费α片在线视频网站| 亚洲成AV人综合在线观看| 中文字幕无码视频手机免费看| 人妻免费久久久久久久了| 亚洲天堂2016| 亚洲色大成网站www永久| 日日噜噜噜噜夜夜爽亚洲精品 | 久久精品国产亚洲AV麻豆王友容| 永久免费av无码网站大全| 免费福利视频导航| 免费观看男人吊女人视频| 亚洲精品偷拍视频免费观看| 精品国产亚洲AV麻豆| 亚洲日韩精品国产一区二区三区| 亚洲视频免费在线播放| 亚洲av无码一区二区三区不卡| 亚洲人成人网站在线观看| 国产在线ts人妖免费视频| 女人18毛片免费观看| 免费大片黄在线观看yw| 四虎在线视频免费观看视频| 一级毛片免费播放| 另类免费视频一区二区在线观看| 中文字幕免费播放| 国产高潮久久免费观看| 国产免费黄色无码视频| 一级毛片不卡免费看老司机| 日韩少妇内射免费播放| 免费看又黄又爽又猛的视频软件 | 四虎影视永久免费观看地址| 大学生一级特黄的免费大片视频| 免费无码又黄又爽又刺激| 日本妇人成熟免费中文字幕| 青青草免费在线视频| 特级做A爰片毛片免费69| 成人网站免费观看| 日韩免费视频观看| 免费很黄很色裸乳在线观看| 亚洲午夜福利精品无码| 综合久久久久久中文字幕亚洲国产国产综合一区首 | a级午夜毛片免费一区二区|