jetty-9 use direct buffers for generated headers

This commit is contained in:
Greg Wilkins 2012-12-14 11:30:55 +11:00
parent a9247d6617
commit ecf7563a79
8 changed files with 142 additions and 20 deletions

View File

@ -39,6 +39,7 @@ public class HttpField
{
CACHE.put(new CachedHttpField(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE));
CACHE.put(new CachedHttpField(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE));
CACHE.put(new CachedHttpField(HttpHeader.CONNECTION,HttpHeaderValue.UPGRADE));
CACHE.put(new CachedHttpField(HttpHeader.ACCEPT_ENCODING,"gzip, deflate"));
CACHE.put(new CachedHttpField(HttpHeader.ACCEPT_LANGUAGE,"en-US,en;q=0.5"));
CACHE.put(new CachedHttpField(HttpHeader.ACCEPT,"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"));

View File

@ -648,7 +648,6 @@ public class HttpGenerator
connection.append(split==null?field.getValue():split[i]);
}
}
}
// Do NOT add yet!
@ -666,15 +665,7 @@ public class HttpGenerator
}
default:
if (h==null)
field.putTo(header);
else
{
header.put(h.getBytesColonSpace());
field.putValueTo(header);
header.put(CRLF);
}
field.putTo(header);
}
}
}

View File

