402075 Dont allocate the parser trie unless needed

This commit is contained in:
Greg Wilkins 2013-03-01 22:16:54 +11:00
parent 718ee4ddeb
commit 41952ebf1d
9 changed files with 83 additions and 6 deletions

View File

@ -127,6 +127,14 @@ public class HttpReceiver implements HttpParser.ResponseHandler<ByteBuffer>
}
}
@Override
public int getHeaderCacheSize()
{
// TODO get from configuration
return 256;
}
@Override
public boolean startResponse(HttpVersion version, int status, String reason)
{

View File

@ -34,6 +34,7 @@ import org.eclipse.jetty.util.log.Logger;
public class HttpParser
{
public static final Logger LOG = Log.getLogger(HttpParser.class);
private static final int INITIAL_URI_LENGTH=256;
// States
public enum State
@ -80,7 +81,7 @@ public class HttpParser
private HttpMethod _method;
private String _methodString;
private HttpVersion _version;
private ByteBuffer _uri=ByteBuffer.allocate(256); // Tune?
private ByteBuffer _uri=ByteBuffer.allocate(INITIAL_URI_LENGTH); // Tune?
private byte _eol;
private EndOfContent _endOfContent;
private long _contentLength;
@ -89,7 +90,7 @@ public class HttpParser
private int _chunkPosition;
private boolean _headResponse;
private ByteBuffer _contentChunk;
private final Trie<HttpField> _connectionFields=new ArrayTernaryTrie<>(256);
private Trie<HttpField> _connectionFields;
private int _length;
private final StringBuilder _string=new StringBuilder();
@ -513,6 +514,14 @@ public class HttpParser
return true;
}
// Should we try to cache header fields?
if (_version.getVersion()>=HttpVersion.HTTP_1_1.getVersion())
{
int header_cache = _handler.getHeaderCacheSize();
if (header_cache>0)
_connectionFields=new ArrayTernaryTrie<>(header_cache);
}
_eol=ch;
setState(State.HEADER);
_uri.flip();
@ -592,7 +601,7 @@ public class HttpParser
break;
case HOST:
add_to_connection_trie=_field==null;
add_to_connection_trie=_connectionFields!=null && _field==null;
_host=true;
String host=_valueString;
int port=0;
@ -630,6 +639,12 @@ public class HttpParser
break;
case CONNECTION:
// Don't cache if not persistent
if (_valueString!=null && _valueString.indexOf("close")>=0)
_connectionFields=null;
break;
case AUTHORIZATION:
case ACCEPT:
case ACCEPT_CHARSET:
@ -638,7 +653,7 @@ public class HttpParser
case COOKIE:
case CACHE_CONTROL:
case USER_AGENT:
add_to_connection_trie=_field==null;
add_to_connection_trie=_connectionFields!=null && _field==null;
}
if (add_to_connection_trie && !_connectionFields.isFull() && _header!=null && _valueString!=null)
@ -786,7 +801,7 @@ public class HttpParser
if (buffer.remaining()>6)
{
// Try a look ahead for the known header name and value.
_field=_connectionFields.getBest(buffer,-1,buffer.remaining());
_field=_connectionFields==null?null:_connectionFields.getBest(buffer,-1,buffer.remaining());
if (_field==null)
_field=HttpField.CACHE.getBest(buffer,-1,buffer.remaining());
@ -1396,6 +1411,11 @@ public class HttpParser
public boolean earlyEOF();
public void badMessage(int status, String reason);
/* ------------------------------------------------------------ */
/** @return the size in bytes of the per parser header cache
*/
public int getHeaderCacheSize();
}
public interface RequestHandler<T> extends HttpHandler<T>

View File

@ -229,6 +229,12 @@ public class HttpTester
}
abstract public HttpGenerator.Info getInfo();
@Override
public int getHeaderCacheSize()
{
return 0;
}
}
public static class Request extends Message implements HttpParser.RequestHandler<ByteBuffer>

View File

@ -91,6 +91,12 @@ public class HttpGeneratorServerTest
{
throw new IllegalStateException(reason);
}
@Override
public int getHeaderCacheSize()
{
return 256;
}
}
private static class TR

View File

@ -926,5 +926,11 @@ public class HttpParserTest
{
return true;
}
@Override
public int getHeaderCacheSize()
{
return 512;
}
}
}

View File

@ -82,6 +82,7 @@
<Set name="responseHeaderSize">8192</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">false</Set>
<Set name="headerCacheSize">512</Set>
<!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">

View File

@ -167,6 +167,12 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
return _endPoint.getRemoteAddress();
}
@Override
public int getHeaderCacheSize()
{
return _configuration.getHeaderCacheSize();
}
/**
* If the associated response has the Expect header set to 100 Continue,
* then accessing the input stream indicates that the handler/servlet

View File

@ -44,6 +44,7 @@ public class HttpConfiguration
private int _outputBufferSize=32*1024;
private int _requestHeaderSize=8*1024;
private int _responseHeaderSize=8*1024;
private int _headerCacheSize=512;
private int _securePort;
private String _secureScheme = HttpScheme.HTTPS.asString();
private boolean _sendServerVersion = true; //send Server: header
@ -78,6 +79,7 @@ public class HttpConfiguration
_secureScheme=config._secureScheme;
_sendDateHeader=config._sendDateHeader;
_sendServerVersion=config._sendServerVersion;
_headerCacheSize=config._headerCacheSize;
}
/* ------------------------------------------------------------ */
@ -125,6 +127,12 @@ public class HttpConfiguration
return _responseHeaderSize;
}
@ManagedAttribute("The maximum allowed size in bytes for a HTTP header field cache")
public int getHeaderCacheSize()
{
return _headerCacheSize;
}
@ManagedAttribute("The port to which Integral or Confidential security constraints are redirected")
public int getSecurePort()
{
@ -210,6 +218,15 @@ public class HttpConfiguration
_responseHeaderSize = responseHeaderSize;
}
/* ------------------------------------------------------------ */
/** Set the header field cache size.
* @param headerCacheSize The size in bytes of the header field cache.
*/
public void setHeaderCacheSize(int headerCacheSize)
{
_headerCacheSize = headerCacheSize;
}
/* ------------------------------------------------------------ */
/** Set the TCP/IP port used for CONFIDENTIAL and INTEGRAL
* redirections.

View File

@ -150,6 +150,13 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
return false;
}
@Override
public int getHeaderCacheSize()
{
// TODO get from configuration
return 256;
}
@Override
public boolean earlyEOF()
{