jetty-9 use DateCache timer to set Date header once per second

This commit is contained in:
Greg Wilkins 2012-12-10 12:58:14 +11:00
parent aeade16b99
commit 6f098dd69c
28 changed files with 104 additions and 78 deletions

View File

@ -60,6 +60,7 @@ public class LikeJettyXml
// Setup Connectors
HttpConnectionFactory http = new HttpConnectionFactory();
http.getHttpConfiguration().setSecurePort(8443);
http.getHttpConfiguration().setSendServerVersion(true);
ServerConnector connector = new ServerConnector(server,http);
connector.setPort(8080);
connector.setIdleTimeout(30000);
@ -119,7 +120,6 @@ public class LikeJettyXml
requestLogHandler.setRequestLog(requestLog);
server.setStopAtShutdown(true);
server.setSendServerVersion(true);
server.start();
server.join();

View File

@ -72,6 +72,7 @@ public class SpdyServer
config.setSecurePort(8443);
config.addCustomizer(new ForwardedRequestCustomizer());
config.addCustomizer(new SecureRequestCustomizer());
config.setSendServerVersion(true);
// Http Connector
@ -160,7 +161,6 @@ public class SpdyServer
requestLogHandler.setRequestLog(requestLog);
server.setStopAtShutdown(true);
server.setSendServerVersion(true);
server.start();
server.dumpStdErr();

View File

@ -113,8 +113,6 @@
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">1000</Set>
</Configure>

View File

