diff --git a/example-jetty-embedded/pom.xml b/example-jetty-embedded/pom.xml
index f2408d3a287..03da5633e3e 100644
--- a/example-jetty-embedded/pom.xml
+++ b/example-jetty-embedded/pom.xml
@@ -38,6 +38,11 @@
org.eclipse.jettyjetty-jmx${project.version}
+
+
+ org.eclipse.jetty.spdy
+ spdy-jetty-http
+ ${project.version}org.eclipse.jetty.toolchain
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
index 7c4083551cb..3c626d93f89 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
@@ -27,8 +27,7 @@ import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpServerConnectionFactory;
+import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server;
@@ -65,13 +64,11 @@ public class LikeJettyXml
mbContainer.addBean(new Log());
// Setup Connectors
- SelectChannelConnector connector = new SelectChannelConnector(server);
+ HttpConnectionFactory http = new HttpConnectionFactory();
+ http.getHttpChannelConfig().setSecurePort(8443);
+ SelectChannelConnector connector = new SelectChannelConnector(server,http);
connector.setPort(8080);
connector.setIdleTimeout(30000);
- HttpConfiguration httpConfiguration = new HttpConfiguration(null, false);
- httpConfiguration.setConfidentialPort(8443);
- connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector, httpConfiguration));
- // TODO connector.setStatsOn(false);
server.setConnectors(new Connector[]
{ connector });
@@ -94,7 +91,6 @@ public class LikeJettyXml
});
SelectChannelConnector sslConnector = new SelectChannelConnector(server,sslContextFactory);
sslConnector.setPort(8443);
- // TODO sslConnector.setStatsOn(false);
server.addConnector(sslConnector);
sslConnector.open();
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
index 4dc4411c806..1f308145000 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
@@ -18,10 +18,23 @@
package org.eclipse.jetty.embedded;
+import org.eclipse.jetty.io.ArrayByteBufferPool;
+import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.ForwardedRequestCustomizer;
+import org.eclipse.jetty.server.HttpChannelConfig;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.spdy.NPNServerConnectionFactory;
+import org.eclipse.jetty.spdy.http.PushStrategy;
+import org.eclipse.jetty.spdy.http.ReferrerPushStrategy;
+import org.eclipse.jetty.spdy.http.HTTPSPDYServerConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.util.thread.TimerScheduler;
/* ------------------------------------------------------------ */
/**
@@ -32,31 +45,73 @@ public class ManyConnectors
{
public static void main(String[] args) throws Exception
{
+ String jetty_home = System.getProperty("jetty.home","../jetty-server/src/main/config");
+ System.setProperty("jetty.home", jetty_home);
+
Server server = new Server();
+ // HTTP connector
SelectChannelConnector connector0 = new SelectChannelConnector(server);
connector0.setPort(8080);
connector0.setIdleTimeout(30000);
- SelectChannelConnector connector1 = new SelectChannelConnector(server);
- connector1.setHost("127.0.0.1");
- connector1.setPort(8888);
-
- String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution");
- System.setProperty("jetty.home", jetty_home);
+ // HTTPS connector
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore");
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
- SelectChannelConnector sslConnector = new SelectChannelConnector(server,sslContextFactory);
- sslConnector.setPort(8443);
-
- server.setConnectors(new Connector[]
- { connector0, connector1, sslConnector });
+
+ SelectChannelConnector connector1 = new SelectChannelConnector(server,sslContextFactory);
+ connector1.setPort(8443);
+
+
+ // A verbosely fully configured connector with SSL, SPDY and HTTP
+
+ HttpChannelConfig config = new HttpChannelConfig();
+ config.setSecureScheme("https");
+ config.setSecurePort(8443);
+ config.setOutputBufferSize(32768);
+ config.setRequestHeaderSize(8192);
+ config.setResponseHeaderSize(8192);
+ config.addCustomizer(new ForwardedRequestCustomizer());
+ config.addCustomizer(new SecureRequestCustomizer());
+
+ HttpConnectionFactory http = new HttpConnectionFactory(config);
+ http.setInputBufferSize(16384);
+
+ PushStrategy push = new ReferrerPushStrategy();
+ HTTPSPDYServerConnectionFactory spdy2 = new HTTPSPDYServerConnectionFactory(2,config,push);
+ spdy2.setInputBufferSize(8192);
+ spdy2.setInitialWindowSize(32768);
+
+ HTTPSPDYServerConnectionFactory spdy3 = new HTTPSPDYServerConnectionFactory(3,config,push);
+ spdy2.setInputBufferSize(8192);
+
+ NPNServerConnectionFactory npn = new NPNServerConnectionFactory(http.getProtocol(),spdy2.getProtocol(),spdy3.getProtocol());
+ npn.setDefaultProtocol(http.getProtocol());
+ npn.setInputBufferSize(1024);
+
+ SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory,npn.getProtocol());
+
+ QueuedThreadPool threadPool = new QueuedThreadPool();
+ threadPool.setMaxThreads(256);
+ TimerScheduler scheduler = new TimerScheduler();
+ ByteBufferPool bufferPool= new ArrayByteBufferPool(32,4096,32768);
+
+ SelectChannelConnector connector2 = new SelectChannelConnector(server,threadPool,scheduler,bufferPool,2,2,ssl,npn,spdy3,spdy2,http);
+ connector2.setDefaultProtocol("ssl-npn");
+ connector2.setPort(8444);
+ connector2.setIdleTimeout(30000);
+ connector2.setSoLingerTime(10000);
+
+ // Set the connectors
+ server.setConnectors(new Connector[] { connector0, connector1, connector2 });
+
server.setHandler(new HelloHandler());
server.start();
+ server.dumpStdErr();
server.join();
}
}
diff --git a/jetty-distribution/src/main/resources/start.ini b/jetty-distribution/src/main/resources/start.ini
index b86d24d2c77..e9dfa9abd28 100644
--- a/jetty-distribution/src/main/resources/start.ini
+++ b/jetty-distribution/src/main/resources/start.ini
@@ -51,7 +51,7 @@
# for a full listing do
# java -jar start.jar --list-options
#-----------------------------------------------------------
-OPTIONS=Server,jsp,resources,websocket,ext,plus
+OPTIONS=Server,jsp,resources,websocket,ext
#-----------------------------------------------------------
@@ -64,7 +64,6 @@ etc/jetty.xml
# etc/jetty-ssl.xml
# etc/jetty-requestlog.xml
etc/jetty-deploy.xml
-#etc/jetty-overlay.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
index 9c9862f8d52..3200d0edb36 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
@@ -47,6 +47,8 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
// TODO: Make this class inherit from oej.util.Fields
+// TODO move this class to jetty-http?
+
/**
* HTTP Fields. A collection of HTTP header and or Trailer fields.
@@ -787,11 +789,11 @@ public class HttpFields implements Iterable
// Format value and params
StringBuilder buf = new StringBuilder(128);
String name_value_params;
- boolean quoted = QuotedStringTokenizer.quoteIfNeeded(buf, name, delim);
+ QuotedStringTokenizer.quoteIfNeeded(buf, name, delim);
buf.append('=');
String start=buf.toString();
if (value != null && value.length() > 0)
- quoted|=QuotedStringTokenizer.quoteIfNeeded(buf, value, delim);
+ QuotedStringTokenizer.quoteIfNeeded(buf, value, delim);
if (path != null && path.length() > 0)
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index 2db27b62bc5..9f7c3e04bef 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -59,9 +59,9 @@ public class HttpParser
CLOSED
};
- private final HttpHandler _handler;
- private final RequestHandler _requestHandler;
- private final ResponseHandler _responseHandler;
+ private final HttpHandler _handler;
+ private final RequestHandler _requestHandler;
+ private final ResponseHandler _responseHandler;
private final int _maxHeaderBytes;
private HttpHeader _header;
private String _headerString;
@@ -91,19 +91,19 @@ public class HttpParser
private final Utf8StringBuilder _utf8=new Utf8StringBuilder();
/* ------------------------------------------------------------------------------- */
- public HttpParser(RequestHandler handler)
+ public HttpParser(RequestHandler handler)
{
this(handler,-1);
}
/* ------------------------------------------------------------------------------- */
- public HttpParser(ResponseHandler handler)
+ public HttpParser(ResponseHandler handler)
{
this(handler,-1);
}
/* ------------------------------------------------------------------------------- */
- public HttpParser(RequestHandler handler,int maxHeaderBytes)
+ public HttpParser(RequestHandler handler,int maxHeaderBytes)
{
_handler=handler;
_requestHandler=handler;
@@ -112,7 +112,7 @@ public class HttpParser
}
/* ------------------------------------------------------------------------------- */
- public HttpParser(ResponseHandler handler,int maxHeaderBytes)
+ public HttpParser(ResponseHandler handler,int maxHeaderBytes)
{
_handler=handler;
_requestHandler=null;
@@ -931,12 +931,14 @@ public class HttpParser
case CLOSED:
if (BufferUtil.hasContent(buffer))
{
- _headerBytes+=buffer.remaining();
+ int len=buffer.remaining();
+ _headerBytes+=len;
if (_headerBytes>_maxHeaderBytes)
{
+ Thread.sleep(100);
String chars = BufferUtil.toDetailString(buffer);
BufferUtil.clear(buffer);
- throw new IllegalStateException(this+" data when CLOSED: "+chars);
+ throw new IllegalStateException(String.format("%s %d/%d data when CLOSED:%s",this,len,_headerBytes,chars));
}
BufferUtil.clear(buffer);
}
@@ -1182,6 +1184,7 @@ public class HttpParser
}
setState(State.CLOSED);
_endOfContent=EndOfContent.UNKNOWN_CONTENT;
+ _contentLength=-1;
_contentPosition=0;
_responseStatus=0;
_headerBytes=0;
@@ -1194,6 +1197,7 @@ public class HttpParser
// reset state
setState(State.START);
_endOfContent=EndOfContent.UNKNOWN_CONTENT;
+ _contentLength=-1;
_contentPosition=0;
_responseStatus=0;
_contentChunk=null;
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
index aeebc0c6140..89f5bd4c292 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java
@@ -115,9 +115,9 @@ public class HttpFieldsTest
header.put("name:2", "value:\r\n2");
ByteBuffer buffer = BufferUtil.allocate(1024);
- buffer.clear();
+ BufferUtil.flipToFill(buffer);
header.putTo(buffer);
- buffer.flip();
+ BufferUtil.flipToFlush(buffer,0);
String out = BufferUtil.toString(buffer);
assertThat(out,containsString("name0: value??0"));
assertThat(out,containsString("name??1: value1"));
@@ -134,9 +134,9 @@ public class HttpFieldsTest
header.put("CONTENT-ENCODING", "gZIP");
ByteBuffer buffer = BufferUtil.allocate(1024);
- buffer.clear();
+ BufferUtil.flipToFill(buffer);
header.putTo(buffer);
- buffer.flip();
+ BufferUtil.flipToFlush(buffer,0);
String out = BufferUtil.toString(buffer);
Assert.assertThat(out,Matchers.containsString(HttpHeader.CONNECTION+": "+HttpHeaderValue.KEEP_ALIVE));
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
index abe1e1f7c3f..cb62efdbcb3 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
@@ -45,6 +45,8 @@ public abstract class AbstractConnection implements Connection
private enum State {IDLE,INTERESTED,FILLING,FILLING_INTERESTED};
private final AtomicReference _state = new AtomicReference<>(State.IDLE);
+ private int _inputBufferSize=8192;
+
public AbstractConnection(EndPoint endp, Executor executor)
{
this(endp, executor, true);
@@ -117,6 +119,16 @@ public abstract class AbstractConnection implements Connection
}
};
}
+
+ public int getInputBufferSize()
+ {
+ return _inputBufferSize;
+ }
+
+ public void setInputBufferSize(int inputBufferSize)
+ {
+ _inputBufferSize = inputBufferSize;
+ }
public Executor getExecutor()
{
@@ -146,7 +158,6 @@ public abstract class AbstractConnection implements Connection
break;
case FILLING:
-
if (_state.compareAndSet(State.FILLING,State.FILLING_INTERESTED))
break loop;
break;
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java
index fa0c8507641..75822c86dcd 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java
@@ -109,7 +109,10 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa
Connection old = getConnection();
super.setConnection(connection);
if (old != null && old != connection)
+ {
+ LOG.debug("Upgrading connection {} -> {} on endPoint {}", old, connection, this);
_selector.getSelectorManager().connectionUpgraded(this, old);
+ }
}
@Override
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
index 3a669747c01..4422f9241f1 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java
@@ -19,7 +19,9 @@
package org.eclipse.jetty.io.ssl;
import java.io.IOException;
+import java.net.SocketException;
import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.concurrent.Executor;
import javax.net.ssl.SSLEngine;
@@ -31,6 +33,7 @@ import javax.net.ssl.SSLException;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.AbstractEndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.ChannelEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
@@ -111,6 +114,19 @@ public class SslConnection extends AbstractConnection
this._bufferPool = byteBufferPool;
this._sslEngine = sslEngine;
this._decryptedEndPoint = new DecryptedEndPoint();
+
+ // TODO ugly
+ if (endPoint instanceof ChannelEndPoint)
+ {
+ try
+ {
+ ((SocketChannel)((ChannelEndPoint)endPoint).getChannel()).socket().setSoLinger(true,30000);
+ }
+ catch (SocketException e)
+ {
+ throw new RuntimeIOException(e);
+ }
+ }
}
public SSLEngine getSSLEngine()
@@ -396,6 +412,18 @@ public class SslConnection extends AbstractConnection
}
}
+ @Override
+ public void setConnection(Connection connection)
+ {
+ if (connection instanceof AbstractConnection)
+ {
+ AbstractConnection a = (AbstractConnection)connection;
+ if (a.getInputBufferSize()<_sslEngine.getSession().getApplicationBufferSize());
+ a.setInputBufferSize(_sslEngine.getSession().getApplicationBufferSize());
+ }
+ super.setConnection(connection);
+ }
+
public SslConnection getSslConnection()
{
return SslConnection.this;
diff --git a/jetty-plus/src/main/config/100-jetty-plus.ini b/jetty-plus/src/main/config/100-jetty-plus.ini
new file mode 100644
index 00000000000..7e23d701fd0
--- /dev/null
+++ b/jetty-plus/src/main/config/100-jetty-plus.ini
@@ -0,0 +1,2 @@
+OPTIONS=plus
+etc/jetty-plus.xml
\ No newline at end of file
diff --git a/jetty-plus/src/main/config/start.d b/jetty-plus/src/main/config/start.d
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
index d323fce2a72..a9e688bbfbb 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -28,9 +28,10 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
+import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.server.HttpChannel;
-import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpChannelConfig;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.UserIdentity;
@@ -87,12 +88,14 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
/**
* @return Returns the constraintMappings.
*/
+ @Override
public List getConstraintMappings()
{
return _constraintMappings;
}
/* ------------------------------------------------------------ */
+ @Override
public Set getRoles()
{
return _roles;
@@ -134,6 +137,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
* The constraintMappings to set.
* @param roles The known roles (or null to determine them from the mappings)
*/
+ @Override
public void setConstraintMappings(List constraintMappings, Set roles)
{
if (isStarted())
@@ -181,6 +185,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
/**
* @see org.eclipse.jetty.security.ConstraintAware#addConstraintMapping(org.eclipse.jetty.security.ConstraintMapping)
*/
+ @Override
public void addConstraintMapping(ConstraintMapping mapping)
{
_constraintMappings.add(mapping);
@@ -198,6 +203,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
/**
* @see org.eclipse.jetty.security.ConstraintAware#addRole(java.lang.String)
*/
+ @Override
public void addRole(String role)
{
boolean modified = _roles.add(role);
@@ -325,6 +331,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
}
}
+ @Override
protected RoleInfo prepareConstraintInfo(String pathInContext, Request request)
{
Map mappings = _constraintMap.match(pathInContext);
@@ -354,34 +361,16 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
if (dataConstraint == null || dataConstraint == UserDataConstraint.None)
return true;
- HttpConfiguration httpConfiguration = HttpChannel.getCurrentHttpChannel().getHttpConfiguration();
+ HttpChannelConfig httpConfig = HttpChannel.getCurrentHttpChannel().getHttpChannelConfig();
- if (dataConstraint == UserDataConstraint.Integral)
+ if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral)
{
- if (httpConfiguration.isIntegral(request))
- return true;
- if (httpConfiguration.getIntegralPort() > 0)
- {
- String url = httpConfiguration.getIntegralScheme() + "://" + request.getServerName() + ":" + httpConfiguration.getIntegralPort() + request.getRequestURI();
- if (request.getQueryString() != null)
- url += "?" + request.getQueryString();
- response.setContentLength(0);
- response.sendRedirect(url);
- }
- else
- response.sendError(Response.SC_FORBIDDEN,"!Integral");
-
- request.setHandled(true);
- return false;
- }
- else if (dataConstraint == UserDataConstraint.Confidential)
- {
- if (httpConfiguration.isConfidential(request))
+ if (request.isSecure())
return true;
- if (httpConfiguration.getConfidentialPort() > 0)
+ if (httpConfig.getSecurePort() > 0)
{
- String url = httpConfiguration.getConfidentialScheme() + "://" + request.getServerName() + ":" + httpConfiguration.getConfidentialPort()
+ String url = httpConfig.getSecureScheme() + "://" + request.getServerName() + ":" + httpConfig.getSecurePort()
+ request.getRequestURI();
if (request.getQueryString() != null)
url += "?" + request.getQueryString();
@@ -390,7 +379,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
response.sendRedirect(url);
}
else
- response.sendError(Response.SC_FORBIDDEN,"!Confidential");
+ response.sendError(HttpStatus.FORBIDDEN_403,"!Secure");
request.setHandled(true);
return false;
@@ -402,6 +391,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
}
+ @Override
protected boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo)
{
return constraintInfo != null && ((RoleInfo)constraintInfo).isChecked();
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java
index 321031f0611..65c8eacc95a 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java
@@ -28,8 +28,8 @@ import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpServerConnectionFactory;
+import org.eclipse.jetty.server.HttpChannelConfig;
+import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
@@ -60,38 +60,25 @@ public class DataConstraintsTest
public void startServer()
{
_server = new Server();
- _connector = new LocalConnector(_server);
+
+ HttpConnectionFactory http = new HttpConnectionFactory();
+ http.getHttpChannelConfig().setSecurePort(9999);
+ http.getHttpChannelConfig().setSecureScheme("BWTP");
+ _connector = new LocalConnector(_server,http);
_connector.setIdleTimeout(300000);
- HttpConfiguration httpConfiguration = new HttpConfiguration(null, false);
- httpConfiguration.setIntegralPort(9998);
- httpConfiguration.setIntegralScheme("FTP");
- httpConfiguration.setConfidentialPort(9999);
- httpConfiguration.setConfidentialScheme("SPDY");
- _connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(_connector, httpConfiguration));
- _connectorS = new LocalConnector(_server);
- _connectorS.setDefaultConnectionFactory(new HttpServerConnectionFactory(_connectorS, new HttpConfiguration(null,false)
+ HttpConnectionFactory https = new HttpConnectionFactory();
+ https.getHttpChannelConfig().addCustomizer(new HttpChannelConfig.Customizer()
{
@Override
- public void customize(Request request) throws IOException
+ public void customize(Connector connector, HttpChannelConfig channelConfig, Request request)
{
request.setScheme(HttpScheme.HTTPS.asString());
- super.customize(request);
+ request.setSecure(true);
}
-
-
- @Override
- public boolean isIntegral(Request request)
- {
- return true;
- }
-
- @Override
- public boolean isConfidential(Request request)
- {
- return true;
- }
- }));
+ });
+
+ _connectorS = new LocalConnector(_server,https);
_server.setConnectors(new Connector[]{_connector,_connectorS});
ContextHandler _context = new ContextHandler();
@@ -106,6 +93,7 @@ public class DataConstraintsTest
_security.setHandler(new AbstractHandler()
{
+ @Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
@@ -149,8 +137,8 @@ public class DataConstraintsTest
response = _connector.getResponses("GET /ctx/integral/info HTTP/1.0\r\n\r\n");
assertThat(response, containsString("HTTP/1.1 302 Found"));
- assertThat(response, containsString("Location: FTP://"));
- assertThat(response, containsString(":9998"));
+ assertThat(response, containsString("Location: BWTP://"));
+ assertThat(response, containsString(":9999"));
response = _connectorS.getResponses("GET /ctx/integral/info HTTP/1.0\r\n\r\n");
assertThat(response, containsString("HTTP/1.1 404 Not Found"));
@@ -181,7 +169,7 @@ public class DataConstraintsTest
response = _connector.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n");
assertThat(response, containsString("HTTP/1.1 302 Found"));
- assertThat(response, containsString("Location: SPDY://"));
+ assertThat(response, containsString("Location: BWTP://"));
assertThat(response, containsString(":9999"));
response = _connectorS.getResponses("GET /ctx/confid/info HTTP/1.0\r\n\r\n");
@@ -444,11 +432,14 @@ public class DataConstraintsTest
{
this.identityService = identityService;
}
+
+ @Override
public String getName()
{
return "name";
}
+ @Override
public UserIdentity login(String username, Object credentials)
{
if("admin".equals(username) && "password".equals(credentials))
@@ -456,20 +447,24 @@ public class DataConstraintsTest
return null;
}
+ @Override
public boolean validate(UserIdentity user)
{
return false;
}
+ @Override
public IdentityService getIdentityService()
{
return identityService;
}
+ @Override
public void setIdentityService(IdentityService service)
{
}
+ @Override
public void logout(UserIdentity user)
{
}
diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml
index 6d5a7e79409..9d0f8b6a961 100644
--- a/jetty-server/src/main/config/etc/jetty.xml
+++ b/jetty-server/src/main/config/etc/jetty.xml
@@ -38,7 +38,7 @@
- 300000
+ 30000
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java
new file mode 100644
index 00000000000..d11f33fe818
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java
@@ -0,0 +1,78 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.server;
+
+import org.eclipse.jetty.util.ArrayUtil;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+public abstract class AbstractConnectionFactory extends AggregateLifeCycle implements ConnectionFactory
+{
+ final String _protocol;
+ int _inputbufferSize=8192;
+
+ protected AbstractConnectionFactory(String protocol)
+ {
+ _protocol=protocol;
+ }
+
+ @Override
+ public String getProtocol()
+ {
+ return _protocol;
+ }
+
+ public int getInputBufferSize()
+ {
+ return _inputbufferSize;
+ }
+
+ public void setInputBufferSize(int size)
+ {
+ _inputbufferSize=size;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x{%s}",this.getClass().getSimpleName(),hashCode(),getProtocol());
+ }
+
+ public static ConnectionFactory[] getFactories(SslContextFactory sslContextFactory, ConnectionFactory... factories)
+ {
+ factories=ArrayUtil.removeNulls(factories);
+
+ if (sslContextFactory==null)
+ return factories;
+
+ for (ConnectionFactory factory : factories)
+ {
+ if (factory instanceof HttpChannelConfig.ConnectionFactory)
+ {
+ HttpChannelConfig config = ((HttpChannelConfig.ConnectionFactory)factory).getHttpChannelConfig();
+ if (config.getCustomizer(SecureRequestCustomizer.class)==null)
+ config.addCustomizer(new SecureRequestCustomizer());
+ }
+ }
+ return ArrayUtil.prependToArray(new SslConnectionFactory(sslContextFactory,factories[0].getProtocol()),factories,ConnectionFactory.class);
+
+ }
+
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 4afd4bdc0ee..6016dd2688b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -20,7 +20,10 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -37,51 +40,63 @@ import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.TimerScheduler;
/**
*
Partial implementation of {@link Connector}
+ *
+ *
+ * The connector keeps a collection of {@link ConnectionFactory} instances, each of which are known by their
+ * protocol name. The protocol name may be a real protocol (eg http/1.1 or spdy/3) or it may be a private name
+ * that represents a special connection factory. For example, the name "SSL-http/1.1" is used for
+ * an {@link SslConnectionFactory} that has been instantiated with the {@link HttpConnectionFactory} as it's
+ * next protocol.
+ *
+ * If NPN is used to select the real protocol used by an SSL connection, then the name "SSL-NPN" is used,
+ * which represents a {@link SslConnectionFactory} with a NPNConnectionFactory as the next protocol. Once
+ * the NPN connection is established, it will get the next protocol from the NPN extension and then call
+ * {@link #getConnectionFactory(String)} to get the next connection factory.
+ *
*/
@ManagedObject("Abstract implementation of the Connector Interface")
public abstract class AbstractConnector extends AggregateLifeCycle implements Connector, Dumpable
{
protected final Logger LOG = Log.getLogger(getClass());
// Order is important on server side, so we use a LinkedHashMap
- private final Map factories = new LinkedHashMap<>();
+ private final Map _factories = new LinkedHashMap<>();
private final Statistics _stats = new ConnectorStatistics();
private final Server _server;
- private final SslContextFactory _sslContextFactory;
private final Executor _executor;
private final Scheduler _scheduler;
private final ByteBufferPool _byteBufferPool;
private final Thread[] _acceptors;
private volatile CountDownLatch _stopping;
- private volatile long _idleTimeout = 200000;
- private volatile ConnectionFactory defaultConnectionFactory;
+ private long _idleTimeout = 200000;
+ private String _defaultProtocol;
+ private ConnectionFactory _defaultConnectionFactory;
/**
* @param server The server this connector will be added to. Must not be null.
+ * @param factory TODO
+ * @param sslContextFactory the SSL context factory to make this connector SSL enabled, or null
* @param executor An executor for this connector or null to use the servers executor
* @param scheduler A scheduler for this connector or null to use the servers scheduler
* @param pool A buffer pool for this connector or null to use a default {@link ByteBufferPool}
- * @param sslContextFactory the SSL context factory to make this connector SSL enabled, or null
* @param acceptors the number of acceptor threads to use, or 0 for a default value.
*/
public AbstractConnector(
Server server,
Executor executor,
Scheduler scheduler,
- ByteBufferPool pool,
- SslContextFactory sslContextFactory,
- int acceptors)
+ ByteBufferPool pool,
+ int acceptors,
+ ConnectionFactory... factories)
{
_server=server;
_executor=executor!=null?executor:_server.getThreadPool();
_scheduler=scheduler!=null?scheduler:new TimerScheduler();
_byteBufferPool = pool!=null?pool:new ArrayByteBufferPool();
- _sslContextFactory = sslContextFactory;
addBean(_server,false);
addBean(_executor);
@@ -89,9 +104,11 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
unmanage(_executor); // inherited from server
addBean(_scheduler);
addBean(_byteBufferPool);
- addBean(_sslContextFactory);
addBean(_stats,true);
+ for (ConnectionFactory factory:factories)
+ addConnectionFactory(factory);
+
if (acceptors<=0)
acceptors=Math.max(1,(Runtime.getRuntime().availableProcessors()) / 4);
if (acceptors > 2 * Runtime.getRuntime().availableProcessors())
@@ -123,12 +140,6 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
return _byteBufferPool;
}
- @Override
- public SslContextFactory getSslContextFactory()
- {
- return _sslContextFactory;
- }
-
@Override
public long getIdleTimeout()
{
@@ -162,10 +173,13 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
return _acceptors.length;
}
-
@Override
protected void doStart() throws Exception
{
+ _defaultConnectionFactory = getConnectionFactory(_defaultProtocol);
+ if(_defaultConnectionFactory==null)
+ throw new IllegalStateException("No protocol factory for default protocol: "+_defaultProtocol);
+
super.doStart();
_stopping=new CountDownLatch(_acceptors.length);
@@ -232,56 +246,97 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
return isRunning();
}
+ @Override
public ConnectionFactory getConnectionFactory(String protocol)
{
- synchronized (factories)
+ synchronized (_factories)
{
- return factories.get(protocol);
+ return _factories.get(protocol.toLowerCase());
}
}
- public ConnectionFactory putConnectionFactory(String protocol, ConnectionFactory factory)
+ @Override
+ public T getConnectionFactory(Class factoryType)
{
- synchronized (factories)
+ synchronized (_factories)
{
- return factories.put(protocol, factory);
+ for (ConnectionFactory f : _factories.values())
+ if (factoryType.isAssignableFrom(f.getClass()))
+ return (T)f;
+ return null;
+ }
+ }
+
+ public void addConnectionFactory(ConnectionFactory factory)
+ {
+ synchronized (_factories)
+ {
+ ConnectionFactory old=_factories.remove(factory.getProtocol());
+ if (old!=null)
+ removeBean(old);
+ _factories.put(factory.getProtocol().toLowerCase(), factory);
+ addBean(factory);
+ if (_defaultProtocol==null)
+ _defaultProtocol=factory.getProtocol();
}
}
public ConnectionFactory removeConnectionFactory(String protocol)
{
- synchronized (factories)
+ synchronized (_factories)
{
- return factories.remove(protocol);
+ ConnectionFactory factory= _factories.remove(protocol.toLowerCase());
+ removeBean(factory);
+ return factory;
}
}
- public Map getConnectionFactories()
+ @Override
+ public Collection getConnectionFactories()
{
- synchronized (factories)
+ synchronized (_factories)
{
- return new LinkedHashMap<>(factories);
+ return _factories.values();
+ }
+ }
+
+ @Override
+ public List getProtocols()
+ {
+ synchronized (_factories)
+ {
+ return new ArrayList<>(_factories.keySet());
}
}
public void clearConnectionFactories()
{
- synchronized (factories)
+ synchronized (_factories)
{
- factories.clear();
+ _factories.clear();
}
}
+ public String getDefaultProtocol()
+ {
+ return _defaultProtocol;
+ }
+
+ public void setDefaultProtocol(String defaultProtocol)
+ {
+ if(isRunning())
+ throw new IllegalStateException(getState());
+ _defaultProtocol = defaultProtocol.toLowerCase();
+ }
+
+ @Override
public ConnectionFactory getDefaultConnectionFactory()
{
- return defaultConnectionFactory;
+ if (isStarted())
+ return _defaultConnectionFactory;
+ return getConnectionFactory(_defaultProtocol);
}
-
- public void setDefaultConnectionFactory(ConnectionFactory defaultConnectionFactory)
- {
- this.defaultConnectionFactory = defaultConnectionFactory;
- }
-
+
private class Acceptor implements Runnable
{
private final int _acceptor;
@@ -358,4 +413,13 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
{
return _scheduler;
}
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x{%s}",
+ getClass().getSimpleName(),
+ hashCode(),
+ getDefaultProtocol());
+ }
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java
index 21fafc7a50c..59070233d33 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java
@@ -23,7 +23,6 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.Scheduler;
/**
@@ -34,9 +33,9 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme
private volatile String _host;
private volatile int _port = 0;
- public AbstractNetworkConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, SslContextFactory sslContextFactory, int acceptors)
+ public AbstractNetworkConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, int acceptors, ConnectionFactory... factories)
{
- super(server, executor, scheduler, pool, sslContextFactory, acceptors);
+ super(server,executor,scheduler,pool,acceptors,factories);
}
public void setHost(String host)
@@ -110,8 +109,8 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme
@Override
public String toString()
{
- return String.format("%s@%s:%d",
- getClass().getSimpleName(),
+ return String.format("%s{%s:%d}",
+ super.toString(),
getHost() == null ? "0.0.0.0" : getHost(),
getLocalPort() <= 0 ? getPort() : getLocalPort());
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ByteBufferHttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ByteBufferHttpInput.java
index 680deb511f6..8d81c83c7b5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ByteBufferHttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ByteBufferHttpInput.java
@@ -42,6 +42,5 @@ public class ByteBufferHttpInput extends HttpInput
@Override
protected void onContentConsumed(ByteBuffer item)
{
- item.clear();
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java
index daad1fa5c9c..b129baf62f9 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java
@@ -18,7 +18,6 @@
package org.eclipse.jetty.server;
-import java.nio.channels.SocketChannel;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
@@ -28,12 +27,14 @@ import org.eclipse.jetty.io.EndPoint;
*/
public interface ConnectionFactory
{
+ public String getProtocol();
+
/**
*
Creates a new {@link Connection} with the given parameters
- * @param channel the {@link SocketChannel} associated with the connection
+ * @param connector The {@link Connector} creating this connection
* @param endPoint the {@link EndPoint} associated with the connection
- * @param attachment the attachment associated with the connection
* @return a new {@link Connection}
*/
- public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment);
+ public Connection newConnection(Connector connector, EndPoint endPoint);
+
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
index 908abd0db07..c37f3fd5463 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java
@@ -18,6 +18,8 @@
package org.eclipse.jetty.server;
+import java.util.Collection;
+import java.util.List;
import java.util.concurrent.Executor;
import org.eclipse.jetty.io.ByteBufferPool;
@@ -25,7 +27,6 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Graceful;
import org.eclipse.jetty.util.component.LifeCycle;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.Scheduler;
/**
@@ -57,10 +58,22 @@ public interface Connector extends LifeCycle, Graceful
public ByteBufferPool getByteBufferPool();
/**
- * @return the {@link SslContextFactory} associated with this {@link Connector}
+ * @return the {@link ConnectionFactory} associated with the protocol name
*/
- public SslContextFactory getSslContextFactory();
+ public ConnectionFactory getConnectionFactory(String nextProtocol);
+
+ public T getConnectionFactory(Class factoryType);
+
+ /**
+ * @return the default {@link ConnectionFactory} associated with the default protocol name
+ */
+ public ConnectionFactory getDefaultConnectionFactory();
+
+ public Collection getConnectionFactories();
+
+ public List getProtocols();
+
/**
* @return the dle timeout for connections in milliseconds
*/
@@ -199,4 +212,6 @@ public interface Connector extends LifeCycle, Graceful
*/
public void connectionClosed(long duration, int messagesIn, int messagesOut);
}
+
+
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
index 90954666c6f..9919323211b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
+
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java
new file mode 100644
index 00000000000..8f9f5825d76
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java
@@ -0,0 +1,280 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.server;
+
+import java.net.InetSocketAddress;
+
+import javax.servlet.ServletRequest;
+
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpScheme;
+import org.eclipse.jetty.server.HttpChannelConfig.Customizer;
+
+public class ForwardedRequestCustomizer implements Customizer
+{
+ private String _hostHeader;
+ private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
+ private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
+ private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
+ private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString();
+ private String _forwardedCipherSuiteHeader;
+ private String _forwardedSslSessionIdHeader;
+
+
+ /* ------------------------------------------------------------ */
+ public String getHostHeader()
+ {
+ return _hostHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
+ * This value is only used if {@link #isForwarded()} is true.
+ *
+ * @param hostHeader
+ * The value of the host header to force.
+ */
+ public void setHostHeader(String hostHeader)
+ {
+ _hostHeader = hostHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /*
+ *
+ * @see #setForwarded(boolean)
+ */
+ public String getForwardedHostHeader()
+ {
+ return _forwardedHostHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param forwardedHostHeader
+ * The header name for forwarded hosts (default x-forwarded-host)
+ * @see #setForwarded(boolean)
+ */
+ public void setForwardedHostHeader(String forwardedHostHeader)
+ {
+ _forwardedHostHeader = forwardedHostHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return the header name for forwarded server.
+ * @see #setForwarded(boolean)
+ */
+ public String getForwardedServerHeader()
+ {
+ return _forwardedServerHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param forwardedServerHeader
+ * The header name for forwarded server (default x-forwarded-server)
+ * @see #setForwarded(boolean)
+ */
+ public void setForwardedServerHeader(String forwardedServerHeader)
+ {
+ _forwardedServerHeader = forwardedServerHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return the forwarded for header
+ * @see #setForwarded(boolean)
+ */
+ public String getForwardedForHeader()
+ {
+ return _forwardedForHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param forwardedRemoteAddressHeader
+ * The header name for forwarded for (default x-forwarded-for)
+ * @see #setForwarded(boolean)
+ */
+ public void setForwardedForHeader(String forwardedRemoteAddressHeader)
+ {
+ _forwardedForHeader = forwardedRemoteAddressHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Get the forwardedProtoHeader.
+ *
+ * @return the forwardedProtoHeader (default X-Forwarded-For)
+ * @see #setForwarded(boolean)
+ */
+ public String getForwardedProtoHeader()
+ {
+ return _forwardedProtoHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the forwardedProtoHeader.
+ *
+ * @param forwardedProtoHeader
+ * the forwardedProtoHeader to set (default X-Forwarded-For)
+ * @see #setForwarded(boolean)
+ */
+ public void setForwardedProtoHeader(String forwardedProtoHeader)
+ {
+ _forwardedProtoHeader = forwardedProtoHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The header name holding a forwarded cipher suite (default null)
+ */
+ public String getForwardedCipherSuiteHeader()
+ {
+ return _forwardedCipherSuiteHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param forwardedCipherSuite
+ * The header name holding a forwarded cipher suite (default null)
+ */
+ public void setForwardedCipherSuiteHeader(String forwardedCipherSuite)
+ {
+ _forwardedCipherSuiteHeader = forwardedCipherSuite;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The header name holding a forwarded SSL Session ID (default null)
+ */
+ public String getForwardedSslSessionIdHeader()
+ {
+ return _forwardedSslSessionIdHeader;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param forwardedSslSessionId
+ * The header name holding a forwarded SSL Session ID (default null)
+ */
+ public void setForwardedSslSessionIdHeader(String forwardedSslSessionId)
+ {
+ _forwardedSslSessionIdHeader = forwardedSslSessionId;
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void customize(Connector connector, HttpChannelConfig config, Request request)
+ {
+ HttpFields httpFields = request.getHttpFields();
+
+ // Do SSL first
+ if (getForwardedCipherSuiteHeader()!=null)
+ {
+ String cipher_suite=httpFields.getStringField(getForwardedCipherSuiteHeader());
+ if (cipher_suite!=null)
+ request.setAttribute("javax.servlet.request.cipher_suite",cipher_suite);
+ }
+ if (getForwardedSslSessionIdHeader()!=null)
+ {
+ String ssl_session_id=httpFields.getStringField(getForwardedSslSessionIdHeader());
+ if(ssl_session_id!=null)
+ {
+ request.setAttribute("javax.servlet.request.ssl_session_id", ssl_session_id);
+ request.setScheme(HttpScheme.HTTPS.asString());
+ }
+ }
+
+ // Retrieving headers from the request
+ String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader());
+ String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader());
+ String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader());
+ String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader());
+
+ if (_hostHeader != null)
+ {
+ // Update host header
+ httpFields.put(HttpHeader.HOST.toString(),_hostHeader);
+ request.setServerName(null);
+ request.setServerPort(-1);
+ request.getServerName();
+ }
+ else if (forwardedHost != null)
+ {
+ // Update host header
+ httpFields.put(HttpHeader.HOST.toString(),forwardedHost);
+ request.setServerName(null);
+ request.setServerPort(-1);
+ request.getServerName();
+ }
+ else if (forwardedServer != null)
+ {
+ // Use provided server name
+ request.setServerName(forwardedServer);
+ }
+
+ if (forwardedFor != null)
+ {
+ request.setRemoteAddr(new InetSocketAddress(forwardedFor,request.getRemotePort()));
+ }
+
+ if (forwardedProto != null)
+ {
+ request.setScheme(forwardedProto);
+ if (forwardedProto.equals(config.getSecureScheme()))
+ request.setSecure(true);
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ protected String getLeftMostFieldValue(HttpFields fields, String header)
+ {
+ if (header == null)
+ return null;
+
+ String headerValue = fields.getStringField(header);
+
+ if (headerValue == null)
+ return null;
+
+ int commaIndex = headerValue.indexOf(',');
+
+ if (commaIndex == -1)
+ {
+ // Single value
+ return headerValue;
+ }
+
+ // The left-most value is the farthest downstream client
+ return headerValue.substring(0,commaIndex);
+ }
+
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x",this.getClass().getSimpleName(),hashCode());
+ }
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java
index b2715a9c634..1a6205f59ef 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java
@@ -19,6 +19,7 @@
package org.eclipse.jetty.server;
import java.io.IOException;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
index 29fac7f48a2..24536935237 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
@@ -23,6 +23,7 @@ import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
@@ -63,14 +64,14 @@ import org.eclipse.jetty.util.thread.Scheduler;
public class HttpChannel implements HttpParser.RequestHandler, Runnable
{
private static final Logger LOG = Log.getLogger(HttpChannel.class);
- private static final ThreadLocal __currentChannel = new ThreadLocal<>();
+ private static final ThreadLocal> __currentChannel = new ThreadLocal<>();
- public static HttpChannel getCurrentHttpChannel()
+ public static HttpChannel> getCurrentHttpChannel()
{
return __currentChannel.get();
}
- protected static void setCurrentHttpChannel(HttpChannel channel)
+ protected static void setCurrentHttpChannel(HttpChannel> channel)
{
__currentChannel.set(channel);
}
@@ -78,7 +79,7 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable
private final AtomicBoolean _committed = new AtomicBoolean();
private final AtomicInteger _requests = new AtomicInteger();
private final Connector _connector;
- private final HttpConfiguration _configuration;
+ private final HttpChannelConfig _configuration;
private final EndPoint _endPoint;
private final HttpTransport _transport;
private final HttpURI _uri;
@@ -90,7 +91,7 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable
private boolean _expect100Continue = false;
private boolean _expect102Processing = false;
- public HttpChannel(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input)
+ public HttpChannel(Connector connector, HttpChannelConfig configuration, EndPoint endPoint, HttpTransport transport, HttpInput input)
{
_connector = connector;
_configuration = configuration;
@@ -131,7 +132,7 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable
return _connector.getByteBufferPool();
}
- public HttpConfiguration getHttpConfiguration()
+ public HttpChannelConfig getHttpChannelConfig()
{
return _configuration;
}
@@ -237,8 +238,11 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable
if (_state.isInitial())
{
+ _request.setTimeStamp(System.currentTimeMillis());
_request.setDispatcherType(DispatcherType.REQUEST);
- getHttpConfiguration().customize(_request);
+
+ for (HttpChannelConfig.Customizer customizer : _configuration.getCustomizers())
+ customizer.customize(getConnector(),_configuration,_request);
getServer().handle(this);
}
else
@@ -321,7 +325,7 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable
if (_state.isSuspended())
{
HttpFields fields = new HttpFields();
- ResponseInfo info = new ResponseInfo(_request.getHttpVersion(), fields, 0, Response.SC_INTERNAL_SERVER_ERROR, null, _request.isHead());
+ ResponseInfo info = new ResponseInfo(_request.getHttpVersion(), fields, 0, HttpStatus.INTERNAL_SERVER_ERROR_500, null, _request.isHead());
boolean committed = commitResponse(info, null, true);
if (!committed)
LOG.warn("Could not send response error 500: "+x);
@@ -515,7 +519,7 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable
if (LOG.isDebugEnabled())
LOG.debug("{} content {}", this, item);
@SuppressWarnings("unchecked")
- HttpInput input = _request.getHttpInput();
+ HttpInput input = (HttpInput)_request.getHttpInput();
input.content(item);
return true;
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelConfig.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelConfig.java
new file mode 100644
index 00000000000..2ef9016b82c
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelConfig.java
@@ -0,0 +1,124 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.server;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.jetty.http.HttpScheme;
+
+public class HttpChannelConfig
+{
+ private List _customizers=new CopyOnWriteArrayList<>();
+ private int _outputBufferSize=32*1024;
+ private int _requestHeaderSize=8*1024;
+ private int _responseHeaderSize=8*1024;
+ private int _securePort;
+ private String _secureScheme = HttpScheme.HTTPS.asString();
+
+ public interface Customizer
+ {
+ public void customize(Connector connector, HttpChannelConfig channelConfig, Request request);
+ }
+
+ public interface ConnectionFactory
+ {
+ HttpChannelConfig getHttpChannelConfig();
+ }
+
+ public void addCustomizer(Customizer customizer)
+ {
+ _customizers.add(customizer);
+ }
+
+ public List getCustomizers()
+ {
+ return _customizers;
+ }
+
+ public T getCustomizer(Class type)
+ {
+ for (Customizer c : _customizers)
+ if (type.isAssignableFrom(c.getClass()))
+ return (T)c;
+ return null;
+ }
+
+ public int getOutputBufferSize()
+ {
+ return _outputBufferSize;
+ }
+
+ public int getRequestHeaderSize()
+ {
+ return _requestHeaderSize;
+ }
+
+ public int getResponseHeaderSize()
+ {
+ return _responseHeaderSize;
+ }
+
+ public int getSecurePort()
+ {
+ return _securePort;
+ }
+
+ public String getSecureScheme()
+ {
+ return _secureScheme;
+ }
+
+ public void setCustomizers(List customizers)
+ {
+ _customizers.clear();
+ _customizers.addAll(customizers);
+ }
+
+ public void setOutputBufferSize(int responseBufferSize)
+ {
+ _outputBufferSize = responseBufferSize;
+ }
+
+ public void setRequestHeaderSize(int requestHeaderSize)
+ {
+ _requestHeaderSize = requestHeaderSize;
+ }
+
+ public void setResponseHeaderSize(int responseHeaderSize)
+ {
+ _responseHeaderSize = responseHeaderSize;
+ }
+
+ public void setSecurePort(int confidentialPort)
+ {
+ _securePort = confidentialPort;
+ }
+
+ public void setSecureScheme(String confidentialScheme)
+ {
+ _secureScheme = confidentialScheme;
+ }
+
+ @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);
+ }
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java
index 83e7f0ee079..04c3b7008b1 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java
@@ -21,6 +21,7 @@ package org.eclipse.jetty.server;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
+
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
deleted file mode 100644
index 266b22f3e8b..00000000000
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
+++ /dev/null
@@ -1,556 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.server;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLSession;
-import javax.servlet.ServletRequest;
-
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpScheme;
-import org.eclipse.jetty.io.ssl.SslConnection;
-import org.eclipse.jetty.server.ssl.SslCertificates;
-import org.eclipse.jetty.util.component.AggregateLifeCycle;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-
-public class HttpConfiguration extends AggregateLifeCycle
-{
- static final Logger LOG = Log.getLogger(HttpConfiguration.class);
-
- private final SslContextFactory _sslContextFactory;
- private final boolean _ssl;
-
- private String _integralScheme = HttpScheme.HTTPS.asString();
- private int _integralPort = 0;
- private String _confidentialScheme = HttpScheme.HTTPS.asString();
- private int _confidentialPort = 0;
- private boolean _forwarded;
- private String _hostHeader;
- private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
- private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
- private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
- private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString();
- private String _forwardedCipherSuiteHeader;
- private String _forwardedSslSessionIdHeader;
- private int _requestHeaderSize=8*1024;
- private int _requestBufferSize=16*1024;
- private int _responseHeaderSize=8*1024;
- private int _responseBufferSize=32*1024;
-
- public HttpConfiguration(SslContextFactory sslContextFactory,boolean ssl)
- {
- _sslContextFactory=sslContextFactory!=null?sslContextFactory:ssl?new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH):null;
- _ssl=ssl;
- if (_sslContextFactory!=null)
- addBean(_sslContextFactory,sslContextFactory==null);
- }
-
- public SslContextFactory getSslContextFactory()
- {
- return _sslContextFactory;
- }
-
- public boolean isSecure()
- {
- return _ssl;
- }
-
- public int getRequestHeaderSize()
- {
- return _requestHeaderSize;
- }
-
- public void setRequestHeaderSize(int requestHeaderSize)
- {
- _requestHeaderSize = requestHeaderSize;
- }
-
- public int getRequestBufferSize()
- {
- return _requestBufferSize;
- }
-
- public void setRequestBufferSize(int requestBufferSize)
- {
- _requestBufferSize = requestBufferSize;
- }
-
- public int getResponseHeaderSize()
- {
- return _responseHeaderSize;
- }
-
- public void setResponseHeaderSize(int responseHeaderSize)
- {
- _responseHeaderSize = responseHeaderSize;
- }
-
- public int getResponseBufferSize()
- {
- return _responseBufferSize;
- }
-
- public void setResponseBufferSize(int responseBufferSize)
- {
- _responseBufferSize = responseBufferSize;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Allow the Listener a chance to customise the request. before the server
- * does its stuff.
- * This allows the required attributes to be set for SSL requests.
- * The requirements of the Servlet specs are:
- *
- *
an attribute named "javax.servlet.request.ssl_session_id" of type
- * String (since Servlet Spec 3.0).
- *
an attribute named "javax.servlet.request.cipher_suite" of type
- * String.
- *
an attribute named "javax.servlet.request.key_size" of type Integer.
- *
an attribute named "javax.servlet.request.X509Certificate" of type
- * java.security.cert.X509Certificate[]. This is an array of objects of type
- * X509Certificate, the order of this array is defined as being in ascending
- * order of trust. The first certificate in the chain is the one set by the
- * client, the next is the one used to authenticate the first, and so on.
- *
- *
- */
- public void customize(Request request) throws IOException
- {
- if (isSecure())
- {
- request.setScheme(HttpScheme.HTTPS.asString());
- SslConnection.DecryptedEndPoint ssl_endp = (SslConnection.DecryptedEndPoint)request.getHttpChannel().getEndPoint();
- SslConnection sslConnection = ssl_endp.getSslConnection();
- SSLEngine sslEngine=sslConnection.getSSLEngine();
- SslCertificates.customize(sslEngine,request);
- }
-
- request.setTimeStamp(System.currentTimeMillis());
- if (isForwarded())
- checkForwardedHeaders(request);
- }
-
- /* ------------------------------------------------------------ */
- protected void checkForwardedHeaders(Request request) throws IOException
- {
- HttpFields httpFields = request.getHttpFields();
-
- // Do SSL first
- if (getForwardedCipherSuiteHeader()!=null)
- {
- String cipher_suite=httpFields.getStringField(getForwardedCipherSuiteHeader());
- if (cipher_suite!=null)
- request.setAttribute("javax.servlet.request.cipher_suite",cipher_suite);
- }
- if (getForwardedSslSessionIdHeader()!=null)
- {
- String ssl_session_id=httpFields.getStringField(getForwardedSslSessionIdHeader());
- if(ssl_session_id!=null)
- {
- request.setAttribute("javax.servlet.request.ssl_session_id", ssl_session_id);
- request.setScheme(HttpScheme.HTTPS.asString());
- }
- }
-
- // Retrieving headers from the request
- String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader());
- String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader());
- String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader());
- String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader());
-
- if (_hostHeader != null)
- {
- // Update host header
- httpFields.put(HttpHeader.HOST.toString(),_hostHeader);
- request.setServerName(null);
- request.setServerPort(-1);
- request.getServerName();
- }
- else if (forwardedHost != null)
- {
- // Update host header
- httpFields.put(HttpHeader.HOST.toString(),forwardedHost);
- request.setServerName(null);
- request.setServerPort(-1);
- request.getServerName();
- }
- else if (forwardedServer != null)
- {
- // Use provided server name
- request.setServerName(forwardedServer);
- }
-
- if (forwardedFor != null)
- {
- request.setRemoteAddr(new InetSocketAddress(forwardedFor,request.getRemotePort()));
- }
-
- if (forwardedProto != null)
- {
- request.setScheme(forwardedProto);
- }
- }
-
- /* ------------------------------------------------------------ */
- protected String getLeftMostFieldValue(HttpFields fields, String header)
- {
- if (header == null)
- return null;
-
- String headerValue = fields.getStringField(header);
-
- if (headerValue == null)
- return null;
-
- int commaIndex = headerValue.indexOf(',');
-
- if (commaIndex == -1)
- {
- // Single value
- return headerValue;
- }
-
- // The left-most value is the farthest downstream client
- return headerValue.substring(0,commaIndex);
- }
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
- */
- public int getConfidentialPort()
- {
- return _confidentialPort;
- }
-
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.Connector#getConfidentialScheme()
- */
- public String getConfidentialScheme()
- {
- return _confidentialScheme;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * The request is integral IFF it is secure AND the server port
- * matches any configured {@link #getIntegralPort()}.
- * This allows separation of listeners providing INTEGRAL versus
- * CONFIDENTIAL constraints, such as one SSL listener configured to require
- * client certs providing CONFIDENTIAL, whereas another SSL listener not
- * requiring client certs providing mere INTEGRAL constraints.
- *
- * The request is secure if it is SSL or it {@link #isForwarded()} is true
- * and the scheme matches {@link #getIntegralScheme()()}
- */
- public boolean isIntegral(Request request)
- {
- boolean https = isSecure() || _forwarded && _integralScheme.equalsIgnoreCase(request.getScheme());
- int iPort=getIntegralPort();
- boolean port = iPort<=0||iPort==request.getServerPort();
- return https && port;
- }
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
- */
- public int getIntegralPort()
- {
- return _integralPort;
- }
-
- /* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.Connector#getIntegralScheme()
- */
- public String getIntegralScheme()
- {
- return _integralScheme;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * The request is confidential IFF it is secure AND the server port
- * matches any configured {@link #getConfidentialPort()}.
- * This allows separation of listeners providing INTEGRAL versus
- * CONFIDENTIAL constraints, such as one SSL listener configured to require
- * client certs providing CONFIDENTIAL, whereas another SSL listener not
- * requiring client certs providing mere INTEGRAL constraints.
- *
- * The request is secure if it is SSL or it {@link #isForwarded()} is true
- * and the scheme matches {@link #getConfidentialScheme()}
- */
- public boolean isConfidential(Request request)
- {
- boolean https = isSecure() || _forwarded && _confidentialScheme.equalsIgnoreCase(request.getScheme());
- int confidentialPort=getConfidentialPort();
- boolean port = confidentialPort<=0||confidentialPort==request.getServerPort();
- return https && port;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param confidentialPort
- * The confidentialPort to set.
- */
- public void setConfidentialPort(int confidentialPort)
- {
- _confidentialPort = confidentialPort;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param confidentialScheme
- * The confidentialScheme to set.
- */
- public void setConfidentialScheme(String confidentialScheme)
- {
- _confidentialScheme = confidentialScheme;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param integralPort
- * The integralPort to set.
- */
- public void setIntegralPort(int integralPort)
- {
- _integralPort = integralPort;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param integralScheme
- * The integralScheme to set.
- */
- public void setIntegralScheme(String integralScheme)
- {
- _integralScheme = integralScheme;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Is reverse proxy handling on?
- *
- * @return true if this connector is checking the x-forwarded-for/host/server headers
- */
- public boolean isForwarded()
- {
- return _forwarded;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Set reverse proxy handling. If set to true, then the X-Forwarded headers (or the headers set in their place) are looked for to set the request protocol,
- * host, server and client ip.
- *
- * @param check true if this connector is checking the x-forwarded-for/host/server headers
- * @see #setForwardedForHeader(String)
- * @see #setForwardedHostHeader(String)
- * @see #setForwardedProtoHeader(String)
- * @see #setForwardedServerHeader(String)
- */
- public void setForwarded(boolean check)
- {
- if (check)
- LOG.debug("{} is forwarded",this);
- _forwarded = check;
- }
-
- /* ------------------------------------------------------------ */
- public String getHostHeader()
- {
- return _hostHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
- * This value is only used if {@link #isForwarded()} is true.
- *
- * @param hostHeader
- * The value of the host header to force.
- */
- public void setHostHeader(String hostHeader)
- {
- _hostHeader = hostHeader;
- }
-
- /* ------------------------------------------------------------ */
- /*
- *
- * @see #setForwarded(boolean)
- */
- public String getForwardedHostHeader()
- {
- return _forwardedHostHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param forwardedHostHeader
- * The header name for forwarded hosts (default x-forwarded-host)
- * @see #setForwarded(boolean)
- */
- public void setForwardedHostHeader(String forwardedHostHeader)
- {
- _forwardedHostHeader = forwardedHostHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return the header name for forwarded server.
- * @see #setForwarded(boolean)
- */
- public String getForwardedServerHeader()
- {
- return _forwardedServerHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param forwardedServerHeader
- * The header name for forwarded server (default x-forwarded-server)
- * @see #setForwarded(boolean)
- */
- public void setForwardedServerHeader(String forwardedServerHeader)
- {
- _forwardedServerHeader = forwardedServerHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return the forwarded for header
- * @see #setForwarded(boolean)
- */
- public String getForwardedForHeader()
- {
- return _forwardedForHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param forwardedRemoteAddressHeader
- * The header name for forwarded for (default x-forwarded-for)
- * @see #setForwarded(boolean)
- */
- public void setForwardedForHeader(String forwardedRemoteAddressHeader)
- {
- _forwardedForHeader = forwardedRemoteAddressHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Get the forwardedProtoHeader.
- *
- * @return the forwardedProtoHeader (default X-Forwarded-For)
- * @see #setForwarded(boolean)
- */
- public String getForwardedProtoHeader()
- {
- return _forwardedProtoHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Set the forwardedProtoHeader.
- *
- * @param forwardedProtoHeader
- * the forwardedProtoHeader to set (default X-Forwarded-For)
- * @see #setForwarded(boolean)
- */
- public void setForwardedProtoHeader(String forwardedProtoHeader)
- {
- _forwardedProtoHeader = forwardedProtoHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return The header name holding a forwarded cipher suite (default null)
- */
- public String getForwardedCipherSuiteHeader()
- {
- return _forwardedCipherSuiteHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param forwardedCipherSuite
- * The header name holding a forwarded cipher suite (default null)
- */
- public void setForwardedCipherSuiteHeader(String forwardedCipherSuite)
- {
- _forwardedCipherSuiteHeader = forwardedCipherSuite;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return The header name holding a forwarded SSL Session ID (default null)
- */
- public String getForwardedSslSessionIdHeader()
- {
- return _forwardedSslSessionIdHeader;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param forwardedSslSessionId
- * The header name holding a forwarded SSL Session ID (default null)
- */
- public void setForwardedSslSessionIdHeader(String forwardedSslSessionId)
- {
- _forwardedSslSessionIdHeader = forwardedSslSessionId;
- }
-
-
- /* ------------------------------------------------------------ */
- @Override
- protected void doStart() throws Exception
- {
- if (_sslContextFactory!=null)
- {
- _sslContextFactory.checkKeyStore();
-
- super.doStart();
-
- SSLEngine sslEngine = _sslContextFactory.newSSLEngine();
-
- sslEngine.setUseClientMode(false);
-
- SSLSession sslSession = sslEngine.getSession();
-
- if (getRequestHeaderSize() __currentConnection = new ThreadLocal<>();
- private final HttpConfiguration _configuration;
+ private final HttpChannelConfig _config;
private final Connector _connector;
- private final ByteBufferPool _bufferPool; // TODO: remove field, use a _connector.getByteBufferPool()
+ private final ByteBufferPool _bufferPool;
private final HttpGenerator _generator;
private final HttpChannelOverHttp _channel;
private final HttpParser _parser;
- private ByteBuffer _requestBuffer = null;
- private ByteBuffer _chunk = null;
+ private volatile ByteBuffer _requestBuffer = null;
+ private volatile ByteBuffer _chunk = null;
public static HttpConnection getCurrentConnection()
{
@@ -67,12 +67,17 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
__currentConnection.set(connection);
}
+
+ public HttpChannelConfig getHttpChannelConfig()
+ {
+ return _config;
+ }
- public HttpConnection(HttpConfiguration config, Connector connector, EndPoint endPoint)
+ public HttpConnection(HttpChannelConfig config, Connector connector, EndPoint endPoint)
{
super(endPoint, connector.getExecutor());
- _configuration = config;
+ _config = config;
_connector = connector;
_bufferPool = _connector.getByteBufferPool();
_generator = new HttpGenerator(); // TODO: consider moving the generator to the transport, where it belongs
@@ -98,7 +103,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
return _connector;
}
- public HttpChannel getHttpChannel()
+ public HttpChannel> getHttpChannel()
{
return _channel;
}
@@ -145,8 +150,9 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
if (_requestBuffer != null && !_requestBuffer.hasRemaining())
{
- _bufferPool.release(_requestBuffer);
- _requestBuffer = null;
+ ByteBuffer buffer=_requestBuffer;
+ _requestBuffer=null;
+ _bufferPool.release(buffer);
}
}
@@ -175,7 +181,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
if (!event && BufferUtil.isEmpty(_requestBuffer))
{
if (_requestBuffer == null)
- _requestBuffer = _bufferPool.acquire(_configuration.getRequestHeaderSize(), false);
+ _requestBuffer = _bufferPool.acquire(getInputBufferSize(), false);
int filled = getEndPoint().fill(_requestBuffer);
if (filled==0) // Do a retry on fill 0 (optimisation for SSL connections)
@@ -315,7 +321,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
{
case NEED_HEADER:
{
- header = _bufferPool.acquire(_configuration.getResponseHeaderSize(), false);
+ header = _bufferPool.acquire(_config.getResponseHeaderSize(), false);
continue;
}
case NEED_CHUNK:
@@ -533,7 +539,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
// We will need a buffer to read into
if (_requestBuffer==null)
- _requestBuffer=_bufferPool.acquire(_configuration.getRequestBufferSize(),false);
+ _requestBuffer=_bufferPool.acquire(getInputBufferSize(),false);
// read some data
int filled=getEndPoint().fill(_requestBuffer);
@@ -590,9 +596,9 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
private class HttpChannelOverHttp extends HttpChannel
{
- public HttpChannelOverHttp(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input)
+ public HttpChannelOverHttp(Connector connector, HttpChannelConfig config, EndPoint endPoint, HttpTransport transport, HttpInput input)
{
- super(connector,configuration,endPoint,transport,input);
+ super(connector,config,endPoint,transport,input);
}
@Override
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java
similarity index 54%
rename from jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnectionFactory.java
rename to jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java
index 09784704d9a..9ef5d6a6b13 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnectionFactory.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java
@@ -19,39 +19,40 @@
package org.eclipse.jetty.server;
-import java.nio.channels.SocketChannel;
+import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
-public class HttpServerConnectionFactory implements ConnectionFactory
+public class HttpConnectionFactory extends AbstractConnectionFactory implements HttpChannelConfig.ConnectionFactory
{
- private final Connector connector;
- private final HttpConfiguration configuration;
+ private final HttpChannelConfig _config;
- public HttpServerConnectionFactory(Connector connector)
+ public HttpConnectionFactory()
{
- this(connector, new HttpConfiguration(connector.getSslContextFactory(), connector.getSslContextFactory() != null));
+ this(new HttpChannelConfig());
+ setInputBufferSize(16384);
}
- public HttpServerConnectionFactory(Connector connector, HttpConfiguration configuration)
+
+ public HttpConnectionFactory(HttpChannelConfig config)
{
- this.connector = connector;
- this.configuration = configuration;
+ super(HttpVersion.HTTP_1_1.toString());
+ _config=config;
+ addBean(_config);
}
-
- public Connector getConnector()
+
+ @Override
+ public HttpChannelConfig getHttpChannelConfig()
{
- return connector;
- }
-
- public HttpConfiguration getHttpConfiguration()
- {
- return configuration;
+ return _config;
}
@Override
- public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment)
+ public Connection newConnection(Connector connector, EndPoint endPoint)
{
- return new HttpConnection(getHttpConfiguration(), getConnector(), endPoint);
+ HttpConnection connection = new HttpConnection(_config, connector, endPoint);
+ connection.setInputBufferSize(getInputBufferSize()); // TODO constructor injection
+ return connection;
}
+
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
index 3fad5007748..98a86b8a017 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
@@ -20,6 +20,7 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.io.InterruptedIOException;
+
import javax.servlet.ServletInputStream;
import org.eclipse.jetty.io.EofException;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index 1a0b845f58e..631a09ddbd5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -22,6 +22,7 @@ import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
+
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
@@ -54,7 +55,7 @@ public class HttpOutput extends ServletOutputStream
public HttpOutput(HttpChannel channel)
{
_channel = channel;
- _bufferSize = _channel.getHttpConfiguration().getResponseBufferSize();
+ _bufferSize = _channel.getHttpChannelConfig().getOutputBufferSize();
}
public boolean isWritten()
@@ -209,7 +210,7 @@ public class HttpOutput extends ServletOutputStream
HttpContent httpContent = (HttpContent)content;
Response response = _channel.getResponse();
String contentType = httpContent.getContentType();
- if (contentType != null)
+ if (contentType != null && !response.getHttpFields().containsKey(HttpHeader.CONTENT_TYPE.asString()))
response.getHttpFields().put(HttpHeader.CONTENT_TYPE, contentType);
if (httpContent.getContentLength() > 0)
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java
index 19db4db28e8..c7f67174379 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java
@@ -27,19 +27,44 @@ import org.eclipse.jetty.util.thread.Scheduler;
public class HttpServerConnector extends SelectChannelConnector
{
- public HttpServerConnector(Server server)
+ public HttpServerConnector(
+ @Name("server") Server server)
{
- this(server, null);
+ this(server,null,null,null,null,null,0,0);
}
- public HttpServerConnector(Server server, SslContextFactory sslContextFactory)
+ public HttpServerConnector(
+ @Name("server") Server server,
+ @Name("sslContextFactory") SslContextFactory sslContextFactory)
{
- this(server, null, null, null, sslContextFactory, 0, 0);
+ this(server,null,sslContextFactory, null, null, null, 0, 0);
}
- public HttpServerConnector(@Name("server") Server server, @Name("executor") Executor executor, @Name("scheduler") Scheduler scheduler, @Name("bufferPool") ByteBufferPool pool, @Name("sslContextFactory") SslContextFactory sslContextFactory, @Name("acceptors") int acceptors, @Name("selectors") int selectors)
+ public HttpServerConnector(
+ @Name("server") Server server,
+ @Name("connectionFactory") HttpConnectionFactory connectionFactory)
{
- super(server, executor, scheduler, pool, sslContextFactory, acceptors, selectors);
- setDefaultConnectionFactory(new HttpServerConnectionFactory(this));
+ this(server,connectionFactory,null, null, null, null, 0, 0);
+ }
+
+ public HttpServerConnector(
+ @Name("server") Server server,
+ @Name("connectionFactory") HttpConnectionFactory connectionFactory,
+ @Name("sslContextFactory") SslContextFactory sslContextFactory)
+ {
+ this(server,connectionFactory,sslContextFactory, null, null, null, 0, 0);
+ }
+
+ public HttpServerConnector(
+ @Name("server") Server server,
+ @Name("connectionFactory") HttpConnectionFactory connectionFactory,
+ @Name("sslContextFactory") SslContextFactory sslContextFactory,
+ @Name("executor") Executor executor,
+ @Name("scheduler") Scheduler scheduler,
+ @Name("bufferPool") ByteBufferPool pool,
+ @Name("acceptors") int acceptors,
+ @Name("selectors") int selectors)
+ {
+ super(server,executor,scheduler,pool,acceptors,selectors,AbstractConnectionFactory.getFactories(sslContextFactory,connectionFactory==null?new HttpConnectionFactory():connectionFactory));
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
index 9764dd32a84..0cfec6445b4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java
@@ -25,13 +25,10 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -41,22 +38,31 @@ public class LocalConnector extends AbstractConnector
{
private final BlockingQueue _connects = new LinkedBlockingQueue<>();
+
+ public LocalConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, int acceptors, ConnectionFactory... factories)
+ {
+ super(server,executor,scheduler,pool,acceptors,factories);
+ setIdleTimeout(30000);
+ }
+
public LocalConnector(Server server)
{
- this(server,null);
+ this(server, null, null, null, 0, new HttpConnectionFactory());
}
public LocalConnector(Server server, SslContextFactory sslContextFactory)
{
- this(server, null, null, null, sslContextFactory, 0);
+ this(server, null, null, null, 0,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
}
- public LocalConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool,
- SslContextFactory sslContextFactory, int acceptors)
+ public LocalConnector(Server server, ConnectionFactory connectionFactory)
{
- super(server,executor,scheduler,pool, sslContextFactory, acceptors);
- setIdleTimeout(30000);
- setDefaultConnectionFactory(new HttpServerConnectionFactory(this));
+ this(server, null, null, null, 0, connectionFactory);
+ }
+
+ public LocalConnector(Server server, ConnectionFactory connectionFactory, SslContextFactory sslContextFactory)
+ {
+ this(server, null, null, null, 0,AbstractConnectionFactory.getFactories(sslContextFactory,connectionFactory));
}
@Override
@@ -159,29 +165,10 @@ public class LocalConnector extends AbstractConnector
LocalEndPoint endPoint = _connects.take();
endPoint.onOpen();
- SslContextFactory sslContextFactory = getSslContextFactory();
- if (sslContextFactory != null)
- {
- SSLEngine engine = sslContextFactory.newSSLEngine(endPoint.getRemoteAddress());
- engine.setUseClientMode(false);
-
- SslConnection sslConnection = new SslConnection(getByteBufferPool(), getExecutor(), endPoint, engine);
- endPoint.setConnection(sslConnection);
- connectionOpened(sslConnection);
- sslConnection.onOpen();
-
- EndPoint appEndPoint = sslConnection.getDecryptedEndPoint();
- Connection connection = getDefaultConnectionFactory().newConnection(null, appEndPoint, null);
- appEndPoint.setConnection(connection);
- connection.onOpen();
- }
- else
- {
- Connection connection = getDefaultConnectionFactory().newConnection(null, endPoint, null);
- endPoint.setConnection(connection);
- connectionOpened(connection);
- connection.onOpen();
- }
+ Connection connection = getDefaultConnectionFactory().newConnection(this, endPoint);
+ endPoint.setConnection(connection);
+ connectionOpened(connection);
+ connection.onOpen();
}
public class LocalEndPoint extends ByteArrayEndPoint
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
index dadf023485c..02594402957 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NCSARequestLog.java
@@ -24,6 +24,7 @@ import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.TimeZone;
+
import javax.servlet.http.Cookie;
import org.eclipse.jetty.http.HttpHeader;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index d38187f278f..4975a2c6008 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -37,6 +37,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+
import javax.servlet.AsyncContext;
import javax.servlet.AsyncListener;
import javax.servlet.DispatcherType;
@@ -118,28 +119,30 @@ public class Request implements HttpServletRequest
private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault());
private static final int __NONE = 0, _STREAM = 1, __READER = 2;
- private final HttpChannel _channel;
+ private final HttpChannel> _channel;
private final HttpFields _fields=new HttpFields();
private final List _requestAttributeListeners=new ArrayList<>();
- private final HttpInput _input;
+ private final HttpInput> _input;
+ private boolean _secure;
private boolean _asyncSupported = true;
+ private boolean _newContext;
+ private boolean _cookiesExtracted = false;
+ private boolean _handled = false;
+ private boolean _paramsExtracted;
+ private boolean _requestedSessionIdFromCookie = false;
private volatile Attributes _attributes;
private Authentication _authentication;
private MultiMap _baseParameters;
private String _characterEncoding;
private ContextHandler.Context _context;
- private boolean _newContext;
private String _contextPath;
private CookieCutter _cookies;
- private boolean _cookiesExtracted = false;
private DispatcherType _dispatcherType;
- private boolean _handled = false;
private int _inputState = __NONE;
private HttpMethod _httpMethod;
private String _httpMethodString;
private MultiMap _parameters;
- private boolean _paramsExtracted;
private String _pathInfo;
private int _port;
private HttpVersion _httpVersion = HttpVersion.HTTP_1_1;
@@ -149,7 +152,6 @@ public class Request implements HttpServletRequest
private String _readerEncoding;
private InetSocketAddress _remote;
private String _requestedSessionId;
- private boolean _requestedSessionIdFromCookie = false;
private String _requestURI;
private Map