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:
commit
ed594425d3
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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()))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue