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

📄 httpparser.java

📁 jetty SERVER連接資料庫用的軟體
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
// ========================================================================// Copyright 2004-2006 Mort Bay Consulting Pty. Ltd.// ------------------------------------------------------------------------// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// ========================================================================package org.mortbay.jetty;import java.io.IOException;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletResponse;import org.mortbay.io.Buffer;import org.mortbay.io.BufferUtil;import org.mortbay.io.Buffers;import org.mortbay.io.ByteArrayBuffer;import org.mortbay.io.EndPoint;import org.mortbay.io.View;import org.mortbay.io.BufferCache.CachedBuffer;import org.mortbay.log.Log;/* ------------------------------------------------------------------------------- *//** * @author gregw */public class HttpParser implements Parser{    // States    public static final int STATE_START=-13;    public static final int STATE_FIELD0=-12;    public static final int STATE_SPACE1=-11;    public static final int STATE_FIELD1=-10;    public static final int STATE_SPACE2=-9;    public static final int STATE_END0=-8;    public static final int STATE_END1=-7;    public static final int STATE_FIELD2=-6;    public static final int STATE_HEADER=-5;    public static final int STATE_HEADER_NAME=-4;    public static final int STATE_HEADER_IN_NAME=-3;    public static final int STATE_HEADER_VALUE=-2;    public static final int STATE_HEADER_IN_VALUE=-1;    public static final int STATE_END=0;    public static final int STATE_EOF_CONTENT=1;    public static final int STATE_CONTENT=2;    public static final int STATE_CHUNKED_CONTENT=3;    public static final int STATE_CHUNK_SIZE=4;    public static final int STATE_CHUNK_PARAMS=5;    public static final int STATE_CHUNK=6;    private Buffers _buffers; // source of buffers    private EndPoint _endp;    private Buffer _header; // Buffer for header data (and small _content)    private Buffer _body; // Buffer for large content    private Buffer _buffer; // The current buffer in use (either _header or _content)    private View _contentView=new View(); // View of the content in the buffer for {@link Input}    private int _headerBufferSize;    private int _contentBufferSize;    private EventHandler _handler;    private CachedBuffer _cached;    private View.CaseInsensitive _tok0; // Saved token: header name, request method or response version    private View.CaseInsensitive _tok1; // Saved token: header value, request URI or response code    private String _multiLineValue;    private int _responseStatus; // If >0 then we are parsing a response    private boolean _forceContentBuffer;    private Input _input;        /* ------------------------------------------------------------------------------- */    protected int _state=STATE_START;    protected byte _eol;    protected int _length;    protected long _contentLength;    protected long _contentPosition;    protected int _chunkLength;    protected int _chunkPosition;        /* ------------------------------------------------------------------------------- */    /**     * Constructor.     */    public HttpParser(Buffer buffer, EventHandler handler)    {        this._header=buffer;        this._buffer=buffer;        this._handler=handler;        if (buffer != null)        {            _tok0=new View.CaseInsensitive(buffer);            _tok1=new View.CaseInsensitive(buffer);            _tok0.setPutIndex(_tok0.getIndex());            _tok1.setPutIndex(_tok1.getIndex());        }    }    /* ------------------------------------------------------------------------------- */    /**     * Constructor.     * @param headerBufferSize size in bytes of header buffer       * @param contentBufferSize size in bytes of content buffer     */    public HttpParser(Buffers buffers, EndPoint endp, EventHandler handler, int headerBufferSize, int contentBufferSize)    {        _buffers=buffers;        _endp=endp;        _handler=handler;        _headerBufferSize=headerBufferSize;        _contentBufferSize=contentBufferSize;    }    /* ------------------------------------------------------------------------------- */    public long getContentLength()    {        return _contentLength;    }        public long getContentRead()    {        return _contentPosition;    }    /* ------------------------------------------------------------------------------- */    public int getState()    {        return _state;    }    /* ------------------------------------------------------------------------------- */    public boolean inContentState()    {        return _state > 0;    }    /* ------------------------------------------------------------------------------- */    public boolean inHeaderState()    {        return _state < 0;    }    /* ------------------------------------------------------------------------------- */    public boolean isChunking()    {        return _contentLength==HttpTokens.CHUNKED_CONTENT;    }    /* ------------------------------------------------------------ */    public boolean isIdle()    {        return isState(STATE_START);    }    /* ------------------------------------------------------------ */    public boolean isComplete()    {        return isState(STATE_END);    }        /* ------------------------------------------------------------ */    public boolean isMoreInBuffer()    throws IOException    {        if ( _header!=null && _header.hasContent() ||             _body!=null && _body.hasContent())            return true;        return false;    }    /* ------------------------------------------------------------------------------- */    public boolean isState(int state)    {        return _state == state;    }    /* ------------------------------------------------------------------------------- */    /**     * Parse until {@link #STATE_END END} state.     * If the parser is already in the END state, then it is {@link #reset reset} and re-parsed.     * @throws IllegalStateException If the buffers have already been partially parsed.     */    public void parse() throws IOException    {        if (_state==STATE_END)            reset(false);        if (_state!=STATE_START)            throw new IllegalStateException("!START");        // continue parsing        while (_state != STATE_END)            parseNext();    }        /* ------------------------------------------------------------------------------- */    /**     * Parse until END state.     * This method will parse any remaining content in the current buffer. It does not care about the      * {@link #getState current state} of the parser.     * @see #parse     * @see #parseNext     */    public long parseAvailable() throws IOException    {        long len = parseNext();        long total=len>0?len:0;                // continue parsing        while (!isComplete() && _buffer!=null && _buffer.length()>0)        {            len = parseNext();            if (len>0)                total+=len;        }        return total;    }        /* ------------------------------------------------------------------------------- */    /**     * Parse until next Event.     * @returns number of bytes filled from endpoint or -1 if fill never called.     */    public long parseNext() throws IOException    {        long total_filled=-1;        if (_state == STATE_END)             return -1;                if (_buffer==null)        {            if (_header == null)            {                _header=_buffers.getBuffer(_headerBufferSize);            }            _buffer=_header;            _tok0=new View.CaseInsensitive(_header);            _tok1=new View.CaseInsensitive(_header);            _tok0.setPutIndex(_tok0.getIndex());            _tok1.setPutIndex(_tok1.getIndex());        }                        if (_state == STATE_CONTENT && _contentPosition == _contentLength)        {            _state=STATE_END;            _handler.messageComplete(_contentPosition);            return total_filled;        }                int length=_buffer.length();                // Fill buffer if we can        if (length == 0)        {            int filled=-1;            if (_body!=null && _buffer!=_body)            {                _buffer=_body;                filled=_buffer.length();            }                            if (_buffer.markIndex() == 0 && _buffer.putIndex() == _buffer.capacity())                    throw new HttpException(HttpStatus.ORDINAL_413_Request_Entity_Too_Large, "FULL");                        IOException ioex=null;                        if (_endp != null && filled<=0)            {                // Compress buffer if handling _content buffer                // TODO check this is not moving data too much                if (_buffer == _body)                     _buffer.compact();                if (_buffer.space() == 0)                     throw new HttpException(HttpStatus.ORDINAL_413_Request_Entity_Too_Large, "FULL "+(_buffer==_body?"body":"head"));                                try                {                    if (total_filled<0)                        total_filled=0;                    filled=_endp.fill(_buffer);                    if (filled>0)                        total_filled+=filled;                }                catch(IOException e)                {                    Log.debug(e);                    ioex=e;                    filled=-1;                }            }            if (filled < 0)             {                if ( _state == STATE_EOF_CONTENT)                {                    if (_buffer.length()>0)                    {                        // TODO should we do this here or fall down to main loop?                        Buffer chunk=_buffer.get(_buffer.length());                        _contentPosition += chunk.length();                        _contentView.update(chunk);                        _handler.content(chunk); // May recurse here                     }                    _state=STATE_END;                    _handler.messageComplete(_contentPosition);                    return total_filled;                }                reset(true);                throw new EofException(ioex);            }            length=_buffer.length();        }                // EventHandler header        byte ch;        byte[] array=_buffer.array();                while (_state<STATE_END && length-->0)        {            ch=_buffer.get();                        if (_eol == HttpTokens.CARRIAGE_RETURN && ch == HttpTokens.LINE_FEED)            {                _eol=HttpTokens.LINE_FEED;                continue;            }            _eol=0;                        switch (_state)            {                case STATE_START:                    _contentLength=HttpTokens.UNKNOWN_CONTENT;                    _cached=null;                    if (ch > HttpTokens.SPACE || ch<0)                    {                        _buffer.mark();                        _state=STATE_FIELD0;                    }                    break;                case STATE_FIELD0:                    if (ch == HttpTokens.SPACE)                    {                        _tok0.update(_buffer.markIndex(), _buffer.getIndex() - 1);                        _state=STATE_SPACE1;                        continue;                    }                    else if (ch < HttpTokens.SPACE && ch>=0)                    {                        throw new HttpException(HttpServletResponse.SC_BAD_REQUEST);                    }                    break;                case STATE_SPACE1:                    if (ch > HttpTokens.SPACE || ch<0)                    {                        _buffer.mark();                        _state=STATE_FIELD1;                    }                    else if (ch < HttpTokens.SPACE)                    {                        throw new HttpException(HttpServletResponse.SC_BAD_REQUEST);                    }                    break;                case STATE_FIELD1:                    if (ch == HttpTokens.SPACE)                    {                        _tok1.update(_buffer.markIndex(), _buffer.getIndex() - 1);                        _state=STATE_SPACE2;                        continue;                    }                    else if (ch < HttpTokens.SPACE && ch>=0)                    {                        // HTTP/0.9                        _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _buffer                                .sliceFromMark(), null);                        _state=STATE_END;                        _handler.headerComplete();                        _handler.messageComplete(_contentPosition);                        return total_filled;                    }                    break;                case STATE_SPACE2:

⌨️ 快捷键说明

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