@ -716,10 +716,11 @@ public class HttpParser
}
else
{
if (buffer.remaining()>6 && buffer.hasArray())
if (buffer.remaining()>6)
{
// Try a look ahead for the known header name and value.
_field=HttpField.CACHE.getBest(buffer.array(),buffer.arrayOffset()+buffer.position()-1,buffer.remaining()+1);
_field=HttpField.CACHE.getBest(buffer,-1,buffer.remaining());
//_field=HttpField.CACHE.getBest(buffer.array(),buffer.arrayOffset()+buffer.position()-1,buffer.remaining()+1);
if (_field!=null)
{
_header=_field.getHeader();
@ -742,7 +743,8 @@ public class HttpParser
}
// Try a look ahead for the known header name.
_header=HttpHeader.CACHE.getBest(buffer.array(),buffer.arrayOffset()+buffer.position()-1,buffer.remaining()+1);
_header=HttpHeader.CACHE.getBest(buffer,-1,buffer.remaining());
//_header=HttpHeader.CACHE.getBest(buffer.array(),buffer.arrayOffset()+buffer.position()-1,buffer.remaining()+1);
if (_header!=null)
{
_headerString=_header.asString();

View File

@ -146,6 +146,59 @@ public class HttpParserTest
assertEquals(-1, _h);
}
@Test
public void testHeaderParseDirect() throws Exception
{
ByteBuffer b0= BufferUtil.toBuffer(
"GET / HTTP/1.0\015\012" +
"Host: localhost\015\012" +
"Header1: value1\015\012" +
"Header 2 : value 2a \015\012" +
" value 2b \015\012" +
"Header3: \015\012" +
"Header4 \015\012" +
" value4\015\012" +
"Server5 : notServer\015\012" +
"Host Header: notHost\015\012" +
"Connection: close\015\012" +
"Accept-Encoding: gzip, deflated\015\012" +
"Accept: unknown\015\012" +
"\015\012");
ByteBuffer buffer = BufferUtil.allocateDirect(b0.capacity());
int pos=BufferUtil.flipToFill(buffer);
BufferUtil.put(b0,buffer);
BufferUtil.flipToFlush(buffer,pos);
Handler handler = new Handler();
HttpParser parser= new HttpParser((HttpParser.RequestHandler)handler);
parseAll(parser,buffer);
assertEquals("GET", _methodOrVersion);
assertEquals("/", _uriOrStatus);
assertEquals("HTTP/1.0", _versionOrReason);
assertEquals("Host", _hdr[0]);
assertEquals("localhost", _val[0]);
assertEquals("Header1", _hdr[1]);
assertEquals("value1", _val[1]);
assertEquals("Header 2", _hdr[2]);
assertEquals("value 2a value 2b", _val[2]);
assertEquals("Header3", _hdr[3]);
assertEquals(null, _val[3]);
assertEquals("Header4", _hdr[4]);
assertEquals("value4", _val[4]);
assertEquals("Server5", _hdr[5]);
assertEquals("notServer", _val[5]);
assertEquals("Host Header", _hdr[6]);
assertEquals("notHost", _val[6]);
assertEquals("Connection", _hdr[7]);
assertEquals("close", _val[7]);
assertEquals("Accept-Encoding", _hdr[8]);
assertEquals("gzip, deflated", _val[8]);
assertEquals("Accept", _hdr[9]);
assertEquals("unknown", _val[9]);
assertEquals(9, _h);
}
@Test
public void testHeaderParseCRLF() throws Exception
{

View File

@ -50,7 +50,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
public static final String UPGRADE_CONNECTION_ATTRIBUTE = "org.eclipse.jetty.server.HttpConnection.UPGRADE";
private static final boolean REQUEST_BUFFER_DIRECT=false;
private static final boolean HEADER_BUFFER_DIRECT=false;
private static final boolean HEADER_BUFFER_DIRECT=true;
private static final boolean CHUNK_BUFFER_DIRECT=false;
private static final Logger LOG = Log.getLogger(HttpConnection.class);
private static final ThreadLocal<HttpConnection> __currentConnection = new ThreadLocal<>();

View File

@ -677,11 +677,29 @@ public class BufferUtil
{
return ByteBuffer.wrap(s.getBytes(StringUtil.__ISO_8859_1_CHARSET));
}
public static ByteBuffer toDirectBuffer(String s)
{
byte[] bytes=s.getBytes(StringUtil.__ISO_8859_1_CHARSET);
ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length);
buf.put(bytes);
buf.flip();
return buf;
}
public static ByteBuffer toBuffer(String s, Charset charset)
{
return ByteBuffer.wrap(s.getBytes(charset));
}
public static ByteBuffer toDirectBuffer(String s, Charset charset)
{
byte[] bytes=s.getBytes(charset);
ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length);
buf.put(bytes);
buf.flip();
return buf;
}
/**
* Create a new ByteBuffer using provided byte array.

View File

@ -217,15 +217,16 @@ public class Trie<V>
{
if (b.hasArray())
return getBest(b.array(),b.arrayOffset()+b.position()+offset,len);
return doGetBest(b,offset,len);
return getBestByteBuffer(b,offset,len);
}
private V doGetBest(ByteBuffer b,int offset,int len)
private V getBestByteBuffer(ByteBuffer b,int offset,int len)
{
Trie<V> t = this;
int pos=b.position()+offset;
for(int i=0; i < len; i++)
{
byte c=b.get(offset+i);
byte c=b.get(pos++);
int index=c>=0&&c<0x7f?__lookup[c]:-1;
if (index>=0)
{

View File

@ -89,9 +89,48 @@ public class TrieTest
Assert.assertEquals(null,trie.get(BufferUtil.toBuffer("xBlahx"),1,4));
}
@Test
public void testGetDirectBuffer() throws Exception
{
Assert.assertEquals(1,trie.get(BufferUtil.toDirectBuffer("xhellox"),1,5).intValue());
Assert.assertEquals(2,trie.get(BufferUtil.toDirectBuffer("xhellox"),1,2).intValue());
Assert.assertEquals(3,trie.get(BufferUtil.toDirectBuffer("xhellox"),1,4).intValue());
Assert.assertEquals(4,trie.get(BufferUtil.toDirectBuffer("wibble"),0,6).intValue());
Assert.assertEquals(5,trie.get(BufferUtil.toDirectBuffer("xWobble"),1,6).intValue());
Assert.assertEquals(6,trie.get(BufferUtil.toDirectBuffer("xfoo-barx"),1,7).intValue());
Assert.assertEquals(7,trie.get(BufferUtil.toDirectBuffer("xfoo+barx"),1,7).intValue());
Assert.assertEquals(1,trie.get(BufferUtil.toDirectBuffer("xhellox"),1,5).intValue());
Assert.assertEquals(2,trie.get(BufferUtil.toDirectBuffer("xHELLox"),1,2).intValue());
Assert.assertEquals(3,trie.get(BufferUtil.toDirectBuffer("xhellox"),1,4).intValue());
Assert.assertEquals(4,trie.get(BufferUtil.toDirectBuffer("Wibble"),0,6).intValue());
Assert.assertEquals(5,trie.get(BufferUtil.toDirectBuffer("xwobble"),1,6).intValue());
Assert.assertEquals(6,trie.get(BufferUtil.toDirectBuffer("xFOO-barx"),1,7).intValue());
Assert.assertEquals(7,trie.get(BufferUtil.toDirectBuffer("xFOO+barx"),1,7).intValue());
Assert.assertEquals(null,trie.get(BufferUtil.toDirectBuffer("xHelpx"),1,4));
Assert.assertEquals(null,trie.get(BufferUtil.toDirectBuffer("xBlahx"),1,4));
}
@Test
public void testGetBest() throws Exception
public void testGetBestArray() throws Exception
{
Assert.assertEquals(1,trie.getBest(StringUtil.getUtf8Bytes("xhelloxxxx"),1,10).intValue());
Assert.assertEquals(2,trie.getBest(StringUtil.getUtf8Bytes("xhelxoxxxx"),1,10).intValue());
Assert.assertEquals(3,trie.getBest(StringUtil.getUtf8Bytes("xhellxxxxx"),1,10).intValue());
Assert.assertEquals(6,trie.getBest(StringUtil.getUtf8Bytes("xfoo-barxx"),1,10).intValue());
Assert.assertEquals(8,trie.getBest(StringUtil.getUtf8Bytes("xhell4xxxx"),1,10).intValue());
Assert.assertEquals(1,trie.getBest(StringUtil.getUtf8Bytes("xHELLOxxxx"),1,10).intValue());
Assert.assertEquals(2,trie.getBest(StringUtil.getUtf8Bytes("xHELxoxxxx"),1,10).intValue());
Assert.assertEquals(3,trie.getBest(StringUtil.getUtf8Bytes("xHELLxxxxx"),1,10).intValue());
Assert.assertEquals(6,trie.getBest(StringUtil.getUtf8Bytes("xfoo-BARxx"),1,10).intValue());
Assert.assertEquals(8,trie.getBest(StringUtil.getUtf8Bytes("xHELL4xxxx"),1,10).intValue());
}
@Test
public void testGetBestBuffer() throws Exception
{
Assert.assertEquals(1,trie.getBest(BufferUtil.toBuffer("xhelloxxxx"),1,10).intValue());
Assert.assertEquals(2,trie.getBest(BufferUtil.toBuffer("xhelxoxxxx"),1,10).intValue());
@ -108,6 +147,23 @@ public class TrieTest
ByteBuffer buffer = (ByteBuffer)BufferUtil.toBuffer("xhelloxxxxxxx").position(2);
Assert.assertEquals(1,trie.getBest(buffer,-1,10).intValue());
}
@Test
public void testGetBestDirectBuffer() throws Exception
{
Assert.assertEquals(1,trie.getBest(BufferUtil.toDirectBuffer("xhelloxxxx"),1,10).intValue());
Assert.assertEquals(2,trie.getBest(BufferUtil.toDirectBuffer("xhelxoxxxx"),1,10).intValue());
Assert.assertEquals(3,trie.getBest(BufferUtil.toDirectBuffer("xhellxxxxx"),1,10).intValue());
Assert.assertEquals(6,trie.getBest(BufferUtil.toDirectBuffer("xfoo-barxx"),1,10).intValue());
Assert.assertEquals(8,trie.getBest(BufferUtil.toDirectBuffer("xhell4xxxx"),1,10).intValue());
Assert.assertEquals(1,trie.getBest(BufferUtil.toDirectBuffer("xHELLOxxxx"),1,10).intValue());
Assert.assertEquals(2,trie.getBest(BufferUtil.toDirectBuffer("xHELxoxxxx"),1,10).intValue());
Assert.assertEquals(3,trie.getBest(BufferUtil.toDirectBuffer("xHELLxxxxx"),1,10).intValue());
Assert.assertEquals(6,trie.getBest(BufferUtil.toDirectBuffer("xfoo-BARxx"),1,10).intValue());
Assert.assertEquals(8,trie.getBest(BufferUtil.toDirectBuffer("xHELL4xxxx"),1,10).intValue());
ByteBuffer buffer = (ByteBuffer)BufferUtil.toDirectBuffer("xhelloxxxxxxx").position(2);
Assert.assertEquals(1,trie.getBest(buffer,-1,10).intValue());
}
}