Merge branch 'jetty-9.2.x'

Conflicts:
	jetty-server/src/main/config/etc/jetty.xml
	jetty-server/src/main/config/modules/server.mod
	jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
	jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
	jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java
	jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
This commit is contained in:
Joakim Erdfelt 2014-11-25 12:09:09 -07:00
commit ed594425d3
10 changed files with 203 additions and 44 deletions

View File

@ -30,7 +30,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@ -104,7 +103,7 @@ public class ProxyServletFailureTest
proxy = new Server(executor);
proxyConnector = new ServerConnector(proxy);
proxy.addConnector(proxyConnector);
proxyConnector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setDelayDispatchOnContent(false);
proxyConnector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setDelayDispatchUntilContent(false);
ServletContextHandler proxyCtx = new ServletContextHandler(proxy, "/", true, false);
ServletHolder proxyServletHolder = new ServletHolder(proxyServlet);

View File

@ -80,12 +80,13 @@
<Set name="secureScheme">https</Set>
<Set name="securePort"><Property name="jetty.secure.port" default="8443" /></Set>
<Set name="outputBufferSize"><Property name="jetty.output.buffer.size" default="32768" /></Set>
<Set name="outputAggregationSize"><Property name="jetty.output.aggregation.size" default="8192" /></Set>
<Set name="requestHeaderSize"><Property name="jetty.request.header.size" default="8192" /></Set>
<Set name="responseHeaderSize"><Property name="jetty.response.header.size" default="8192" /></Set>
<Set name="sendServerVersion"><Property name="jetty.send.server.version" default="true" /></Set>
<Set name="sendDateHeader"><Property name="jetty.send.date.header" default="false" /></Set>
<Set name="headerCacheSize">512</Set>
<Set name="delayDispatchOnContent"><Property name="jetty.delayDispatchOnContent" default="true"/></Set>
<Set name="delayDispatchUntilContent"><Property name="jetty.delayDispatchUntilContent" default="false"/></Set>
<!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>

View File

@ -46,4 +46,4 @@ jetty.dump.start=false
# Dump the state of the Jetty server, before stop
jetty.dump.stop=false
# Enable delayed dispatch optimisation
jetty.delayDispatchOnContent=true
jetty.delayDispatchUntilContent=false

View File

@ -114,6 +114,8 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
_request = new Request(this, input);
_response = new Response(this, new HttpOutput(this));
_requestLog=_connector==null?null:_connector.getServer().getRequestLog();
if (LOG.isDebugEnabled())
LOG.debug("new {} -> {},{},{}",this,_endPoint,_endPoint.getConnection(),_state);
}
public HttpChannelState getState()

View File

@ -297,7 +297,7 @@ class HttpChannelOverHttp extends HttpChannel implements HttpParser.RequestHandl
// Should we delay dispatch until we have some content?
// We should not delay if there is no content expect or client is expecting 100 or the response is already committed or the request buffer already has something in it to parse
if (getHttpConfiguration().isDelayDispatchOnContent() && _httpConnection.getParser().getContentLength()>0 && !isExpecting100Continue() && !isCommitted() && _httpConnection.isRequestBufferEmpty())
if (getHttpConfiguration().isDelayDispatchUntilContent() && _httpConnection.getParser().getContentLength()>0 && !isExpecting100Continue() && !isCommitted() && _httpConnection.isRequestBufferEmpty())
return false;
return true;

View File

