406923 Accept CRLF or LF but not CR as line termination

Fixed lookahead parsing of cached fields
This commit is contained in:
Greg Wilkins 2013-05-02 14:49:46 +10:00
parent 22b0098be7
commit e6dc08cf97
3 changed files with 67 additions and 10 deletions

View File

@ -217,6 +217,11 @@ public class HttpParser
badMessage(buffer,400,"Bad EOL");
return -1;
}
/*
if (ch>HttpTokens.SPACE)
System.err.println("Next "+(char)ch);
else
System.err.println("Next ["+ch+"]");*/
return ch;
}
@ -260,6 +265,12 @@ public class HttpParser
return -1;
}
/*
if (ch>HttpTokens.SPACE)
System.err.println("Next "+(char)ch);
else
System.err.println("Next ["+ch+"]");
*/
return ch;
}
@ -575,7 +586,7 @@ public class HttpParser
}
// Should we try to cache header fields?
if (_version.getVersion()>=HttpVersion.HTTP_1_1.getVersion())
if (_connectionFields==null && _version.getVersion()>=HttpVersion.HTTP_1_1.getVersion())
{
int header_cache = _handler.getHeaderCacheSize();
if (header_cache>0)
@ -868,7 +879,7 @@ public class HttpParser
}
else
{
if (buffer.remaining()>6)
if (buffer.hasRemaining())
{
// Try a look ahead for the known header name and value.
HttpField field=_connectionFields==null?null:_connectionFields.getBest(buffer,-1,buffer.remaining());
@ -883,14 +894,12 @@ public class HttpParser
if (v==null)
{
// Header only
int pos=buffer.position()+n.length()+1;
byte b=buffer.get(pos);
_header=field.getHeader();
_headerString=n;
setState(State.HEADER_VALUE);
_string.setLength(0);
_length=0;
buffer.position(pos);
buffer.position(buffer.position()+n.length()+1);
break;
}
else
@ -949,8 +958,6 @@ public class HttpParser
{
_headerString=takeLengthString();
_header=HttpHeader.CACHE.get(_headerString);
if (_header!=null)
System.err.println(_header);
}
setState(State.HEADER_VALUE);
break;
@ -1505,5 +1512,9 @@ public class HttpParser
public abstract boolean startResponse(HttpVersion version, int status, String reason);
}
public Trie<HttpField> getFieldCache()
{
return _connectionFields;
}
}

View File

@ -23,6 +23,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.http.HttpParser.State;
import org.eclipse.jetty.util.BufferUtil;
@ -261,6 +263,8 @@ public class HttpParserTest
assertEquals(9, _h);
}
@Test
public void testHeaderParseLF() throws Exception
{
@ -332,7 +336,7 @@ public class HttpParserTest
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser parser= new HttpParser(handler);
System.err.println(BufferUtil.toDetailString(buffer));
// System.err.println(BufferUtil.toDetailString(buffer));
buffer.position(2);
buffer.limit(2+i);
@ -989,6 +993,28 @@ public class HttpParserTest
assertEquals(8888,_port);
}
@Test
public void testCachedField() throws Exception
{
ByteBuffer buffer= BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n"+
"Host: www.smh.com.au\r\n"+
"\r\n");
HttpParser.RequestHandler<ByteBuffer> handler = new Handler();
HttpParser parser= new HttpParser(handler);
parseAll(parser,buffer);
assertEquals("www.smh.com.au",parser.getFieldCache().get("Host: www.smh.com.au").getValue());
HttpField field=_fields.get(0);
//System.err.println(parser.getFieldCache());
buffer.position(0);
parseAll(parser,buffer);
assertTrue(field==_fields.get(0));
}
@Before
public void init()
{
@ -1011,6 +1037,7 @@ public class HttpParserTest
private String _methodOrVersion;
private String _uriOrStatus;
private String _versionOrReason;
private List<HttpField> _fields=new ArrayList<>();
private String[] _hdr;
private String[] _val;
private int _h;
@ -1038,6 +1065,7 @@ public class HttpParserTest
@Override
public boolean startRequest(HttpMethod httpMethod, String method, ByteBuffer uri, HttpVersion version)
{
_fields.clear();
request=true;
_h= -1;
_hdr= new String[10];
@ -1055,6 +1083,7 @@ public class HttpParserTest
@Override
public boolean parsedHeader(HttpField field)
{
_fields.add(field);
//System.err.println("header "+name+": "+value);
_hdr[++_h]= field.getName();
_val[_h]= field.getValue();
@ -1102,6 +1131,7 @@ public class HttpParserTest
@Override
public boolean startResponse(HttpVersion version, int status, String reason)
{
_fields.clear();
request=false;
_methodOrVersion = version.asString();
_uriOrStatus = Integer.toString(status);

View File

@ -131,8 +131,6 @@ public class ArrayTernaryTrie<V> extends AbstractTrie<V>
_tree[row]=c;
_tree[last]=(char)t;
last=row+EQ;
t=0;
break;
}
int row=ROW_SIZE*t;
@ -419,4 +417,22 @@ public class ArrayTernaryTrie<V> extends AbstractTrie<V>
{
return _rows+1==_key.length;
}
public void dump()
{
for (int r=0;r<=_rows;r++)
{
char c=_tree[r*ROW_SIZE+0];
System.err.printf("%4d [%s,%d,%d,%d] %s:%s%n",
r,
(c<' '||c>127)?(""+(int)c):"'"+c+"'",
(int)_tree[r*ROW_SIZE+LO],
(int)_tree[r*ROW_SIZE+EQ],
(int)_tree[r*ROW_SIZE+HI],
_key[r],
_value[r]);
}
}
}