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

View File

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

View File

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

View File

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

View File

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

View File

@ -167,6 +167,12 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
return _endPoint.getRemoteAddress(); return _endPoint.getRemoteAddress();
} }
@Override
public int getHeaderCacheSize()
{
return _configuration.getHeaderCacheSize();
}
/** /**
* If the associated response has the Expect header set to 100 Continue, * If the associated response has the Expect header set to 100 Continue,
* then accessing the input stream indicates that the handler/servlet * 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 _outputBufferSize=32*1024;
private int _requestHeaderSize=8*1024; private int _requestHeaderSize=8*1024;
private int _responseHeaderSize=8*1024; private int _responseHeaderSize=8*1024;
private int _headerCacheSize=512;
private int _securePort; private int _securePort;
private String _secureScheme = HttpScheme.HTTPS.asString(); private String _secureScheme = HttpScheme.HTTPS.asString();
private boolean _sendServerVersion = true; //send Server: header private boolean _sendServerVersion = true; //send Server: header
@ -78,6 +79,7 @@ public class HttpConfiguration
_secureScheme=config._secureScheme; _secureScheme=config._secureScheme;
_sendDateHeader=config._sendDateHeader; _sendDateHeader=config._sendDateHeader;
_sendServerVersion=config._sendServerVersion; _sendServerVersion=config._sendServerVersion;
_headerCacheSize=config._headerCacheSize;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -125,6 +127,12 @@ public class HttpConfiguration
return _responseHeaderSize; 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") @ManagedAttribute("The port to which Integral or Confidential security constraints are redirected")
public int getSecurePort() public int getSecurePort()
{ {
@ -210,6 +218,15 @@ public class HttpConfiguration
_responseHeaderSize = responseHeaderSize; _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 /** Set the TCP/IP port used for CONFIDENTIAL and INTEGRAL
* redirections. * redirections.

View File

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