@ -45,17 +45,17 @@ public class HttpConfiguration
private List<Customizer> _customizers=new CopyOnWriteArrayList<>();
private int _outputBufferSize=32*1024;
private int _outputAggregationSize=_outputBufferSize/4;
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
private boolean _sendXPoweredBy = false; //send X-Powered-By: header
private boolean _sendDateHeader = true; //send Date: header
private boolean _delayDispatchOnContent = true; // Don't dispatch until content arrives
private boolean _sendServerVersion = true;
private boolean _sendXPoweredBy = false;
private boolean _sendDateHeader = true;
private boolean _delayDispatchUntilContent = false;
/* ------------------------------------------------------------ */
/**
* <p>An interface that allows a request object to be customized
@ -94,6 +94,7 @@ public class HttpConfiguration
{
_customizers.addAll(config._customizers);
_outputBufferSize=config._outputBufferSize;
_outputAggregationSize=config._outputAggregationSize;
_requestHeaderSize=config._requestHeaderSize;
_responseHeaderSize=config._responseHeaderSize;
_securePort=config._securePort;
@ -138,6 +139,13 @@ public class HttpConfiguration
return _outputBufferSize;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("The maximum size in bytes for HTTP output to be aggregated")
public int getOutputAggregationSize()
{
return _outputAggregationSize;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("The maximum allowed size in bytes for a HTTP request header")
public int getRequestHeaderSize()
@ -211,31 +219,30 @@ public class HttpConfiguration
{
return _sendDateHeader;
}
/* ------------------------------------------------------------ */
/**
* @param delay if true, delay the application dispatch until content is available
*/
public void setDelayDispatchOnContent(boolean delay)
public void setDelayDispatchUntilContent(boolean delay)
{
_delayDispatchOnContent=delay;
_delayDispatchUntilContent = delay;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("if true, delay the application dispatch until content is available")
public boolean isDelayDispatchOnContent()
public boolean isDelayDispatchUntilContent()
{
return _delayDispatchOnContent;
return _delayDispatchUntilContent;
}
/* ------------------------------------------------------------ */
/**
* <p>Set the {@link Customizer}s that are invoked for every
* request received.</p>
* <p>Customisers are often used to interpret optional headers (eg {@link ForwardedRequestCustomizer}) or
* <p>Customizers are often used to interpret optional headers (eg {@link ForwardedRequestCustomizer}) or
* optional protocol semantics (eg {@link SecureRequestCustomizer}).
* @param customizers
* @param customizers the list of customizers
*/
public void setCustomizers(List<Customizer> customizers)
{
@ -256,6 +263,19 @@ public class HttpConfiguration
_outputBufferSize = responseBufferSize;
}
/* ------------------------------------------------------------ */
/**
* Set the max size of the response content write that is copied into the aggregate buffer.
* Writes that are smaller of this size are copied into the aggregate buffer, while
* writes that are larger of this size will cause the aggregate buffer to be flushed
* and the write to be executed without being copied.
* @param outputAggregationSize the max write size that is aggregated
*/
public void setOutputAggregationSize(int outputAggregationSize)
{
_outputAggregationSize = outputAggregationSize;
}
/* ------------------------------------------------------------ */
/** Set the maximum size of a request header.
* <p>Larger headers will allow for more and/or larger cookies plus larger form content encoded
@ -290,28 +310,32 @@ public class HttpConfiguration
}
/* ------------------------------------------------------------ */
/** Set the TCP/IP port used for CONFIDENTIAL and INTEGRAL
* redirections.
* @param confidentialPort
/** Set the TCP/IP port used for CONFIDENTIAL and INTEGRAL redirections.
* @param securePort the secure port to redirect to.
*/
public void setSecurePort(int confidentialPort)
public void setSecurePort(int securePort)
{
_securePort = confidentialPort;
_securePort = securePort;
}
/* ------------------------------------------------------------ */
/** Set the URI scheme used for CONFIDENTIAL and INTEGRAL
* redirections.
* @param confidentialScheme A string like"https"
/** Set the URI scheme used for CONFIDENTIAL and INTEGRAL redirections.
* @param secureScheme A scheme string like "https"
*/
public void setSecureScheme(String confidentialScheme)
public void setSecureScheme(String secureScheme)
{
_secureScheme = confidentialScheme;
_secureScheme = secureScheme;
}
@Override
public String toString()
{
return String.format("%s@%x{%d,%d/%d,%s://:%d,%s}",this.getClass().getSimpleName(),hashCode(),_outputBufferSize,_requestHeaderSize,_responseHeaderSize,_secureScheme,_securePort,_customizers);
return String.format("%s@%x{%d/%d,%d/%d,%s://:%d,%s}",
this.getClass().getSimpleName(),
hashCode(),
_outputBufferSize, _outputAggregationSize,
_requestHeaderSize,_responseHeaderSize,
_secureScheme,_securePort,
_customizers);
}
}

