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

📄 fcgiinputstream.java

📁 FastCGI,语言无关的、可伸缩架构的CGI开放扩展
💻 JAVA
字号:
/* * @(#)FCGIInputStream.java * *      FastCGi compatibility package Interface * * *  Copyright (c) 1996 Open Market, Inc. * * See the file "LICENSE.TERMS" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * $Id: FCGIInputStream.java,v 1.4 2000/03/21 12:12:25 robs Exp $ */package com.fastcgi;import java.io.*;/** * This stream manages buffered reads of FCGI messages. */public class FCGIInputStream extends InputStream{    private static final String RCSID = "$Id: FCGIInputStream.java,v 1.4 2000/03/21 12:12:25 robs Exp $";    /* Stream vars */    public int rdNext;    public int stop;    public boolean isClosed;    /* require methods to set, get and clear */    private int errno;    private Exception errex;    /* data vars */    public byte buff[];    public int buffLen;    public int buffStop;    public int type;    public int contentLen;    public int paddingLen;    public boolean skip;    public boolean eorStop;    public FCGIRequest request;    public InputStream in;    /**    * Creates a new input stream to manage fcgi prototcol stuff    * @param in the input stream  bufLen  length of buffer streamType    */    public FCGIInputStream(FileInputStream inStream, int bufLen,        int streamType,        FCGIRequest inReq) {        in = inStream;        buffLen = Math.min(bufLen,FCGIGlobalDefs.def_FCGIMaxLen);        buff = new byte[buffLen];        type = streamType;        stop = rdNext = buffStop = 0;        isClosed = false;        contentLen = 0;        paddingLen = 0;        skip = false;        eorStop = false;        request = inReq;    }    /**    * Reads a byte of data. This method will block if no input is    * available.    * @return  the byte read, or -1 if the end of the    *      stream is reached.    * @exception IOException If an I/O error has occurred.    */    public int read() throws IOException {        if (rdNext != stop) {            return buff[rdNext++] & 0xff;        }        if (isClosed){            return -1;        }        fill();        if (rdNext != stop){            return buff[rdNext++] & 0xff;        }        return -1;    }    /**    * Reads into an array of bytes.  This method will    * block until some input is available.    * @param b the buffer into which the data is read    * @return  the actual number of bytes read, -1 is    *      returned when the end of the stream is reached.    * @exception IOException If an I/O error has occurred.    */    public int read(byte b[]) throws IOException {        return read(b, 0, b.length);    }    /**    * Reads into an array of bytes.    * Blocks until some input is available.    * @param b the buffer into which the data is read    * @param off the start offset of the data    * @param len the maximum number of bytes read    * @return  the actual number of bytes read, -1 is    *      returned when the end of the stream is reached.    * @exception IOException If an I/O error has occurred.    */    public int read(byte b[], int off, int len) throws IOException {        int m, bytesMoved;        if (len <= 0){            return 0;        }        /*        *Fast path: len bytes already available.        */        if (len <= stop - rdNext){            System.arraycopy(buff, rdNext, b, off, len);            rdNext += len;            return len;        }        /*        *General case: stream is closed or fill needs to be called        */        bytesMoved = 0;        for(;;){            if (rdNext != stop){                m = Math.min(len - bytesMoved, stop - rdNext);                System.arraycopy(buff, rdNext, b, off, m);                bytesMoved += m;                rdNext += m;                if (bytesMoved == len)                    return bytesMoved;                off += m;            }            if (isClosed){                return bytesMoved;            }            fill();        }    }    /**    * Reads into an array of bytes.  This method will    * block until some input is available.    * @param b the buffer into which the data is read    * @param off the start offset of the data    * @param len the maximum number of bytes read    * @return  the actual number of bytes read, -1 is    *      returned when the end of the stream is reached.    * @exception IOException If an I/O error has occurred.    */    public void  fill() throws IOException {        byte[] headerBuf = new byte[FCGIGlobalDefs.def_FCGIHeaderLen];        int headerLen = 0;        int status = 0;        int count = 0;        for(;;) {            /*            * If buffer is empty, do a read            */            if (rdNext == buffStop) {                try {                    count = in.read(buff, 0, buffLen);                } catch (IOException e) {                    setException(e);                    return;                }                if (count == 0) {                    setFCGIError(FCGIGlobalDefs.def_FCGIProtocolError);                    return;                }                rdNext = 0;                buffStop = count;       // 1 more than we read            }            /* Now buf is not empty: If the current record contains more content             * bytes, deliver all that are present in buff to callers buffer             * unless he asked for less than we have, in which case give him less             */            if (contentLen > 0) {                count = Math.min(contentLen, buffStop - rdNext);                contentLen -= count;                if (!skip) {                    stop = rdNext + count;                    return;                }                else {                    rdNext += count;                    if (contentLen > 0) {                        continue;                    }                    else {                        skip = false;                    }                }            }            /* Content has been consumed by client.             * If record was padded, skip over padding             */            if (paddingLen > 0) {                count = Math.min(paddingLen, buffStop - rdNext);                paddingLen -= count;                rdNext += count;                if (paddingLen > 0) {                    continue;    // more padding to read                }            }            /* All done with current record, including the padding.             * If we are in a recursive call from Process Header, deliver EOF             */            if (eorStop){                stop = rdNext;                isClosed = true;                return;            }            /*             * Fill header with bytes from input buffer - get the whole header.             */            count = Math.min(headerBuf.length - headerLen, buffStop - rdNext);            System.arraycopy(buff,rdNext, headerBuf, headerLen, count);            headerLen += count;            rdNext  += count;            if (headerLen < headerBuf.length) {                continue;            }            headerLen = 0;            /*             * Interperet the header. eorStop prevents ProcessHeader from             * reading past the end of record when using stream to read content             */            eorStop = true;            stop = rdNext;            status = 0;            status = new FCGIMessage(this).processHeader(headerBuf);            eorStop = false;            isClosed = false;            switch (status){            case FCGIGlobalDefs.def_FCGIStreamRecord:                if (contentLen == 0) {                    stop = rdNext;                    isClosed = true;                    return;                }                break;            case FCGIGlobalDefs.def_FCGISkip:                skip = true;                break;            case FCGIGlobalDefs.def_FCGIBeginRecord:                /*                * If this header marked the beginning of a new                * request, return role info to caller                */                return;            case FCGIGlobalDefs.def_FCGIMgmtRecord:                break;            default:                /*                * ASSERT                */                setFCGIError(status);                return;            }        }    }    /**     * Skips n bytes of input.     * @param n the number of bytes to be skipped     * @return  the actual number of bytes skipped.     * @exception IOException If an I/O error has occurred.     */    public long skip(long n) throws IOException {        byte data[] = new byte[(int)n];        return in.read(data);    }    /*     * An FCGI error has occurred. Save the error code in the stream     * for diagnostic purposes and set the stream state so that     * reads return EOF     */    public void setFCGIError(int errnum) {        /*        * Preserve only the first error.        */        if(errno == 0) {            errno = errnum;        }        isClosed = true;    }    /*    * An Exception has occurred. Save the Exception in the stream    * for diagnostic purposes and set the stream state so that    * reads return EOF    */    public void setException(Exception errexpt) {        /*        * Preserve only the first error.        */        if(errex == null) {            errex = errexpt;        }        isClosed = true;    }    /*    * Clear the stream error code and end-of-file indication.    */    public void clearFCGIError() {        errno = 0;        /*        * isClosed = false;        * XXX: should clear isClosed but work is needed to make it safe        * to do so.        */    }    /*    * Clear the stream error code and end-of-file indication.    */    public void clearException() {        errex = null;        /*        * isClosed = false;        * XXX: should clear isClosed but work is needed to make it safe        * to do so.        */    }    /*    * accessor method since var is private    */    public int getFCGIError() {        return errno;    }    /*    * accessor method since var is private    */    public Exception getException() {        return errex;    }    /*    * Re-initializes the stream to read data of the specified type.    */    public void setReaderType(int streamType) {        type = streamType;        eorStop = false;        skip = false;        contentLen = 0;        paddingLen = 0;        stop = rdNext;        isClosed = false;    }    /*    * Close the stream. This method does not really exist for BufferedInputStream in java,    * but is implemented here for compatibility with the FCGI structures being used. It    * doent really throw any IOExceptions either, but that's there for compatiblity with    * the InputStreamInterface.    */    public void close() throws IOException{        isClosed = true;        stop = rdNext;    }    /*    * Returns the number of bytes that can be read without blocking.    */    public int available() throws IOException {        return stop - rdNext + in.available();    }}

⌨️ 快捷键说明

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