@ -225,10 +225,14 @@ public class HttpField
return false;
}
private static class CachedHttpField extends HttpField
/* ------------------------------------------------------------ */
/** A HTTP Field optimised to be reused.
*/
public static class CachedHttpField extends HttpField
{
final byte[] _bytes;
CachedHttpField(HttpHeader header, String value)
public CachedHttpField(HttpHeader header, String value)
{
super(header,value);
_bytes=new byte[header.asString().length()+2+value.length()+2];

View File

@ -76,8 +76,7 @@ public class HttpFields implements Iterable<HttpField>
private static final String[] MONTHS =
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan"};
private static class DateGenerator
public static class DateGenerator
{
private final StringBuilder buf = new StringBuilder(32);
private final GregorianCalendar gc = new GregorianCalendar(__GMT);

View File

@ -49,8 +49,6 @@
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">1000</Set>
<Set name="dumpAfterStart">false</Set>
<Set name="dumpBeforeStop">false</Set>

View File

@ -49,8 +49,6 @@
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">1000</Set>
<Set name="dumpAfterStart">false</Set>
<Set name="dumpBeforeStop">false</Set>

View File

@ -43,8 +43,6 @@
</Set>
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">1000</Set>
</Configure>

View File

@ -274,8 +274,6 @@
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">1000</Set>
</Configure>

View File

@ -449,7 +449,6 @@ public class Runner
if (_server==null)
usage("No Contexts defined");
_server.setStopAtShutdown(true);
_server.setSendServerVersion(true);
switch ((stopPort > 0 ? 1 : 0) + (stopKey != null ? 2 : 0))
{

View File

@ -110,8 +110,6 @@
<!-- extra server options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">5000</Set>
<Set name="dumpAfterStart">false</Set>
<Set name="dumpBeforeStop">false</Set>

View File

@ -320,7 +320,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
@Override
public <T extends ConnectionFactory> T getConnectionFactory(Class<T> factoryType)
public <T> T getConnectionFactory(Class<T> factoryType)
{
synchronized (_factories)
{

View File

@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@ -63,7 +64,7 @@ public interface Connector extends LifeCycle, Graceful
public ConnectionFactory getConnectionFactory(String nextProtocol);
public <T extends ConnectionFactory> T getConnectionFactory(Class<T> factoryType);
public <T> T getConnectionFactory(Class<T> factoryType);
/**
* @return the default {@link ConnectionFactory} associated with the default protocol name
@ -84,5 +85,6 @@ public interface Connector extends LifeCycle, Graceful
* @return the underlying socket, channel, buffer etc. for the connector.
*/
public Object getTransport();
}

View File

@ -494,13 +494,13 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
break;
case HTTP_1_0:
if (getServer().getSendDateHeader())
_response.getHttpFields().putDateField(HttpHeader.DATE.toString(), _request.getTimeStamp());
if (_configuration.getSendDateHeader())
_response.getHttpFields().put(_connector.getServer().getDateField());
break;
case HTTP_1_1:
if (getServer().getSendDateHeader())
_response.getHttpFields().putDateField(HttpHeader.DATE.toString(), _request.getTimeStamp());
if (_configuration.getSendDateHeader())
_response.getHttpFields().put(_connector.getServer().getDateField());
if (_expect)
{

View File

@ -46,6 +46,9 @@ public class HttpConfiguration
private int _responseHeaderSize=8*1024;
private int _securePort;
private String _secureScheme = HttpScheme.HTTPS.asString();
private boolean _sendServerVersion = true; //send Server: header
private boolean _sendDateHeader = false; //send Date: header
public interface Customizer
{
@ -73,6 +76,8 @@ public class HttpConfiguration
_responseHeaderSize=config._responseHeaderSize;
_securePort=config._securePort;
_secureScheme=config._secureScheme;
_sendDateHeader=config._sendDateHeader;
_sendServerVersion=config._sendServerVersion;
}
/* ------------------------------------------------------------ */
@ -131,6 +136,28 @@ public class HttpConfiguration
{
return _secureScheme;
}
public void setSendServerVersion (boolean sendServerVersion)
{
_sendServerVersion = sendServerVersion;
}
@ManagedAttribute("if true, include the server version in HTTP headers")
public boolean getSendServerVersion()
{
return _sendServerVersion;
}
public void setSendDateHeader(boolean sendDateHeader)
{
_sendDateHeader = sendDateHeader;
}
@ManagedAttribute("if true, include the date in HTTP headers")
public boolean getSendDateHeader()
{
return _sendDateHeader;
}
/* ------------------------------------------------------------ */
/**

View File

@ -108,7 +108,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
_connector = connector;
_bufferPool = _connector.getByteBufferPool();
_generator = new HttpGenerator(); // TODO: consider moving the generator to the transport, where it belongs
_generator.setSendServerVersion(getServer().getSendServerVersion());
_generator.setSendServerVersion(_config.getSendServerVersion());
_channel = new HttpChannelOverHttp(connector, config, endPoint, this, new Input());
_parser = newHttpParser();

View File

@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@ -35,6 +36,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
@ -43,6 +46,7 @@ import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.DateCache;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.URIUtil;
@ -73,11 +77,10 @@ public class Server extends HandlerWrapper implements Attributes
private final ThreadPool _threadPool;
private final List<Connector> _connectors = new CopyOnWriteArrayList<>();
private SessionIdManager _sessionIdManager;
private boolean _sendServerVersion = true; //send Server: header
private boolean _sendDateHeader = false; //send Date: header
private boolean _stopAtShutdown;
private boolean _dumpAfterStart=false;
private boolean _dumpBeforeStop=false;
private HttpField _dateField;
/* ------------------------------------------------------------ */
@ -257,6 +260,11 @@ public class Server extends HandlerWrapper implements Attributes
}
/* ------------------------------------------------------------ */
public HttpField getDateField()
{
return _dateField;
}
/* ------------------------------------------------------------ */
@Override
@ -296,6 +304,25 @@ public class Server extends HandlerWrapper implements Attributes
if (isDumpAfterStart())
dumpStdErr();
// use DateCache timer for Date field reformat
final HttpFields.DateGenerator date = new HttpFields.DateGenerator();
long now=System.currentTimeMillis();
long tick=1000*((now/1000)+1)-now;
_dateField=new HttpField.CachedHttpField(HttpHeader.DATE,date.formatDate(now));
DateCache.getTimer().scheduleAtFixedRate(new TimerTask()
{
@Override
public void run()
{
long now=System.currentTimeMillis();
_dateField=new HttpField.CachedHttpField(HttpHeader.DATE,date.formatDate(now));
if (!isRunning())
this.cancel();
}
},tick,1000);
mex.ifExceptionThrow();
}
@ -494,32 +521,6 @@ public class Server extends HandlerWrapper implements Attributes
_sessionIdManager=sessionIdManager;
}
/* ------------------------------------------------------------ */
public void setSendServerVersion (boolean sendServerVersion)
{
_sendServerVersion = sendServerVersion;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("if true, include the server version in HTTP headers")
public boolean getSendServerVersion()
{
return _sendServerVersion;
}
/* ------------------------------------------------------------ */
public void setSendDateHeader(boolean sendDateHeader)
{
_sendDateHeader = sendDateHeader;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("if true, include the date in HTTP headers")
public boolean getSendDateHeader()
{
return _sendDateHeader;
}
/* ------------------------------------------------------------ */
/*
* @see org.eclipse.util.AttributesMap#clearAttributes()

View File

@ -56,10 +56,10 @@ public class NetworkTrafficListenerTest
public void initConnector(Handler handler) throws Exception
{
server = new Server();
server.setSendDateHeader(false);
server.setSendServerVersion(false);
connector = new NetworkTrafficSelectChannelConnector(server);
connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
server.addConnector(connector);
server.setHandler(handler);
server.start();

View File

@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
@ -53,9 +54,9 @@ public class DefaultServletRangesTest
public void init() throws Exception
{
server = new Server();
server.setSendServerVersion(false);
connector = new LocalConnector(server);
connector = new LocalConnector(server);
connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
context = new ServletContextHandler();
context.setContextPath("/context");

View File

@ -33,6 +33,7 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
@ -64,9 +65,9 @@ public class DefaultServletTest
public void init() throws Exception
{
server = new Server();
server.setSendServerVersion(false);
connector = new LocalConnector(server);
connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
context = new ServletContextHandler();
context.setContextPath("/context");

View File

@ -44,6 +44,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
@ -71,8 +72,8 @@ public class DispatcherTest
public void init() throws Exception
{
_server = new Server();
_server.setSendServerVersion(false);
_connector = new LocalConnector(_server);
_connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
_contextCollection = new ContextHandlerCollection();
_contextHandler = new ServletContextHandler();

View File

@ -25,6 +25,7 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.junit.After;
@ -46,9 +47,9 @@ public class InvokerTest
{
_server = new Server();
_connector = new LocalConnector(_server);
_connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
_server.setSendServerVersion(false);
_server.addConnector(_connector);
_server.setHandler(context);

View File

@ -31,8 +31,6 @@
</property>
<property name="stopAtShutdown" value="true"/>
<property name="sendServerVersion" value="true"/>
<property name="sendDateHeader" value="true"/>
<property name="stopTimeout" value="1000"/>
<property name="dumpAfterStart" value="true"/>
<property name="dumpBeforeStop" value="false"/>

View File

@ -60,6 +60,16 @@ public class DateCache
private static Timer __timer;
public static Timer getTimer()
{
synchronized (DateCache.class)
{
if (__timer==null)
__timer=new Timer("DateCache",true);
return __timer;
}
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
private static class Tick
@ -94,11 +104,9 @@ public class DateCache
synchronized (DateCache.class)
{
if (__timer==null)
__timer=new Timer("DateCache@"+Integer.toHexString(hashCode()),true);
Date start = new Date((2+(System.currentTimeMillis()/1000))*1000);
__timer.scheduleAtFixedRate(new TimerTask()
long now=System.currentTimeMillis();
long tick=1000*((now/1000)+1)-now;
getTimer().scheduleAtFixedRate(new TimerTask()
{
@Override
public void run()
@ -106,7 +114,7 @@ public class DateCache
formatNow();
}
},
start,
tick,
1000);
}
}
@ -264,7 +272,7 @@ public class DateCache
}
/* ------------------------------------------------------------ */
private void formatNow()
protected void formatNow()
{
long now = System.currentTimeMillis();
long seconds = now / 1000;

View File

@ -63,8 +63,6 @@
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">1000</Set>
</Configure>

View File

@ -139,8 +139,6 @@
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="stopTimeout">1000</Set>
</Configure>

View File

@ -76,7 +76,6 @@ public class TestServer
// Setup server
Server server = new Server(threadPool);
server.manage(threadPool);
server.setSendDateHeader(true);
// Setup JMX
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
@ -89,6 +88,8 @@ public class TestServer
config.setSecurePort(8443);
config.addCustomizer(new ForwardedRequestCustomizer());
config.addCustomizer(new SecureRequestCustomizer());
config.setSendDateHeader(true);
config.setSendServerVersion(true);
// Http Connector
@ -161,7 +162,6 @@ public class TestServer
requestLogHandler.setRequestLog(requestLog);
server.setStopAtShutdown(true);
server.setSendServerVersion(true);
WebAppContext webapp = new WebAppContext();
webapp.setParentLoaderPriority(true);

View File

@ -62,7 +62,6 @@ public class TestTransparentProxyServer
// Setup server
Server server = new Server(threadPool);
server.manage(threadPool);
server.setSendDateHeader(true);
// Setup JMX
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
@ -75,6 +74,8 @@ public class TestTransparentProxyServer
config.setSecurePort(8443);
config.addCustomizer(new ForwardedRequestCustomizer());
config.addCustomizer(new SecureRequestCustomizer());
config.setSendDateHeader(true);
config.setSendServerVersion(true);
// Http Connector
@ -134,7 +135,6 @@ public class TestTransparentProxyServer
// start server
server.setStopAtShutdown(true);
server.setSendServerVersion(true);
server.start();
server.join();
}