View File

@ -99,8 +99,9 @@ public class HttpOutput extends ServletOutputStream implements Runnable
return _channel.getIdleTimeout();
}
};
_bufferSize = _channel.getHttpConfiguration().getOutputBufferSize();
_commitSize=_bufferSize/4;
HttpConfiguration config = channel.getHttpConfiguration();
_bufferSize = config.getOutputBufferSize();
_commitSize = config.getOutputAggregationSize();
}
public HttpChannel getHttpChannel()

View File

@ -497,7 +497,7 @@ public class Server extends HandlerWrapper implements Attributes
final Response response=connection.getResponse();
if (LOG.isDebugEnabled())
LOG.debug(request.getDispatcherType()+" "+target+" on "+connection);
LOG.debug(request.getDispatcherType()+" "+request.getMethod()+" "+target+" on "+connection);
if ("*".equals(target))
{

View File

@ -18,16 +18,6 @@
package org.eclipse.jetty.server;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -41,7 +31,6 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.Exchanger;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
@ -59,6 +48,16 @@ import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
*
*/
@ -1278,7 +1277,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
{
AvailableHandler ah = new AvailableHandler();
configureServer(ah);
_connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setDelayDispatchOnContent(false);
_connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setDelayDispatchUntilContent(false);
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
{

View File

@ -33,6 +33,7 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
public class XmlConfigurationTest
@ -646,4 +647,136 @@ public class XmlConfigurationTest
Assert.assertEquals("nested second parameter not wired correctly","arg2", atc.getNested().getSecond());
Assert.assertEquals("nested third parameter not wired correctly","arg3", atc.getNested().getThird());
}
public static class NativeHolder
{
private boolean _boolean;
private int _integer;
private float _float;
public boolean getBoolean()
{
return _boolean;
}
public void setBoolean(boolean value)
{
this._boolean = value;
}
public int getInteger()
{
return _integer;
}
public void setInteger(int integer)
{
_integer = integer;
}
public float getFloat()
{
return _float;
}
public void setFloat(float f)
{
_float = f;
}
}
@Test
public void testSetBooleanTrue() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.XmlConfigurationTest$NativeHolder\">" +
" <Set name=\"boolean\">true</Set>" +
"</Configure>");
NativeHolder bh = (NativeHolder)xmlConfiguration.configure();
Assert.assertTrue(bh.getBoolean());
}
@Test
public void testSetBooleanFalse() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.XmlConfigurationTest$NativeHolder\">" +
" <Set name=\"boolean\">false</Set>" +
"</Configure>");
NativeHolder bh = (NativeHolder)xmlConfiguration.configure();
Assert.assertFalse(bh.getBoolean());
}
@Test
@Ignore
public void testSetBadBoolean() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.XmlConfigurationTest$NativeHolder\">" +
" <Set name=\"boolean\">tru</Set>" +
"</Configure>");
NativeHolder bh = (NativeHolder)xmlConfiguration.configure();
Assert.assertTrue(bh.getBoolean());
}
@Test
public void testSetBadInteger() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.XmlConfigurationTest$NativeHolder\">" +
" <Set name=\"integer\">bad</Set>" +
"</Configure>");
try
{
xmlConfiguration.configure();
Assert.fail();
}
catch (Exception e)
{
}
}
@Test
public void testSetBadExtraInteger() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.XmlConfigurationTest$NativeHolder\">" +
" <Set name=\"integer\">100 bas</Set>" +
"</Configure>");
try
{
xmlConfiguration.configure();
Assert.fail();
}
catch (Exception e)
{
}
}
@Test
public void testSetBadFloatInteger() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.XmlConfigurationTest$NativeHolder\">" +
" <Set name=\"integer\">1.5</Set>" +
"</Configure>");
try
{
xmlConfiguration.configure();
Assert.fail();
}
catch (Exception e)
{
}
}
}