406923 Accept CRLF or LF but not CR as line termination
Fixed lookahead parsing of cached fields
This commit is contained in:
parent
22b0098be7
commit
e6dc08cf97
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue