103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.http; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2203928aee4356845252ac6b662d5c72c29903813eJake Slack 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Buffer; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.BufferCache.CachedBuffer; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.BufferUtil; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Buffers; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.ByteArrayBuffer; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.EndPoint; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.EofException; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.View; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.bio.StreamEndPoint; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.StringUtil; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 3503928aee4356845252ac6b662d5c72c29903813eJake Slack 3603928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class HttpParser implements Parser 3703928aee4356845252ac6b662d5c72c29903813eJake Slack{ 3803928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(HttpParser.class); 3903928aee4356845252ac6b662d5c72c29903813eJake Slack 4003928aee4356845252ac6b662d5c72c29903813eJake Slack // States 4103928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_START=-14; 4203928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_FIELD0=-13; 4303928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_SPACE1=-12; 4403928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_STATUS=-11; 4503928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_URI=-10; 4603928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_SPACE2=-9; 4703928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_END0=-8; 4803928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_END1=-7; 4903928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_FIELD2=-6; 5003928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_HEADER=-5; 5103928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_HEADER_NAME=-4; 5203928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_HEADER_IN_NAME=-3; 5303928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_HEADER_VALUE=-2; 5403928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_HEADER_IN_VALUE=-1; 5503928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_END=0; 5603928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_EOF_CONTENT=1; 5703928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_CONTENT=2; 5803928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_CHUNKED_CONTENT=3; 5903928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_CHUNK_SIZE=4; 6003928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_CHUNK_PARAMS=5; 6103928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_CHUNK=6; 6203928aee4356845252ac6b662d5c72c29903813eJake Slack public static final int STATE_SEEKING_EOF=7; 6303928aee4356845252ac6b662d5c72c29903813eJake Slack 6403928aee4356845252ac6b662d5c72c29903813eJake Slack private final EventHandler _handler; 6503928aee4356845252ac6b662d5c72c29903813eJake Slack private final Buffers _buffers; // source of buffers 6603928aee4356845252ac6b662d5c72c29903813eJake Slack private final EndPoint _endp; 6703928aee4356845252ac6b662d5c72c29903813eJake Slack private Buffer _header; // Buffer for header data (and small _content) 6803928aee4356845252ac6b662d5c72c29903813eJake Slack private Buffer _body; // Buffer for large content 6903928aee4356845252ac6b662d5c72c29903813eJake Slack private Buffer _buffer; // The current buffer in use (either _header or _content) 7003928aee4356845252ac6b662d5c72c29903813eJake Slack private CachedBuffer _cached; 7103928aee4356845252ac6b662d5c72c29903813eJake Slack private final View.CaseInsensitive _tok0; // Saved token: header name, request method or response version 7203928aee4356845252ac6b662d5c72c29903813eJake Slack private final View.CaseInsensitive _tok1; // Saved token: header value, request URI or response code 7303928aee4356845252ac6b662d5c72c29903813eJake Slack private String _multiLineValue; 7403928aee4356845252ac6b662d5c72c29903813eJake Slack private int _responseStatus; // If >0 then we are parsing a response 7503928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean _forceContentBuffer; 7603928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean _persistent; 7703928aee4356845252ac6b662d5c72c29903813eJake Slack 7803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 7903928aee4356845252ac6b662d5c72c29903813eJake Slack protected final View _contentView=new View(); // View of the content in the buffer for {@link Input} 8003928aee4356845252ac6b662d5c72c29903813eJake Slack protected int _state=STATE_START; 8103928aee4356845252ac6b662d5c72c29903813eJake Slack protected byte _eol; 8203928aee4356845252ac6b662d5c72c29903813eJake Slack protected int _length; 8303928aee4356845252ac6b662d5c72c29903813eJake Slack protected long _contentLength; 8403928aee4356845252ac6b662d5c72c29903813eJake Slack protected long _contentPosition; 8503928aee4356845252ac6b662d5c72c29903813eJake Slack protected int _chunkLength; 8603928aee4356845252ac6b662d5c72c29903813eJake Slack protected int _chunkPosition; 8703928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean _headResponse; 8803928aee4356845252ac6b662d5c72c29903813eJake Slack 8903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 9003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 9103928aee4356845252ac6b662d5c72c29903813eJake Slack * Constructor. 9203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 9303928aee4356845252ac6b662d5c72c29903813eJake Slack public HttpParser(Buffer buffer, EventHandler handler) 9403928aee4356845252ac6b662d5c72c29903813eJake Slack { 9503928aee4356845252ac6b662d5c72c29903813eJake Slack _endp=null; 9603928aee4356845252ac6b662d5c72c29903813eJake Slack _buffers=null; 9703928aee4356845252ac6b662d5c72c29903813eJake Slack _header=buffer; 9803928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=buffer; 9903928aee4356845252ac6b662d5c72c29903813eJake Slack _handler=handler; 10003928aee4356845252ac6b662d5c72c29903813eJake Slack 10103928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0=new View.CaseInsensitive(_header); 10203928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1=new View.CaseInsensitive(_header); 10303928aee4356845252ac6b662d5c72c29903813eJake Slack } 10403928aee4356845252ac6b662d5c72c29903813eJake Slack 10503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 10603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 10703928aee4356845252ac6b662d5c72c29903813eJake Slack * Constructor. 10803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param buffers the buffers to use 10903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param endp the endpoint 11003928aee4356845252ac6b662d5c72c29903813eJake Slack * @param handler the even handler 11103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 11203928aee4356845252ac6b662d5c72c29903813eJake Slack public HttpParser(Buffers buffers, EndPoint endp, EventHandler handler) 11303928aee4356845252ac6b662d5c72c29903813eJake Slack { 11403928aee4356845252ac6b662d5c72c29903813eJake Slack _buffers=buffers; 11503928aee4356845252ac6b662d5c72c29903813eJake Slack _endp=endp; 11603928aee4356845252ac6b662d5c72c29903813eJake Slack _handler=handler; 11703928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0=new View.CaseInsensitive(); 11803928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1=new View.CaseInsensitive(); 11903928aee4356845252ac6b662d5c72c29903813eJake Slack } 12003928aee4356845252ac6b662d5c72c29903813eJake Slack 12103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 12203928aee4356845252ac6b662d5c72c29903813eJake Slack public long getContentLength() 12303928aee4356845252ac6b662d5c72c29903813eJake Slack { 12403928aee4356845252ac6b662d5c72c29903813eJake Slack return _contentLength; 12503928aee4356845252ac6b662d5c72c29903813eJake Slack } 12603928aee4356845252ac6b662d5c72c29903813eJake Slack 12703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 12803928aee4356845252ac6b662d5c72c29903813eJake Slack public long getContentRead() 12903928aee4356845252ac6b662d5c72c29903813eJake Slack { 13003928aee4356845252ac6b662d5c72c29903813eJake Slack return _contentPosition; 13103928aee4356845252ac6b662d5c72c29903813eJake Slack } 13203928aee4356845252ac6b662d5c72c29903813eJake Slack 13303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 13403928aee4356845252ac6b662d5c72c29903813eJake Slack /** Set if a HEAD response is expected 13503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param head 13603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 13703928aee4356845252ac6b662d5c72c29903813eJake Slack public void setHeadResponse(boolean head) 13803928aee4356845252ac6b662d5c72c29903813eJake Slack { 13903928aee4356845252ac6b662d5c72c29903813eJake Slack _headResponse=head; 14003928aee4356845252ac6b662d5c72c29903813eJake Slack } 14103928aee4356845252ac6b662d5c72c29903813eJake Slack 14203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 14303928aee4356845252ac6b662d5c72c29903813eJake Slack public int getState() 14403928aee4356845252ac6b662d5c72c29903813eJake Slack { 14503928aee4356845252ac6b662d5c72c29903813eJake Slack return _state; 14603928aee4356845252ac6b662d5c72c29903813eJake Slack } 14703928aee4356845252ac6b662d5c72c29903813eJake Slack 14803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 14903928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean inContentState() 15003928aee4356845252ac6b662d5c72c29903813eJake Slack { 15103928aee4356845252ac6b662d5c72c29903813eJake Slack return _state > 0; 15203928aee4356845252ac6b662d5c72c29903813eJake Slack } 15303928aee4356845252ac6b662d5c72c29903813eJake Slack 15403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 15503928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean inHeaderState() 15603928aee4356845252ac6b662d5c72c29903813eJake Slack { 15703928aee4356845252ac6b662d5c72c29903813eJake Slack return _state < 0; 15803928aee4356845252ac6b662d5c72c29903813eJake Slack } 15903928aee4356845252ac6b662d5c72c29903813eJake Slack 16003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 16103928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isChunking() 16203928aee4356845252ac6b662d5c72c29903813eJake Slack { 16303928aee4356845252ac6b662d5c72c29903813eJake Slack return _contentLength==HttpTokens.CHUNKED_CONTENT; 16403928aee4356845252ac6b662d5c72c29903813eJake Slack } 16503928aee4356845252ac6b662d5c72c29903813eJake Slack 16603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 16703928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isIdle() 16803928aee4356845252ac6b662d5c72c29903813eJake Slack { 16903928aee4356845252ac6b662d5c72c29903813eJake Slack return isState(STATE_START); 17003928aee4356845252ac6b662d5c72c29903813eJake Slack } 17103928aee4356845252ac6b662d5c72c29903813eJake Slack 17203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 17303928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isComplete() 17403928aee4356845252ac6b662d5c72c29903813eJake Slack { 17503928aee4356845252ac6b662d5c72c29903813eJake Slack return isState(STATE_END); 17603928aee4356845252ac6b662d5c72c29903813eJake Slack } 17703928aee4356845252ac6b662d5c72c29903813eJake Slack 17803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 17903928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isMoreInBuffer() 18003928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException 18103928aee4356845252ac6b662d5c72c29903813eJake Slack { 18203928aee4356845252ac6b662d5c72c29903813eJake Slack return ( _header!=null && _header.hasContent() || 18303928aee4356845252ac6b662d5c72c29903813eJake Slack _body!=null && _body.hasContent()); 18403928aee4356845252ac6b662d5c72c29903813eJake Slack } 18503928aee4356845252ac6b662d5c72c29903813eJake Slack 18603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 18703928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isState(int state) 18803928aee4356845252ac6b662d5c72c29903813eJake Slack { 18903928aee4356845252ac6b662d5c72c29903813eJake Slack return _state == state; 19003928aee4356845252ac6b662d5c72c29903813eJake Slack } 19103928aee4356845252ac6b662d5c72c29903813eJake Slack 19203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 19303928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isPersistent() 19403928aee4356845252ac6b662d5c72c29903813eJake Slack { 19503928aee4356845252ac6b662d5c72c29903813eJake Slack return _persistent; 19603928aee4356845252ac6b662d5c72c29903813eJake Slack } 19703928aee4356845252ac6b662d5c72c29903813eJake Slack 19803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 19903928aee4356845252ac6b662d5c72c29903813eJake Slack public void setPersistent(boolean persistent) 20003928aee4356845252ac6b662d5c72c29903813eJake Slack { 20103928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent = persistent; 20203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_persistent &&(_state==STATE_END || _state==STATE_START)) 20303928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_SEEKING_EOF; 20403928aee4356845252ac6b662d5c72c29903813eJake Slack } 20503928aee4356845252ac6b662d5c72c29903813eJake Slack 20603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 20703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 20803928aee4356845252ac6b662d5c72c29903813eJake Slack * Parse until {@link #STATE_END END} state. 20903928aee4356845252ac6b662d5c72c29903813eJake Slack * If the parser is already in the END state, then it is {@link #reset reset} and re-parsed. 21003928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws IllegalStateException If the buffers have already been partially parsed. 21103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 21203928aee4356845252ac6b662d5c72c29903813eJake Slack public void parse() throws IOException 21303928aee4356845252ac6b662d5c72c29903813eJake Slack { 21403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state==STATE_END) 21503928aee4356845252ac6b662d5c72c29903813eJake Slack reset(); 21603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state!=STATE_START) 21703928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("!START"); 21803928aee4356845252ac6b662d5c72c29903813eJake Slack 21903928aee4356845252ac6b662d5c72c29903813eJake Slack // continue parsing 22003928aee4356845252ac6b662d5c72c29903813eJake Slack while (_state != STATE_END) 22103928aee4356845252ac6b662d5c72c29903813eJake Slack if (parseNext()<0) 22203928aee4356845252ac6b662d5c72c29903813eJake Slack return; 22303928aee4356845252ac6b662d5c72c29903813eJake Slack } 22403928aee4356845252ac6b662d5c72c29903813eJake Slack 22503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 22603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 22703928aee4356845252ac6b662d5c72c29903813eJake Slack * Parse until END state. 22803928aee4356845252ac6b662d5c72c29903813eJake Slack * This method will parse any remaining content in the current buffer as long as there is 22903928aee4356845252ac6b662d5c72c29903813eJake Slack * no unconsumed content. It does not care about the {@link #getState current state} of the parser. 23003928aee4356845252ac6b662d5c72c29903813eJake Slack * @see #parse 23103928aee4356845252ac6b662d5c72c29903813eJake Slack * @see #parseNext 23203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 23303928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean parseAvailable() throws IOException 23403928aee4356845252ac6b662d5c72c29903813eJake Slack { 23503928aee4356845252ac6b662d5c72c29903813eJake Slack boolean progress=parseNext()>0; 23603928aee4356845252ac6b662d5c72c29903813eJake Slack 23703928aee4356845252ac6b662d5c72c29903813eJake Slack // continue parsing 23803928aee4356845252ac6b662d5c72c29903813eJake Slack while (!isComplete() && _buffer!=null && _buffer.length()>0 && !_contentView.hasContent()) 23903928aee4356845252ac6b662d5c72c29903813eJake Slack { 24003928aee4356845252ac6b662d5c72c29903813eJake Slack progress |= parseNext()>0; 24103928aee4356845252ac6b662d5c72c29903813eJake Slack } 24203928aee4356845252ac6b662d5c72c29903813eJake Slack return progress; 24303928aee4356845252ac6b662d5c72c29903813eJake Slack } 24403928aee4356845252ac6b662d5c72c29903813eJake Slack 24503928aee4356845252ac6b662d5c72c29903813eJake Slack 24603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 24703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 24803928aee4356845252ac6b662d5c72c29903813eJake Slack * Parse until next Event. 24903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return an indication of progress <0 EOF, 0 no progress, >0 progress. 25003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 25103928aee4356845252ac6b662d5c72c29903813eJake Slack public int parseNext() throws IOException 25203928aee4356845252ac6b662d5c72c29903813eJake Slack { 25303928aee4356845252ac6b662d5c72c29903813eJake Slack try 25403928aee4356845252ac6b662d5c72c29903813eJake Slack { 25503928aee4356845252ac6b662d5c72c29903813eJake Slack int progress=0; 25603928aee4356845252ac6b662d5c72c29903813eJake Slack 25703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state == STATE_END) 25803928aee4356845252ac6b662d5c72c29903813eJake Slack return 0; 25903928aee4356845252ac6b662d5c72c29903813eJake Slack 26003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer==null) 26103928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=getHeaderBuffer(); 26203928aee4356845252ac6b662d5c72c29903813eJake Slack 26303928aee4356845252ac6b662d5c72c29903813eJake Slack 26403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state == STATE_CONTENT && _contentPosition == _contentLength) 26503928aee4356845252ac6b662d5c72c29903813eJake Slack { 26603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_END; 26703928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 26803928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 26903928aee4356845252ac6b662d5c72c29903813eJake Slack } 27003928aee4356845252ac6b662d5c72c29903813eJake Slack 27103928aee4356845252ac6b662d5c72c29903813eJake Slack int length=_buffer.length(); 27203928aee4356845252ac6b662d5c72c29903813eJake Slack 27303928aee4356845252ac6b662d5c72c29903813eJake Slack // Fill buffer if we can 27403928aee4356845252ac6b662d5c72c29903813eJake Slack if (length == 0) 27503928aee4356845252ac6b662d5c72c29903813eJake Slack { 27603928aee4356845252ac6b662d5c72c29903813eJake Slack int filled=-1; 27703928aee4356845252ac6b662d5c72c29903813eJake Slack IOException ex=null; 27803928aee4356845252ac6b662d5c72c29903813eJake Slack try 27903928aee4356845252ac6b662d5c72c29903813eJake Slack { 28003928aee4356845252ac6b662d5c72c29903813eJake Slack filled=fill(); 28103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("filled {}/{}",filled,_buffer.length()); 28203928aee4356845252ac6b662d5c72c29903813eJake Slack } 28303928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 28403928aee4356845252ac6b662d5c72c29903813eJake Slack { 28503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(this.toString(),e); 28603928aee4356845252ac6b662d5c72c29903813eJake Slack ex=e; 28703928aee4356845252ac6b662d5c72c29903813eJake Slack } 28803928aee4356845252ac6b662d5c72c29903813eJake Slack 28903928aee4356845252ac6b662d5c72c29903813eJake Slack if (filled > 0 ) 29003928aee4356845252ac6b662d5c72c29903813eJake Slack progress++; 29103928aee4356845252ac6b662d5c72c29903813eJake Slack else if (filled < 0 ) 29203928aee4356845252ac6b662d5c72c29903813eJake Slack { 29303928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=false; 29403928aee4356845252ac6b662d5c72c29903813eJake Slack 29503928aee4356845252ac6b662d5c72c29903813eJake Slack // do we have content to deliver? 29603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state>STATE_END) 29703928aee4356845252ac6b662d5c72c29903813eJake Slack { 29803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer.length()>0 && !_headResponse) 29903928aee4356845252ac6b662d5c72c29903813eJake Slack { 30003928aee4356845252ac6b662d5c72c29903813eJake Slack Buffer chunk=_buffer.get(_buffer.length()); 30103928aee4356845252ac6b662d5c72c29903813eJake Slack _contentPosition += chunk.length(); 30203928aee4356845252ac6b662d5c72c29903813eJake Slack _contentView.update(chunk); 30303928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.content(chunk); // May recurse here 30403928aee4356845252ac6b662d5c72c29903813eJake Slack } 30503928aee4356845252ac6b662d5c72c29903813eJake Slack } 30603928aee4356845252ac6b662d5c72c29903813eJake Slack 30703928aee4356845252ac6b662d5c72c29903813eJake Slack // was this unexpected? 30803928aee4356845252ac6b662d5c72c29903813eJake Slack switch(_state) 30903928aee4356845252ac6b662d5c72c29903813eJake Slack { 31003928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_END: 31103928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_SEEKING_EOF: 31203928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_END; 31303928aee4356845252ac6b662d5c72c29903813eJake Slack break; 31403928aee4356845252ac6b662d5c72c29903813eJake Slack 31503928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_EOF_CONTENT: 31603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_END; 31703928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 31803928aee4356845252ac6b662d5c72c29903813eJake Slack break; 31903928aee4356845252ac6b662d5c72c29903813eJake Slack 32003928aee4356845252ac6b662d5c72c29903813eJake Slack default: 32103928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_END; 32203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_headResponse) 32303928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.earlyEOF(); 32403928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 32503928aee4356845252ac6b662d5c72c29903813eJake Slack } 32603928aee4356845252ac6b662d5c72c29903813eJake Slack 32703928aee4356845252ac6b662d5c72c29903813eJake Slack if (ex!=null) 32803928aee4356845252ac6b662d5c72c29903813eJake Slack throw ex; 32903928aee4356845252ac6b662d5c72c29903813eJake Slack 33003928aee4356845252ac6b662d5c72c29903813eJake Slack if (!isComplete() && !isIdle()) 33103928aee4356845252ac6b662d5c72c29903813eJake Slack throw new EofException(); 33203928aee4356845252ac6b662d5c72c29903813eJake Slack 33303928aee4356845252ac6b662d5c72c29903813eJake Slack return -1; 33403928aee4356845252ac6b662d5c72c29903813eJake Slack } 33503928aee4356845252ac6b662d5c72c29903813eJake Slack length=_buffer.length(); 33603928aee4356845252ac6b662d5c72c29903813eJake Slack } 33703928aee4356845252ac6b662d5c72c29903813eJake Slack 33803928aee4356845252ac6b662d5c72c29903813eJake Slack 33903928aee4356845252ac6b662d5c72c29903813eJake Slack // Handle header states 34003928aee4356845252ac6b662d5c72c29903813eJake Slack byte ch; 34103928aee4356845252ac6b662d5c72c29903813eJake Slack byte[] array=_buffer.array(); 34203928aee4356845252ac6b662d5c72c29903813eJake Slack int last=_state; 34303928aee4356845252ac6b662d5c72c29903813eJake Slack while (_state<STATE_END && length-->0) 34403928aee4356845252ac6b662d5c72c29903813eJake Slack { 34503928aee4356845252ac6b662d5c72c29903813eJake Slack if (last!=_state) 34603928aee4356845252ac6b662d5c72c29903813eJake Slack { 34703928aee4356845252ac6b662d5c72c29903813eJake Slack progress++; 34803928aee4356845252ac6b662d5c72c29903813eJake Slack last=_state; 34903928aee4356845252ac6b662d5c72c29903813eJake Slack } 35003928aee4356845252ac6b662d5c72c29903813eJake Slack 35103928aee4356845252ac6b662d5c72c29903813eJake Slack ch=_buffer.get(); 35203928aee4356845252ac6b662d5c72c29903813eJake Slack 35303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_eol == HttpTokens.CARRIAGE_RETURN) 35403928aee4356845252ac6b662d5c72c29903813eJake Slack { 35503928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.LINE_FEED) 35603928aee4356845252ac6b662d5c72c29903813eJake Slack { 35703928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=HttpTokens.LINE_FEED; 35803928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 35903928aee4356845252ac6b662d5c72c29903813eJake Slack } 36003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new HttpException(HttpStatus.BAD_REQUEST_400); 36103928aee4356845252ac6b662d5c72c29903813eJake Slack } 36203928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=0; 36303928aee4356845252ac6b662d5c72c29903813eJake Slack 36403928aee4356845252ac6b662d5c72c29903813eJake Slack switch (_state) 36503928aee4356845252ac6b662d5c72c29903813eJake Slack { 36603928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_START: 36703928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.UNKNOWN_CONTENT; 36803928aee4356845252ac6b662d5c72c29903813eJake Slack _cached=null; 36903928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch > HttpTokens.SPACE || ch<0) 37003928aee4356845252ac6b662d5c72c29903813eJake Slack { 37103928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.mark(); 37203928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_FIELD0; 37303928aee4356845252ac6b662d5c72c29903813eJake Slack } 37403928aee4356845252ac6b662d5c72c29903813eJake Slack break; 37503928aee4356845252ac6b662d5c72c29903813eJake Slack 37603928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_FIELD0: 37703928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.SPACE) 37803928aee4356845252ac6b662d5c72c29903813eJake Slack { 37903928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.update(_buffer.markIndex(), _buffer.getIndex() - 1); 38003928aee4356845252ac6b662d5c72c29903813eJake Slack _responseStatus=HttpVersions.CACHE.get(_tok0)==null?-1:0; 38103928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_SPACE1; 38203928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 38303928aee4356845252ac6b662d5c72c29903813eJake Slack } 38403928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch < HttpTokens.SPACE && ch>=0) 38503928aee4356845252ac6b662d5c72c29903813eJake Slack { 38603928aee4356845252ac6b662d5c72c29903813eJake Slack throw new HttpException(HttpStatus.BAD_REQUEST_400); 38703928aee4356845252ac6b662d5c72c29903813eJake Slack } 38803928aee4356845252ac6b662d5c72c29903813eJake Slack break; 38903928aee4356845252ac6b662d5c72c29903813eJake Slack 39003928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_SPACE1: 39103928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch > HttpTokens.SPACE || ch<0) 39203928aee4356845252ac6b662d5c72c29903813eJake Slack { 39303928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.mark(); 39403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_responseStatus>=0) 39503928aee4356845252ac6b662d5c72c29903813eJake Slack { 39603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_STATUS; 39703928aee4356845252ac6b662d5c72c29903813eJake Slack _responseStatus=ch-'0'; 39803928aee4356845252ac6b662d5c72c29903813eJake Slack } 39903928aee4356845252ac6b662d5c72c29903813eJake Slack else 40003928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_URI; 40103928aee4356845252ac6b662d5c72c29903813eJake Slack } 40203928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch < HttpTokens.SPACE) 40303928aee4356845252ac6b662d5c72c29903813eJake Slack { 40403928aee4356845252ac6b662d5c72c29903813eJake Slack throw new HttpException(HttpStatus.BAD_REQUEST_400); 40503928aee4356845252ac6b662d5c72c29903813eJake Slack } 40603928aee4356845252ac6b662d5c72c29903813eJake Slack break; 40703928aee4356845252ac6b662d5c72c29903813eJake Slack 40803928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_STATUS: 40903928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.SPACE) 41003928aee4356845252ac6b662d5c72c29903813eJake Slack { 41103928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.update(_buffer.markIndex(), _buffer.getIndex() - 1); 41203928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_SPACE2; 41303928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 41403928aee4356845252ac6b662d5c72c29903813eJake Slack } 41503928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch>='0' && ch<='9') 41603928aee4356845252ac6b662d5c72c29903813eJake Slack { 41703928aee4356845252ac6b662d5c72c29903813eJake Slack _responseStatus=_responseStatus*10+(ch-'0'); 41803928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 41903928aee4356845252ac6b662d5c72c29903813eJake Slack } 42003928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch < HttpTokens.SPACE && ch>=0) 42103928aee4356845252ac6b662d5c72c29903813eJake Slack { 42203928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.startResponse(HttpMethods.CACHE.lookup(_tok0), _responseStatus, null); 42303928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 42403928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER; 42503928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.setPutIndex(_tok0.getIndex()); 42603928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.setPutIndex(_tok1.getIndex()); 42703928aee4356845252ac6b662d5c72c29903813eJake Slack _multiLineValue=null; 42803928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 42903928aee4356845252ac6b662d5c72c29903813eJake Slack } 43003928aee4356845252ac6b662d5c72c29903813eJake Slack // not a digit, so must be a URI 43103928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_URI; 43203928aee4356845252ac6b662d5c72c29903813eJake Slack _responseStatus=-1; 43303928aee4356845252ac6b662d5c72c29903813eJake Slack break; 43403928aee4356845252ac6b662d5c72c29903813eJake Slack 43503928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_URI: 43603928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.SPACE) 43703928aee4356845252ac6b662d5c72c29903813eJake Slack { 43803928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.update(_buffer.markIndex(), _buffer.getIndex() - 1); 43903928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_SPACE2; 44003928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 44103928aee4356845252ac6b662d5c72c29903813eJake Slack } 44203928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch < HttpTokens.SPACE && ch>=0) 44303928aee4356845252ac6b662d5c72c29903813eJake Slack { 44403928aee4356845252ac6b662d5c72c29903813eJake Slack // HTTP/0.9 44503928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _buffer.sliceFromMark(), null); 44603928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=false; 44703928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_SEEKING_EOF; 44803928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.headerComplete(); 44903928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 45003928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 45103928aee4356845252ac6b662d5c72c29903813eJake Slack } 45203928aee4356845252ac6b662d5c72c29903813eJake Slack break; 45303928aee4356845252ac6b662d5c72c29903813eJake Slack 45403928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_SPACE2: 45503928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch > HttpTokens.SPACE || ch<0) 45603928aee4356845252ac6b662d5c72c29903813eJake Slack { 45703928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.mark(); 45803928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_FIELD2; 45903928aee4356845252ac6b662d5c72c29903813eJake Slack } 46003928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch < HttpTokens.SPACE) 46103928aee4356845252ac6b662d5c72c29903813eJake Slack { 46203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_responseStatus>0) 46303928aee4356845252ac6b662d5c72c29903813eJake Slack { 46403928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.startResponse(HttpMethods.CACHE.lookup(_tok0), _responseStatus, null); 46503928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 46603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER; 46703928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.setPutIndex(_tok0.getIndex()); 46803928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.setPutIndex(_tok1.getIndex()); 46903928aee4356845252ac6b662d5c72c29903813eJake Slack _multiLineValue=null; 47003928aee4356845252ac6b662d5c72c29903813eJake Slack } 47103928aee4356845252ac6b662d5c72c29903813eJake Slack else 47203928aee4356845252ac6b662d5c72c29903813eJake Slack { 47303928aee4356845252ac6b662d5c72c29903813eJake Slack // HTTP/0.9 47403928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _tok1, null); 47503928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=false; 47603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_SEEKING_EOF; 47703928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.headerComplete(); 47803928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 47903928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 48003928aee4356845252ac6b662d5c72c29903813eJake Slack } 48103928aee4356845252ac6b662d5c72c29903813eJake Slack } 48203928aee4356845252ac6b662d5c72c29903813eJake Slack break; 48303928aee4356845252ac6b662d5c72c29903813eJake Slack 48403928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_FIELD2: 48503928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) 48603928aee4356845252ac6b662d5c72c29903813eJake Slack { 48703928aee4356845252ac6b662d5c72c29903813eJake Slack Buffer version; 48803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_responseStatus>0) 48903928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.startResponse(version=HttpVersions.CACHE.lookup(_tok0), _responseStatus,_buffer.sliceFromMark()); 49003928aee4356845252ac6b662d5c72c29903813eJake Slack else 49103928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _tok1, version=HttpVersions.CACHE.lookup(_buffer.sliceFromMark())); 49203928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 49303928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=HttpVersions.CACHE.getOrdinal(version)>=HttpVersions.HTTP_1_1_ORDINAL; 49403928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER; 49503928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.setPutIndex(_tok0.getIndex()); 49603928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.setPutIndex(_tok1.getIndex()); 49703928aee4356845252ac6b662d5c72c29903813eJake Slack _multiLineValue=null; 49803928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 49903928aee4356845252ac6b662d5c72c29903813eJake Slack } 50003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 50103928aee4356845252ac6b662d5c72c29903813eJake Slack 50203928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_HEADER: 50303928aee4356845252ac6b662d5c72c29903813eJake Slack switch(ch) 50403928aee4356845252ac6b662d5c72c29903813eJake Slack { 50503928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.COLON: 50603928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.SPACE: 50703928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.TAB: 50803928aee4356845252ac6b662d5c72c29903813eJake Slack { 50903928aee4356845252ac6b662d5c72c29903813eJake Slack // header value without name - continuation? 51003928aee4356845252ac6b662d5c72c29903813eJake Slack _length=-1; 51103928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_VALUE; 51203928aee4356845252ac6b662d5c72c29903813eJake Slack break; 51303928aee4356845252ac6b662d5c72c29903813eJake Slack } 51403928aee4356845252ac6b662d5c72c29903813eJake Slack 51503928aee4356845252ac6b662d5c72c29903813eJake Slack default: 51603928aee4356845252ac6b662d5c72c29903813eJake Slack { 51703928aee4356845252ac6b662d5c72c29903813eJake Slack // handler last header if any 51803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cached!=null || _tok0.length() > 0 || _tok1.length() > 0 || _multiLineValue != null) 51903928aee4356845252ac6b662d5c72c29903813eJake Slack { 52003928aee4356845252ac6b662d5c72c29903813eJake Slack Buffer header=_cached!=null?_cached:HttpHeaders.CACHE.lookup(_tok0); 52103928aee4356845252ac6b662d5c72c29903813eJake Slack _cached=null; 52203928aee4356845252ac6b662d5c72c29903813eJake Slack Buffer value=_multiLineValue == null ? _tok1 : new ByteArrayBuffer(_multiLineValue); 52303928aee4356845252ac6b662d5c72c29903813eJake Slack 52403928aee4356845252ac6b662d5c72c29903813eJake Slack int ho=HttpHeaders.CACHE.getOrdinal(header); 52503928aee4356845252ac6b662d5c72c29903813eJake Slack if (ho >= 0) 52603928aee4356845252ac6b662d5c72c29903813eJake Slack { 52703928aee4356845252ac6b662d5c72c29903813eJake Slack int vo; 52803928aee4356845252ac6b662d5c72c29903813eJake Slack 52903928aee4356845252ac6b662d5c72c29903813eJake Slack switch (ho) 53003928aee4356845252ac6b662d5c72c29903813eJake Slack { 53103928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpHeaders.CONTENT_LENGTH_ORDINAL: 53203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_contentLength != HttpTokens.CHUNKED_CONTENT ) 53303928aee4356845252ac6b662d5c72c29903813eJake Slack { 53403928aee4356845252ac6b662d5c72c29903813eJake Slack try 53503928aee4356845252ac6b662d5c72c29903813eJake Slack { 53603928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=BufferUtil.toLong(value); 53703928aee4356845252ac6b662d5c72c29903813eJake Slack } 53803928aee4356845252ac6b662d5c72c29903813eJake Slack catch(NumberFormatException e) 53903928aee4356845252ac6b662d5c72c29903813eJake Slack { 54003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 54103928aee4356845252ac6b662d5c72c29903813eJake Slack throw new HttpException(HttpStatus.BAD_REQUEST_400); 54203928aee4356845252ac6b662d5c72c29903813eJake Slack } 54303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_contentLength <= 0) 54403928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.NO_CONTENT; 54503928aee4356845252ac6b662d5c72c29903813eJake Slack } 54603928aee4356845252ac6b662d5c72c29903813eJake Slack break; 54703928aee4356845252ac6b662d5c72c29903813eJake Slack 54803928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpHeaders.TRANSFER_ENCODING_ORDINAL: 54903928aee4356845252ac6b662d5c72c29903813eJake Slack value=HttpHeaderValues.CACHE.lookup(value); 55003928aee4356845252ac6b662d5c72c29903813eJake Slack vo=HttpHeaderValues.CACHE.getOrdinal(value); 55103928aee4356845252ac6b662d5c72c29903813eJake Slack if (HttpHeaderValues.CHUNKED_ORDINAL == vo) 55203928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.CHUNKED_CONTENT; 55303928aee4356845252ac6b662d5c72c29903813eJake Slack else 55403928aee4356845252ac6b662d5c72c29903813eJake Slack { 55503928aee4356845252ac6b662d5c72c29903813eJake Slack String c=value.toString(StringUtil.__ISO_8859_1); 55603928aee4356845252ac6b662d5c72c29903813eJake Slack if (c.endsWith(HttpHeaderValues.CHUNKED)) 55703928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.CHUNKED_CONTENT; 55803928aee4356845252ac6b662d5c72c29903813eJake Slack 55903928aee4356845252ac6b662d5c72c29903813eJake Slack else if (c.indexOf(HttpHeaderValues.CHUNKED) >= 0) 56003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new HttpException(400,null); 56103928aee4356845252ac6b662d5c72c29903813eJake Slack } 56203928aee4356845252ac6b662d5c72c29903813eJake Slack break; 56303928aee4356845252ac6b662d5c72c29903813eJake Slack 56403928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpHeaders.CONNECTION_ORDINAL: 56503928aee4356845252ac6b662d5c72c29903813eJake Slack switch(HttpHeaderValues.CACHE.getOrdinal(value)) 56603928aee4356845252ac6b662d5c72c29903813eJake Slack { 56703928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpHeaderValues.CLOSE_ORDINAL: 56803928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=false; 56903928aee4356845252ac6b662d5c72c29903813eJake Slack break; 57003928aee4356845252ac6b662d5c72c29903813eJake Slack 57103928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpHeaderValues.KEEP_ALIVE_ORDINAL: 57203928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=true; 57303928aee4356845252ac6b662d5c72c29903813eJake Slack break; 57403928aee4356845252ac6b662d5c72c29903813eJake Slack 57503928aee4356845252ac6b662d5c72c29903813eJake Slack case -1: // No match, may be multi valued 57603928aee4356845252ac6b662d5c72c29903813eJake Slack { 57703928aee4356845252ac6b662d5c72c29903813eJake Slack for (String v : value.toString().split(",")) 57803928aee4356845252ac6b662d5c72c29903813eJake Slack { 57903928aee4356845252ac6b662d5c72c29903813eJake Slack switch(HttpHeaderValues.CACHE.getOrdinal(v.trim())) 58003928aee4356845252ac6b662d5c72c29903813eJake Slack { 58103928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpHeaderValues.CLOSE_ORDINAL: 58203928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=false; 58303928aee4356845252ac6b662d5c72c29903813eJake Slack break; 58403928aee4356845252ac6b662d5c72c29903813eJake Slack 58503928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpHeaderValues.KEEP_ALIVE_ORDINAL: 58603928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=true; 58703928aee4356845252ac6b662d5c72c29903813eJake Slack break; 58803928aee4356845252ac6b662d5c72c29903813eJake Slack } 58903928aee4356845252ac6b662d5c72c29903813eJake Slack } 59003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 59103928aee4356845252ac6b662d5c72c29903813eJake Slack } 59203928aee4356845252ac6b662d5c72c29903813eJake Slack } 59303928aee4356845252ac6b662d5c72c29903813eJake Slack } 59403928aee4356845252ac6b662d5c72c29903813eJake Slack } 59503928aee4356845252ac6b662d5c72c29903813eJake Slack 59603928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.parsedHeader(header, value); 59703928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.setPutIndex(_tok0.getIndex()); 59803928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.setPutIndex(_tok1.getIndex()); 59903928aee4356845252ac6b662d5c72c29903813eJake Slack _multiLineValue=null; 60003928aee4356845252ac6b662d5c72c29903813eJake Slack } 60103928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.setMarkIndex(-1); 60203928aee4356845252ac6b662d5c72c29903813eJake Slack 60303928aee4356845252ac6b662d5c72c29903813eJake Slack // now handle ch 60403928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) 60503928aee4356845252ac6b662d5c72c29903813eJake Slack { 60603928aee4356845252ac6b662d5c72c29903813eJake Slack // is it a response that cannot have a body? 60703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_responseStatus > 0 && // response 60803928aee4356845252ac6b662d5c72c29903813eJake Slack (_responseStatus == 304 || // not-modified response 60903928aee4356845252ac6b662d5c72c29903813eJake Slack _responseStatus == 204 || // no-content response 61003928aee4356845252ac6b662d5c72c29903813eJake Slack _responseStatus < 200)) // 1xx response 61103928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.NO_CONTENT; // ignore any other headers set 61203928aee4356845252ac6b662d5c72c29903813eJake Slack // else if we don't know framing 61303928aee4356845252ac6b662d5c72c29903813eJake Slack else if (_contentLength == HttpTokens.UNKNOWN_CONTENT) 61403928aee4356845252ac6b662d5c72c29903813eJake Slack { 61503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_responseStatus == 0 // request 61603928aee4356845252ac6b662d5c72c29903813eJake Slack || _responseStatus == 304 // not-modified response 61703928aee4356845252ac6b662d5c72c29903813eJake Slack || _responseStatus == 204 // no-content response 61803928aee4356845252ac6b662d5c72c29903813eJake Slack || _responseStatus < 200) // 1xx response 61903928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.NO_CONTENT; 62003928aee4356845252ac6b662d5c72c29903813eJake Slack else 62103928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.EOF_CONTENT; 62203928aee4356845252ac6b662d5c72c29903813eJake Slack } 62303928aee4356845252ac6b662d5c72c29903813eJake Slack 62403928aee4356845252ac6b662d5c72c29903813eJake Slack _contentPosition=0; 62503928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 62603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED) 62703928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=_buffer.get(); 62803928aee4356845252ac6b662d5c72c29903813eJake Slack 62903928aee4356845252ac6b662d5c72c29903813eJake Slack // We convert _contentLength to an int for this switch statement because 63003928aee4356845252ac6b662d5c72c29903813eJake Slack // we don't care about the amount of data available just whether there is some. 63103928aee4356845252ac6b662d5c72c29903813eJake Slack switch (_contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) _contentLength) 63203928aee4356845252ac6b662d5c72c29903813eJake Slack { 63303928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.EOF_CONTENT: 63403928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_EOF_CONTENT; 63503928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.headerComplete(); // May recurse here ! 63603928aee4356845252ac6b662d5c72c29903813eJake Slack break; 63703928aee4356845252ac6b662d5c72c29903813eJake Slack 63803928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.CHUNKED_CONTENT: 63903928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_CHUNKED_CONTENT; 64003928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.headerComplete(); // May recurse here ! 64103928aee4356845252ac6b662d5c72c29903813eJake Slack break; 64203928aee4356845252ac6b662d5c72c29903813eJake Slack 64303928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.NO_CONTENT: 64403928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.headerComplete(); 64503928aee4356845252ac6b662d5c72c29903813eJake Slack _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF; 64603928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 64703928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 64803928aee4356845252ac6b662d5c72c29903813eJake Slack 64903928aee4356845252ac6b662d5c72c29903813eJake Slack default: 65003928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_CONTENT; 65103928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.headerComplete(); // May recurse here ! 65203928aee4356845252ac6b662d5c72c29903813eJake Slack break; 65303928aee4356845252ac6b662d5c72c29903813eJake Slack } 65403928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 65503928aee4356845252ac6b662d5c72c29903813eJake Slack } 65603928aee4356845252ac6b662d5c72c29903813eJake Slack else 65703928aee4356845252ac6b662d5c72c29903813eJake Slack { 65803928aee4356845252ac6b662d5c72c29903813eJake Slack // New header 65903928aee4356845252ac6b662d5c72c29903813eJake Slack _length=1; 66003928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.mark(); 66103928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_NAME; 66203928aee4356845252ac6b662d5c72c29903813eJake Slack 66303928aee4356845252ac6b662d5c72c29903813eJake Slack // try cached name! 66403928aee4356845252ac6b662d5c72c29903813eJake Slack if (array!=null) 66503928aee4356845252ac6b662d5c72c29903813eJake Slack { 66603928aee4356845252ac6b662d5c72c29903813eJake Slack _cached=HttpHeaders.CACHE.getBest(array, _buffer.markIndex(), length+1); 66703928aee4356845252ac6b662d5c72c29903813eJake Slack 66803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cached!=null) 66903928aee4356845252ac6b662d5c72c29903813eJake Slack { 67003928aee4356845252ac6b662d5c72c29903813eJake Slack _length=_cached.length(); 67103928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.setGetIndex(_buffer.markIndex()+_length); 67203928aee4356845252ac6b662d5c72c29903813eJake Slack length=_buffer.length(); 67303928aee4356845252ac6b662d5c72c29903813eJake Slack } 67403928aee4356845252ac6b662d5c72c29903813eJake Slack } 67503928aee4356845252ac6b662d5c72c29903813eJake Slack } 67603928aee4356845252ac6b662d5c72c29903813eJake Slack } 67703928aee4356845252ac6b662d5c72c29903813eJake Slack } 67803928aee4356845252ac6b662d5c72c29903813eJake Slack 67903928aee4356845252ac6b662d5c72c29903813eJake Slack break; 68003928aee4356845252ac6b662d5c72c29903813eJake Slack 68103928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_HEADER_NAME: 68203928aee4356845252ac6b662d5c72c29903813eJake Slack switch(ch) 68303928aee4356845252ac6b662d5c72c29903813eJake Slack { 68403928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.CARRIAGE_RETURN: 68503928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.LINE_FEED: 68603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length > 0) 68703928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); 68803928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 68903928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER; 69003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 69103928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.COLON: 69203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length > 0 && _cached==null) 69303928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); 69403928aee4356845252ac6b662d5c72c29903813eJake Slack _length=-1; 69503928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_VALUE; 69603928aee4356845252ac6b662d5c72c29903813eJake Slack break; 69703928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.SPACE: 69803928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.TAB: 69903928aee4356845252ac6b662d5c72c29903813eJake Slack break; 70003928aee4356845252ac6b662d5c72c29903813eJake Slack default: 70103928aee4356845252ac6b662d5c72c29903813eJake Slack { 70203928aee4356845252ac6b662d5c72c29903813eJake Slack _cached=null; 70303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length == -1) 70403928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.mark(); 70503928aee4356845252ac6b662d5c72c29903813eJake Slack _length=_buffer.getIndex() - _buffer.markIndex(); 70603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_IN_NAME; 70703928aee4356845252ac6b662d5c72c29903813eJake Slack } 70803928aee4356845252ac6b662d5c72c29903813eJake Slack } 70903928aee4356845252ac6b662d5c72c29903813eJake Slack 71003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 71103928aee4356845252ac6b662d5c72c29903813eJake Slack 71203928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_HEADER_IN_NAME: 71303928aee4356845252ac6b662d5c72c29903813eJake Slack switch(ch) 71403928aee4356845252ac6b662d5c72c29903813eJake Slack { 71503928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.CARRIAGE_RETURN: 71603928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.LINE_FEED: 71703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length > 0) 71803928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); 71903928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 72003928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER; 72103928aee4356845252ac6b662d5c72c29903813eJake Slack break; 72203928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.COLON: 72303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length > 0 && _cached==null) 72403928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); 72503928aee4356845252ac6b662d5c72c29903813eJake Slack _length=-1; 72603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_VALUE; 72703928aee4356845252ac6b662d5c72c29903813eJake Slack break; 72803928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.SPACE: 72903928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.TAB: 73003928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_NAME; 73103928aee4356845252ac6b662d5c72c29903813eJake Slack break; 73203928aee4356845252ac6b662d5c72c29903813eJake Slack default: 73303928aee4356845252ac6b662d5c72c29903813eJake Slack { 73403928aee4356845252ac6b662d5c72c29903813eJake Slack _cached=null; 73503928aee4356845252ac6b662d5c72c29903813eJake Slack _length++; 73603928aee4356845252ac6b662d5c72c29903813eJake Slack } 73703928aee4356845252ac6b662d5c72c29903813eJake Slack } 73803928aee4356845252ac6b662d5c72c29903813eJake Slack break; 73903928aee4356845252ac6b662d5c72c29903813eJake Slack 74003928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_HEADER_VALUE: 74103928aee4356845252ac6b662d5c72c29903813eJake Slack switch(ch) 74203928aee4356845252ac6b662d5c72c29903813eJake Slack { 74303928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.CARRIAGE_RETURN: 74403928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.LINE_FEED: 74503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length > 0) 74603928aee4356845252ac6b662d5c72c29903813eJake Slack { 74703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_tok1.length() == 0) 74803928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); 74903928aee4356845252ac6b662d5c72c29903813eJake Slack else 75003928aee4356845252ac6b662d5c72c29903813eJake Slack { 75103928aee4356845252ac6b662d5c72c29903813eJake Slack // Continuation line! 75203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_multiLineValue == null) _multiLineValue=_tok1.toString(StringUtil.__ISO_8859_1); 75303928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); 75403928aee4356845252ac6b662d5c72c29903813eJake Slack _multiLineValue += " " + _tok1.toString(StringUtil.__ISO_8859_1); 75503928aee4356845252ac6b662d5c72c29903813eJake Slack } 75603928aee4356845252ac6b662d5c72c29903813eJake Slack } 75703928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 75803928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER; 75903928aee4356845252ac6b662d5c72c29903813eJake Slack break; 76003928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.SPACE: 76103928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.TAB: 76203928aee4356845252ac6b662d5c72c29903813eJake Slack break; 76303928aee4356845252ac6b662d5c72c29903813eJake Slack default: 76403928aee4356845252ac6b662d5c72c29903813eJake Slack { 76503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length == -1) 76603928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.mark(); 76703928aee4356845252ac6b662d5c72c29903813eJake Slack _length=_buffer.getIndex() - _buffer.markIndex(); 76803928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_IN_VALUE; 76903928aee4356845252ac6b662d5c72c29903813eJake Slack } 77003928aee4356845252ac6b662d5c72c29903813eJake Slack } 77103928aee4356845252ac6b662d5c72c29903813eJake Slack break; 77203928aee4356845252ac6b662d5c72c29903813eJake Slack 77303928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_HEADER_IN_VALUE: 77403928aee4356845252ac6b662d5c72c29903813eJake Slack switch(ch) 77503928aee4356845252ac6b662d5c72c29903813eJake Slack { 77603928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.CARRIAGE_RETURN: 77703928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.LINE_FEED: 77803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_length > 0) 77903928aee4356845252ac6b662d5c72c29903813eJake Slack { 78003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_tok1.length() == 0) 78103928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); 78203928aee4356845252ac6b662d5c72c29903813eJake Slack else 78303928aee4356845252ac6b662d5c72c29903813eJake Slack { 78403928aee4356845252ac6b662d5c72c29903813eJake Slack // Continuation line! 78503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_multiLineValue == null) _multiLineValue=_tok1.toString(StringUtil.__ISO_8859_1); 78603928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); 78703928aee4356845252ac6b662d5c72c29903813eJake Slack _multiLineValue += " " + _tok1.toString(StringUtil.__ISO_8859_1); 78803928aee4356845252ac6b662d5c72c29903813eJake Slack } 78903928aee4356845252ac6b662d5c72c29903813eJake Slack } 79003928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 79103928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER; 79203928aee4356845252ac6b662d5c72c29903813eJake Slack break; 79303928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.SPACE: 79403928aee4356845252ac6b662d5c72c29903813eJake Slack case HttpTokens.TAB: 79503928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_HEADER_VALUE; 79603928aee4356845252ac6b662d5c72c29903813eJake Slack break; 79703928aee4356845252ac6b662d5c72c29903813eJake Slack default: 79803928aee4356845252ac6b662d5c72c29903813eJake Slack _length++; 79903928aee4356845252ac6b662d5c72c29903813eJake Slack } 80003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 80103928aee4356845252ac6b662d5c72c29903813eJake Slack } 80203928aee4356845252ac6b662d5c72c29903813eJake Slack } // end of HEADER states loop 80303928aee4356845252ac6b662d5c72c29903813eJake Slack 80403928aee4356845252ac6b662d5c72c29903813eJake Slack // ========================== 80503928aee4356845252ac6b662d5c72c29903813eJake Slack 80603928aee4356845252ac6b662d5c72c29903813eJake Slack // Handle HEAD response 80703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_responseStatus>0 && _headResponse) 80803928aee4356845252ac6b662d5c72c29903813eJake Slack { 80903928aee4356845252ac6b662d5c72c29903813eJake Slack _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF; 81003928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentLength); 81103928aee4356845252ac6b662d5c72c29903813eJake Slack } 81203928aee4356845252ac6b662d5c72c29903813eJake Slack 81303928aee4356845252ac6b662d5c72c29903813eJake Slack 81403928aee4356845252ac6b662d5c72c29903813eJake Slack // ========================== 81503928aee4356845252ac6b662d5c72c29903813eJake Slack 81603928aee4356845252ac6b662d5c72c29903813eJake Slack // Handle _content 81703928aee4356845252ac6b662d5c72c29903813eJake Slack length=_buffer.length(); 81803928aee4356845252ac6b662d5c72c29903813eJake Slack Buffer chunk; 81903928aee4356845252ac6b662d5c72c29903813eJake Slack last=_state; 82003928aee4356845252ac6b662d5c72c29903813eJake Slack while (_state > STATE_END && length > 0) 82103928aee4356845252ac6b662d5c72c29903813eJake Slack { 82203928aee4356845252ac6b662d5c72c29903813eJake Slack if (last!=_state) 82303928aee4356845252ac6b662d5c72c29903813eJake Slack { 82403928aee4356845252ac6b662d5c72c29903813eJake Slack progress++; 82503928aee4356845252ac6b662d5c72c29903813eJake Slack last=_state; 82603928aee4356845252ac6b662d5c72c29903813eJake Slack } 82703928aee4356845252ac6b662d5c72c29903813eJake Slack 82803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_eol == HttpTokens.CARRIAGE_RETURN && _buffer.peek() == HttpTokens.LINE_FEED) 82903928aee4356845252ac6b662d5c72c29903813eJake Slack { 83003928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=_buffer.get(); 83103928aee4356845252ac6b662d5c72c29903813eJake Slack length=_buffer.length(); 83203928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 83303928aee4356845252ac6b662d5c72c29903813eJake Slack } 83403928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=0; 83503928aee4356845252ac6b662d5c72c29903813eJake Slack switch (_state) 83603928aee4356845252ac6b662d5c72c29903813eJake Slack { 83703928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_EOF_CONTENT: 83803928aee4356845252ac6b662d5c72c29903813eJake Slack chunk=_buffer.get(_buffer.length()); 83903928aee4356845252ac6b662d5c72c29903813eJake Slack _contentPosition += chunk.length(); 84003928aee4356845252ac6b662d5c72c29903813eJake Slack _contentView.update(chunk); 84103928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.content(chunk); // May recurse here 84203928aee4356845252ac6b662d5c72c29903813eJake Slack // TODO adjust the _buffer to keep unconsumed content 84303928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 84403928aee4356845252ac6b662d5c72c29903813eJake Slack 84503928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_CONTENT: 84603928aee4356845252ac6b662d5c72c29903813eJake Slack { 84703928aee4356845252ac6b662d5c72c29903813eJake Slack long remaining=_contentLength - _contentPosition; 84803928aee4356845252ac6b662d5c72c29903813eJake Slack if (remaining == 0) 84903928aee4356845252ac6b662d5c72c29903813eJake Slack { 85003928aee4356845252ac6b662d5c72c29903813eJake Slack _state=_persistent?STATE_END:STATE_SEEKING_EOF; 85103928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 85203928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 85303928aee4356845252ac6b662d5c72c29903813eJake Slack } 85403928aee4356845252ac6b662d5c72c29903813eJake Slack 85503928aee4356845252ac6b662d5c72c29903813eJake Slack if (length > remaining) 85603928aee4356845252ac6b662d5c72c29903813eJake Slack { 85703928aee4356845252ac6b662d5c72c29903813eJake Slack // We can cast reamining to an int as we know that it is smaller than 85803928aee4356845252ac6b662d5c72c29903813eJake Slack // or equal to length which is already an int. 85903928aee4356845252ac6b662d5c72c29903813eJake Slack length=(int)remaining; 86003928aee4356845252ac6b662d5c72c29903813eJake Slack } 86103928aee4356845252ac6b662d5c72c29903813eJake Slack 86203928aee4356845252ac6b662d5c72c29903813eJake Slack chunk=_buffer.get(length); 86303928aee4356845252ac6b662d5c72c29903813eJake Slack _contentPosition += chunk.length(); 86403928aee4356845252ac6b662d5c72c29903813eJake Slack _contentView.update(chunk); 86503928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.content(chunk); // May recurse here 86603928aee4356845252ac6b662d5c72c29903813eJake Slack 86703928aee4356845252ac6b662d5c72c29903813eJake Slack if(_contentPosition == _contentLength) 86803928aee4356845252ac6b662d5c72c29903813eJake Slack { 86903928aee4356845252ac6b662d5c72c29903813eJake Slack _state=_persistent?STATE_END:STATE_SEEKING_EOF; 87003928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 87103928aee4356845252ac6b662d5c72c29903813eJake Slack } 87203928aee4356845252ac6b662d5c72c29903813eJake Slack // TODO adjust the _buffer to keep unconsumed content 87303928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 87403928aee4356845252ac6b662d5c72c29903813eJake Slack } 87503928aee4356845252ac6b662d5c72c29903813eJake Slack 87603928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_CHUNKED_CONTENT: 87703928aee4356845252ac6b662d5c72c29903813eJake Slack { 87803928aee4356845252ac6b662d5c72c29903813eJake Slack ch=_buffer.peek(); 87903928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) 88003928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=_buffer.get(); 88103928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch <= HttpTokens.SPACE) 88203928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.get(); 88303928aee4356845252ac6b662d5c72c29903813eJake Slack else 88403928aee4356845252ac6b662d5c72c29903813eJake Slack { 88503928aee4356845252ac6b662d5c72c29903813eJake Slack _chunkLength=0; 88603928aee4356845252ac6b662d5c72c29903813eJake Slack _chunkPosition=0; 88703928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_CHUNK_SIZE; 88803928aee4356845252ac6b662d5c72c29903813eJake Slack } 88903928aee4356845252ac6b662d5c72c29903813eJake Slack break; 89003928aee4356845252ac6b662d5c72c29903813eJake Slack } 89103928aee4356845252ac6b662d5c72c29903813eJake Slack 89203928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_CHUNK_SIZE: 89303928aee4356845252ac6b662d5c72c29903813eJake Slack { 89403928aee4356845252ac6b662d5c72c29903813eJake Slack ch=_buffer.get(); 89503928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) 89603928aee4356845252ac6b662d5c72c29903813eJake Slack { 89703928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 89803928aee4356845252ac6b662d5c72c29903813eJake Slack 89903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_chunkLength == 0) 90003928aee4356845252ac6b662d5c72c29903813eJake Slack { 90103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED) 90203928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=_buffer.get(); 90303928aee4356845252ac6b662d5c72c29903813eJake Slack _state=_persistent?STATE_END:STATE_SEEKING_EOF; 90403928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 90503928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 90603928aee4356845252ac6b662d5c72c29903813eJake Slack } 90703928aee4356845252ac6b662d5c72c29903813eJake Slack else 90803928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_CHUNK; 90903928aee4356845252ac6b662d5c72c29903813eJake Slack } 91003928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch <= HttpTokens.SPACE || ch == HttpTokens.SEMI_COLON) 91103928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_CHUNK_PARAMS; 91203928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch >= '0' && ch <= '9') 91303928aee4356845252ac6b662d5c72c29903813eJake Slack _chunkLength=_chunkLength * 16 + (ch - '0'); 91403928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch >= 'a' && ch <= 'f') 91503928aee4356845252ac6b662d5c72c29903813eJake Slack _chunkLength=_chunkLength * 16 + (10 + ch - 'a'); 91603928aee4356845252ac6b662d5c72c29903813eJake Slack else if (ch >= 'A' && ch <= 'F') 91703928aee4356845252ac6b662d5c72c29903813eJake Slack _chunkLength=_chunkLength * 16 + (10 + ch - 'A'); 91803928aee4356845252ac6b662d5c72c29903813eJake Slack else 91903928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IOException("bad chunk char: " + ch); 92003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 92103928aee4356845252ac6b662d5c72c29903813eJake Slack } 92203928aee4356845252ac6b662d5c72c29903813eJake Slack 92303928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_CHUNK_PARAMS: 92403928aee4356845252ac6b662d5c72c29903813eJake Slack { 92503928aee4356845252ac6b662d5c72c29903813eJake Slack ch=_buffer.get(); 92603928aee4356845252ac6b662d5c72c29903813eJake Slack if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) 92703928aee4356845252ac6b662d5c72c29903813eJake Slack { 92803928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=ch; 92903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_chunkLength == 0) 93003928aee4356845252ac6b662d5c72c29903813eJake Slack { 93103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED) 93203928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=_buffer.get(); 93303928aee4356845252ac6b662d5c72c29903813eJake Slack _state=_persistent?STATE_END:STATE_SEEKING_EOF; 93403928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.messageComplete(_contentPosition); 93503928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 93603928aee4356845252ac6b662d5c72c29903813eJake Slack } 93703928aee4356845252ac6b662d5c72c29903813eJake Slack else 93803928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_CHUNK; 93903928aee4356845252ac6b662d5c72c29903813eJake Slack } 94003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 94103928aee4356845252ac6b662d5c72c29903813eJake Slack } 94203928aee4356845252ac6b662d5c72c29903813eJake Slack 94303928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_CHUNK: 94403928aee4356845252ac6b662d5c72c29903813eJake Slack { 94503928aee4356845252ac6b662d5c72c29903813eJake Slack int remaining=_chunkLength - _chunkPosition; 94603928aee4356845252ac6b662d5c72c29903813eJake Slack if (remaining == 0) 94703928aee4356845252ac6b662d5c72c29903813eJake Slack { 94803928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_CHUNKED_CONTENT; 94903928aee4356845252ac6b662d5c72c29903813eJake Slack break; 95003928aee4356845252ac6b662d5c72c29903813eJake Slack } 95103928aee4356845252ac6b662d5c72c29903813eJake Slack else if (length > remaining) 95203928aee4356845252ac6b662d5c72c29903813eJake Slack length=remaining; 95303928aee4356845252ac6b662d5c72c29903813eJake Slack chunk=_buffer.get(length); 95403928aee4356845252ac6b662d5c72c29903813eJake Slack _contentPosition += chunk.length(); 95503928aee4356845252ac6b662d5c72c29903813eJake Slack _chunkPosition += chunk.length(); 95603928aee4356845252ac6b662d5c72c29903813eJake Slack _contentView.update(chunk); 95703928aee4356845252ac6b662d5c72c29903813eJake Slack _handler.content(chunk); // May recurse here 95803928aee4356845252ac6b662d5c72c29903813eJake Slack // TODO adjust the _buffer to keep unconsumed content 95903928aee4356845252ac6b662d5c72c29903813eJake Slack return 1; 96003928aee4356845252ac6b662d5c72c29903813eJake Slack } 96103928aee4356845252ac6b662d5c72c29903813eJake Slack 96203928aee4356845252ac6b662d5c72c29903813eJake Slack case STATE_SEEKING_EOF: 96303928aee4356845252ac6b662d5c72c29903813eJake Slack { 96403928aee4356845252ac6b662d5c72c29903813eJake Slack // Close if there is more data than CRLF 96503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer.length()>2) 96603928aee4356845252ac6b662d5c72c29903813eJake Slack { 96703928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_END; 96803928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 96903928aee4356845252ac6b662d5c72c29903813eJake Slack } 97003928aee4356845252ac6b662d5c72c29903813eJake Slack else 97103928aee4356845252ac6b662d5c72c29903813eJake Slack { 97203928aee4356845252ac6b662d5c72c29903813eJake Slack // or if the data is not white space 97303928aee4356845252ac6b662d5c72c29903813eJake Slack while (_buffer.length()>0) 97403928aee4356845252ac6b662d5c72c29903813eJake Slack if (!Character.isWhitespace(_buffer.get())) 97503928aee4356845252ac6b662d5c72c29903813eJake Slack { 97603928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_END; 97703928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 97803928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.clear(); 97903928aee4356845252ac6b662d5c72c29903813eJake Slack } 98003928aee4356845252ac6b662d5c72c29903813eJake Slack } 98103928aee4356845252ac6b662d5c72c29903813eJake Slack 98203928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.clear(); 98303928aee4356845252ac6b662d5c72c29903813eJake Slack break; 98403928aee4356845252ac6b662d5c72c29903813eJake Slack } 98503928aee4356845252ac6b662d5c72c29903813eJake Slack } 98603928aee4356845252ac6b662d5c72c29903813eJake Slack 98703928aee4356845252ac6b662d5c72c29903813eJake Slack length=_buffer.length(); 98803928aee4356845252ac6b662d5c72c29903813eJake Slack } 98903928aee4356845252ac6b662d5c72c29903813eJake Slack 99003928aee4356845252ac6b662d5c72c29903813eJake Slack return progress; 99103928aee4356845252ac6b662d5c72c29903813eJake Slack } 99203928aee4356845252ac6b662d5c72c29903813eJake Slack catch(HttpException e) 99303928aee4356845252ac6b662d5c72c29903813eJake Slack { 99403928aee4356845252ac6b662d5c72c29903813eJake Slack _persistent=false; 99503928aee4356845252ac6b662d5c72c29903813eJake Slack _state=STATE_SEEKING_EOF; 99603928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 99703928aee4356845252ac6b662d5c72c29903813eJake Slack } 99803928aee4356845252ac6b662d5c72c29903813eJake Slack } 99903928aee4356845252ac6b662d5c72c29903813eJake Slack 100003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 100103928aee4356845252ac6b662d5c72c29903813eJake Slack /** fill the buffers from the endpoint 100203928aee4356845252ac6b662d5c72c29903813eJake Slack * 100303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 100403928aee4356845252ac6b662d5c72c29903813eJake Slack protected int fill() throws IOException 100503928aee4356845252ac6b662d5c72c29903813eJake Slack { 100603928aee4356845252ac6b662d5c72c29903813eJake Slack // Do we have a buffer? 100703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer==null) 100803928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=getHeaderBuffer(); 100903928aee4356845252ac6b662d5c72c29903813eJake Slack 101003928aee4356845252ac6b662d5c72c29903813eJake Slack // Is there unconsumed content in body buffer 101103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state>STATE_END && _buffer==_header && _header!=null && !_header.hasContent() && _body!=null && _body.hasContent()) 101203928aee4356845252ac6b662d5c72c29903813eJake Slack { 101303928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=_body; 101403928aee4356845252ac6b662d5c72c29903813eJake Slack return _buffer.length(); 101503928aee4356845252ac6b662d5c72c29903813eJake Slack } 101603928aee4356845252ac6b662d5c72c29903813eJake Slack 101703928aee4356845252ac6b662d5c72c29903813eJake Slack // Shall we switch to a body buffer? 101803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer==_header && _state>STATE_END && _header.length()==0 && (_forceContentBuffer || (_contentLength-_contentPosition)>_header.capacity()) && (_body!=null||_buffers!=null)) 101903928aee4356845252ac6b662d5c72c29903813eJake Slack { 102003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_body==null) 102103928aee4356845252ac6b662d5c72c29903813eJake Slack _body=_buffers.getBuffer(); 102203928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=_body; 102303928aee4356845252ac6b662d5c72c29903813eJake Slack } 102403928aee4356845252ac6b662d5c72c29903813eJake Slack 102503928aee4356845252ac6b662d5c72c29903813eJake Slack // Do we have somewhere to fill from? 102603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_endp != null ) 102703928aee4356845252ac6b662d5c72c29903813eJake Slack { 102803928aee4356845252ac6b662d5c72c29903813eJake Slack // Shall we compact the body? 102903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer==_body || _state>STATE_END) 103003928aee4356845252ac6b662d5c72c29903813eJake Slack { 103103928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.compact(); 103203928aee4356845252ac6b662d5c72c29903813eJake Slack } 103303928aee4356845252ac6b662d5c72c29903813eJake Slack 103403928aee4356845252ac6b662d5c72c29903813eJake Slack // Are we full? 103503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer.space() == 0) 103603928aee4356845252ac6b662d5c72c29903813eJake Slack { 103703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("HttpParser Full for {} ",_endp); 103803928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer.clear(); 103903928aee4356845252ac6b662d5c72c29903813eJake Slack throw new HttpException(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413, "Request Entity Too Large: "+(_buffer==_body?"body":"head")); 104003928aee4356845252ac6b662d5c72c29903813eJake Slack } 104103928aee4356845252ac6b662d5c72c29903813eJake Slack 104203928aee4356845252ac6b662d5c72c29903813eJake Slack try 104303928aee4356845252ac6b662d5c72c29903813eJake Slack { 104403928aee4356845252ac6b662d5c72c29903813eJake Slack int filled = _endp.fill(_buffer); 104503928aee4356845252ac6b662d5c72c29903813eJake Slack return filled; 104603928aee4356845252ac6b662d5c72c29903813eJake Slack } 104703928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 104803928aee4356845252ac6b662d5c72c29903813eJake Slack { 104903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 105003928aee4356845252ac6b662d5c72c29903813eJake Slack throw (e instanceof EofException) ? e:new EofException(e); 105103928aee4356845252ac6b662d5c72c29903813eJake Slack } 105203928aee4356845252ac6b662d5c72c29903813eJake Slack } 105303928aee4356845252ac6b662d5c72c29903813eJake Slack 105403928aee4356845252ac6b662d5c72c29903813eJake Slack return -1; 105503928aee4356845252ac6b662d5c72c29903813eJake Slack } 105603928aee4356845252ac6b662d5c72c29903813eJake Slack 105703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 105803928aee4356845252ac6b662d5c72c29903813eJake Slack public void reset() 105903928aee4356845252ac6b662d5c72c29903813eJake Slack { 106003928aee4356845252ac6b662d5c72c29903813eJake Slack // reset state 106103928aee4356845252ac6b662d5c72c29903813eJake Slack _contentView.setGetIndex(_contentView.putIndex()); 106203928aee4356845252ac6b662d5c72c29903813eJake Slack _state=_persistent?STATE_START:(_endp.isInputShutdown()?STATE_END:STATE_SEEKING_EOF); 106303928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.UNKNOWN_CONTENT; 106403928aee4356845252ac6b662d5c72c29903813eJake Slack _contentPosition=0; 106503928aee4356845252ac6b662d5c72c29903813eJake Slack _length=0; 106603928aee4356845252ac6b662d5c72c29903813eJake Slack _responseStatus=0; 106703928aee4356845252ac6b662d5c72c29903813eJake Slack 106803928aee4356845252ac6b662d5c72c29903813eJake Slack // Consume LF if CRLF 106903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_eol == HttpTokens.CARRIAGE_RETURN && _buffer!=null && _buffer.hasContent() && _buffer.peek() == HttpTokens.LINE_FEED) 107003928aee4356845252ac6b662d5c72c29903813eJake Slack _eol=_buffer.get(); 107103928aee4356845252ac6b662d5c72c29903813eJake Slack 107203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_body!=null && _body.hasContent()) 107303928aee4356845252ac6b662d5c72c29903813eJake Slack { 107403928aee4356845252ac6b662d5c72c29903813eJake Slack // There is content in the body after the end of the request. 107503928aee4356845252ac6b662d5c72c29903813eJake Slack // This is probably a pipelined header of the next request, so we need to 107603928aee4356845252ac6b662d5c72c29903813eJake Slack // copy it to the header buffer. 107703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_header==null) 107803928aee4356845252ac6b662d5c72c29903813eJake Slack getHeaderBuffer(); 107903928aee4356845252ac6b662d5c72c29903813eJake Slack else 108003928aee4356845252ac6b662d5c72c29903813eJake Slack { 108103928aee4356845252ac6b662d5c72c29903813eJake Slack _header.setMarkIndex(-1); 108203928aee4356845252ac6b662d5c72c29903813eJake Slack _header.compact(); 108303928aee4356845252ac6b662d5c72c29903813eJake Slack } 108403928aee4356845252ac6b662d5c72c29903813eJake Slack int take=_header.space(); 108503928aee4356845252ac6b662d5c72c29903813eJake Slack if (take>_body.length()) 108603928aee4356845252ac6b662d5c72c29903813eJake Slack take=_body.length(); 108703928aee4356845252ac6b662d5c72c29903813eJake Slack _body.peek(_body.getIndex(),take); 108803928aee4356845252ac6b662d5c72c29903813eJake Slack _body.skip(_header.put(_body.peek(_body.getIndex(),take))); 108903928aee4356845252ac6b662d5c72c29903813eJake Slack } 109003928aee4356845252ac6b662d5c72c29903813eJake Slack 109103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_header!=null) 109203928aee4356845252ac6b662d5c72c29903813eJake Slack { 109303928aee4356845252ac6b662d5c72c29903813eJake Slack _header.setMarkIndex(-1); 109403928aee4356845252ac6b662d5c72c29903813eJake Slack _header.compact(); 109503928aee4356845252ac6b662d5c72c29903813eJake Slack } 109603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_body!=null) 109703928aee4356845252ac6b662d5c72c29903813eJake Slack _body.setMarkIndex(-1); 109803928aee4356845252ac6b662d5c72c29903813eJake Slack 109903928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=_header; 110003928aee4356845252ac6b662d5c72c29903813eJake Slack returnBuffers(); 110103928aee4356845252ac6b662d5c72c29903813eJake Slack } 110203928aee4356845252ac6b662d5c72c29903813eJake Slack 110303928aee4356845252ac6b662d5c72c29903813eJake Slack 110403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 110503928aee4356845252ac6b662d5c72c29903813eJake Slack public void returnBuffers() 110603928aee4356845252ac6b662d5c72c29903813eJake Slack { 110703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_body!=null && !_body.hasContent() && _body.markIndex()==-1 && _buffers!=null) 110803928aee4356845252ac6b662d5c72c29903813eJake Slack { 110903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer==_body) 111003928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=_header; 111103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffers!=null) 111203928aee4356845252ac6b662d5c72c29903813eJake Slack _buffers.returnBuffer(_body); 111303928aee4356845252ac6b662d5c72c29903813eJake Slack _body=null; 111403928aee4356845252ac6b662d5c72c29903813eJake Slack } 111503928aee4356845252ac6b662d5c72c29903813eJake Slack 111603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_header!=null && !_header.hasContent() && _header.markIndex()==-1 && _buffers!=null) 111703928aee4356845252ac6b662d5c72c29903813eJake Slack { 111803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_buffer==_header) 111903928aee4356845252ac6b662d5c72c29903813eJake Slack _buffer=null; 112003928aee4356845252ac6b662d5c72c29903813eJake Slack _buffers.returnBuffer(_header); 112103928aee4356845252ac6b662d5c72c29903813eJake Slack _header=null; 112203928aee4356845252ac6b662d5c72c29903813eJake Slack } 112303928aee4356845252ac6b662d5c72c29903813eJake Slack } 112403928aee4356845252ac6b662d5c72c29903813eJake Slack 112503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 112603928aee4356845252ac6b662d5c72c29903813eJake Slack public void setState(int state) 112703928aee4356845252ac6b662d5c72c29903813eJake Slack { 112803928aee4356845252ac6b662d5c72c29903813eJake Slack this._state=state; 112903928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength=HttpTokens.UNKNOWN_CONTENT; 113003928aee4356845252ac6b662d5c72c29903813eJake Slack } 113103928aee4356845252ac6b662d5c72c29903813eJake Slack 113203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 113303928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString(Buffer buf) 113403928aee4356845252ac6b662d5c72c29903813eJake Slack { 113503928aee4356845252ac6b662d5c72c29903813eJake Slack return "state=" + _state + " length=" + _length + " buf=" + buf.hashCode(); 113603928aee4356845252ac6b662d5c72c29903813eJake Slack } 113703928aee4356845252ac6b662d5c72c29903813eJake Slack 113803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 113903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 114003928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 114103928aee4356845252ac6b662d5c72c29903813eJake Slack { 114203928aee4356845252ac6b662d5c72c29903813eJake Slack return String.format("%s{s=%d,l=%d,c=%d}", 114303928aee4356845252ac6b662d5c72c29903813eJake Slack getClass().getSimpleName(), 114403928aee4356845252ac6b662d5c72c29903813eJake Slack _state, 114503928aee4356845252ac6b662d5c72c29903813eJake Slack _length, 114603928aee4356845252ac6b662d5c72c29903813eJake Slack _contentLength); 114703928aee4356845252ac6b662d5c72c29903813eJake Slack } 114803928aee4356845252ac6b662d5c72c29903813eJake Slack 114903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 115003928aee4356845252ac6b662d5c72c29903813eJake Slack public Buffer getHeaderBuffer() 115103928aee4356845252ac6b662d5c72c29903813eJake Slack { 115203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_header == null) 115303928aee4356845252ac6b662d5c72c29903813eJake Slack { 115403928aee4356845252ac6b662d5c72c29903813eJake Slack _header=_buffers.getHeader(); 115503928aee4356845252ac6b662d5c72c29903813eJake Slack _tok0.update(_header); 115603928aee4356845252ac6b662d5c72c29903813eJake Slack _tok1.update(_header); 115703928aee4356845252ac6b662d5c72c29903813eJake Slack } 115803928aee4356845252ac6b662d5c72c29903813eJake Slack return _header; 115903928aee4356845252ac6b662d5c72c29903813eJake Slack } 116003928aee4356845252ac6b662d5c72c29903813eJake Slack 116103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 116203928aee4356845252ac6b662d5c72c29903813eJake Slack public Buffer getBodyBuffer() 116303928aee4356845252ac6b662d5c72c29903813eJake Slack { 116403928aee4356845252ac6b662d5c72c29903813eJake Slack return _body; 116503928aee4356845252ac6b662d5c72c29903813eJake Slack } 116603928aee4356845252ac6b662d5c72c29903813eJake Slack 116703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 116803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 116903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param force True if a new buffer will be forced to be used for content and the header buffer will not be used. 117003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 117103928aee4356845252ac6b662d5c72c29903813eJake Slack public void setForceContentBuffer(boolean force) 117203928aee4356845252ac6b662d5c72c29903813eJake Slack { 117303928aee4356845252ac6b662d5c72c29903813eJake Slack _forceContentBuffer=force; 117403928aee4356845252ac6b662d5c72c29903813eJake Slack } 117503928aee4356845252ac6b662d5c72c29903813eJake Slack 117603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 117703928aee4356845252ac6b662d5c72c29903813eJake Slack public Buffer blockForContent(long maxIdleTime) throws IOException 117803928aee4356845252ac6b662d5c72c29903813eJake Slack { 117903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_contentView.length()>0) 118003928aee4356845252ac6b662d5c72c29903813eJake Slack return _contentView; 118103928aee4356845252ac6b662d5c72c29903813eJake Slack 118203928aee4356845252ac6b662d5c72c29903813eJake Slack if (getState() <= STATE_END || isState(STATE_SEEKING_EOF)) 118303928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 118403928aee4356845252ac6b662d5c72c29903813eJake Slack 118503928aee4356845252ac6b662d5c72c29903813eJake Slack try 118603928aee4356845252ac6b662d5c72c29903813eJake Slack { 118703928aee4356845252ac6b662d5c72c29903813eJake Slack parseNext(); 118803928aee4356845252ac6b662d5c72c29903813eJake Slack 118903928aee4356845252ac6b662d5c72c29903813eJake Slack // parse until some progress is made (or IOException thrown for timeout) 119003928aee4356845252ac6b662d5c72c29903813eJake Slack while(_contentView.length() == 0 && !(isState(HttpParser.STATE_END)||isState(HttpParser.STATE_SEEKING_EOF)) && _endp!=null && _endp.isOpen()) 119103928aee4356845252ac6b662d5c72c29903813eJake Slack { 119203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_endp.isBlocking()) 119303928aee4356845252ac6b662d5c72c29903813eJake Slack { 119403928aee4356845252ac6b662d5c72c29903813eJake Slack if (parseNext()>0) 119503928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 119603928aee4356845252ac6b662d5c72c29903813eJake Slack 119703928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_endp.blockReadable(maxIdleTime)) 119803928aee4356845252ac6b662d5c72c29903813eJake Slack { 119903928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 120003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new EofException("timeout"); 120103928aee4356845252ac6b662d5c72c29903813eJake Slack } 120203928aee4356845252ac6b662d5c72c29903813eJake Slack } 120303928aee4356845252ac6b662d5c72c29903813eJake Slack 120403928aee4356845252ac6b662d5c72c29903813eJake Slack parseNext(); 120503928aee4356845252ac6b662d5c72c29903813eJake Slack } 120603928aee4356845252ac6b662d5c72c29903813eJake Slack } 120703928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 120803928aee4356845252ac6b662d5c72c29903813eJake Slack { 120903928aee4356845252ac6b662d5c72c29903813eJake Slack // TODO is this needed? 121003928aee4356845252ac6b662d5c72c29903813eJake Slack _endp.close(); 121103928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 121203928aee4356845252ac6b662d5c72c29903813eJake Slack } 121303928aee4356845252ac6b662d5c72c29903813eJake Slack 121403928aee4356845252ac6b662d5c72c29903813eJake Slack return _contentView.length()>0?_contentView:null; 121503928aee4356845252ac6b662d5c72c29903813eJake Slack } 121603928aee4356845252ac6b662d5c72c29903813eJake Slack 121703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 121803928aee4356845252ac6b662d5c72c29903813eJake Slack /* (non-Javadoc) 121903928aee4356845252ac6b662d5c72c29903813eJake Slack * @see java.io.InputStream#available() 122003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 122103928aee4356845252ac6b662d5c72c29903813eJake Slack public int available() throws IOException 122203928aee4356845252ac6b662d5c72c29903813eJake Slack { 122303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_contentView!=null && _contentView.length()>0) 122403928aee4356845252ac6b662d5c72c29903813eJake Slack return _contentView.length(); 122503928aee4356845252ac6b662d5c72c29903813eJake Slack 122603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_endp.isBlocking()) 122703928aee4356845252ac6b662d5c72c29903813eJake Slack { 122803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_state>0 && _endp instanceof StreamEndPoint) 122903928aee4356845252ac6b662d5c72c29903813eJake Slack return ((StreamEndPoint)_endp).getInputStream().available()>0?1:0; 123003928aee4356845252ac6b662d5c72c29903813eJake Slack 123103928aee4356845252ac6b662d5c72c29903813eJake Slack return 0; 123203928aee4356845252ac6b662d5c72c29903813eJake Slack } 123303928aee4356845252ac6b662d5c72c29903813eJake Slack 123403928aee4356845252ac6b662d5c72c29903813eJake Slack parseNext(); 123503928aee4356845252ac6b662d5c72c29903813eJake Slack return _contentView==null?0:_contentView.length(); 123603928aee4356845252ac6b662d5c72c29903813eJake Slack } 123703928aee4356845252ac6b662d5c72c29903813eJake Slack 123803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 123903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 124003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 124103928aee4356845252ac6b662d5c72c29903813eJake Slack public static abstract class EventHandler 124203928aee4356845252ac6b662d5c72c29903813eJake Slack { 124303928aee4356845252ac6b662d5c72c29903813eJake Slack public abstract void content(Buffer ref) throws IOException; 124403928aee4356845252ac6b662d5c72c29903813eJake Slack 124503928aee4356845252ac6b662d5c72c29903813eJake Slack public void headerComplete() throws IOException 124603928aee4356845252ac6b662d5c72c29903813eJake Slack { 124703928aee4356845252ac6b662d5c72c29903813eJake Slack } 124803928aee4356845252ac6b662d5c72c29903813eJake Slack 124903928aee4356845252ac6b662d5c72c29903813eJake Slack public void messageComplete(long contentLength) throws IOException 125003928aee4356845252ac6b662d5c72c29903813eJake Slack { 125103928aee4356845252ac6b662d5c72c29903813eJake Slack } 125203928aee4356845252ac6b662d5c72c29903813eJake Slack 125303928aee4356845252ac6b662d5c72c29903813eJake Slack /** 125403928aee4356845252ac6b662d5c72c29903813eJake Slack * This is the method called by parser when a HTTP Header name and value is found 125503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 125603928aee4356845252ac6b662d5c72c29903813eJake Slack public void parsedHeader(Buffer name, Buffer value) throws IOException 125703928aee4356845252ac6b662d5c72c29903813eJake Slack { 125803928aee4356845252ac6b662d5c72c29903813eJake Slack } 125903928aee4356845252ac6b662d5c72c29903813eJake Slack 126003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 126103928aee4356845252ac6b662d5c72c29903813eJake Slack * This is the method called by parser when the HTTP request line is parsed 126203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 126303928aee4356845252ac6b662d5c72c29903813eJake Slack public abstract void startRequest(Buffer method, Buffer url, Buffer version) 126403928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException; 126503928aee4356845252ac6b662d5c72c29903813eJake Slack 126603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 126703928aee4356845252ac6b662d5c72c29903813eJake Slack * This is the method called by parser when the HTTP request line is parsed 126803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 126903928aee4356845252ac6b662d5c72c29903813eJake Slack public abstract void startResponse(Buffer version, int status, Buffer reason) 127003928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException; 127103928aee4356845252ac6b662d5c72c29903813eJake Slack 127203928aee4356845252ac6b662d5c72c29903813eJake Slack public void earlyEOF() 127303928aee4356845252ac6b662d5c72c29903813eJake Slack {} 127403928aee4356845252ac6b662d5c72c29903813eJake Slack } 127503928aee4356845252ac6b662d5c72c29903813eJake Slack 127603928aee4356845252ac6b662d5c72c29903813eJake Slack 127703928aee4356845252ac6b662d5c72c29903813eJake Slack 127803928aee4356845252ac6b662d5c72c29903813eJake Slack 127903928aee4356845252ac6b662d5c72c29903813eJake Slack} 1280