summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2022-10-07 14:54:01 +0200
committerBjørn Christian Seime <bjorncs@yahooinc.com>2022-10-07 15:22:00 +0200
commitea880e5a8b25e10b3b72e1a4068a92d54d986ca5 (patch)
treeeafcf897e5514e9bee051a968a1572004f66a18a /container-core
parent43634441529d078fb8c7156356e7d96d299694a4 (diff)
Create separate Jetty handler chain for each connector
Use connector name and virtual hosts configuration to route requests between handler chains.
Diffstat (limited to 'container-core')
-rw-r--r--container-core/abi-spec.json10
-rw-r--r--container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java109
-rw-r--r--container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def2
3 files changed, 77 insertions, 44 deletions
diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json
index bbee5ffd7da..d324656abf2 100644
--- a/container-core/abi-spec.json
+++ b/container-core/abi-spec.json
@@ -1202,9 +1202,13 @@
"public void <init>()",
"public void <init>(com.yahoo.jdisc.http.ConnectorConfig$ServerName)",
"public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder fallback(java.lang.String)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder allowed(java.lang.String)",
+ "public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder allowed(java.util.Collection)",
"public com.yahoo.jdisc.http.ConnectorConfig$ServerName build()"
],
- "fields": []
+ "fields": [
+ "public java.util.List allowed"
+ ]
},
"com.yahoo.jdisc.http.ConnectorConfig$ServerName": {
"superClass": "com.yahoo.config.InnerNode",
@@ -1215,7 +1219,9 @@
],
"methods": [
"public void <init>(com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder)",
- "public java.lang.String fallback()"
+ "public java.lang.String fallback()",
+ "public java.util.List allowed()",
+ "public java.lang.String allowed(int)"
],
"fields": []
},
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
index dd5181d2bb5..c0b3a336a39 100644
--- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
+++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java
@@ -14,11 +14,13 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.jmx.ConnectorServer;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHttpOutputInterceptor;
@@ -83,20 +85,13 @@ public class JettyHttpServer extends AbstractServerProvider {
listenedPorts.add(connectorConfig.listenPort());
}
- JDiscContext jDiscContext = new JDiscContext(filterBindings,
- container,
- janitor,
- metric,
- serverConfig);
+ JDiscContext jDiscContext = new JDiscContext(filterBindings, container, janitor, metric, serverConfig);
ServletHolder jdiscServlet = new ServletHolder(new JDiscHttpServlet(jDiscContext));
List<JDiscServerConnector> connectors = Arrays.stream(server.getConnectors())
.map(JDiscServerConnector.class::cast)
.collect(toList());
-
- server.setHandler(getHandlerCollection(serverConfig,
- connectors,
- jdiscServlet));
+ server.setHandler(createRootHandler(serverConfig, connectors, jdiscServlet));
this.metricsReporter = new ServerMetricReporter(metric, server);
}
@@ -136,38 +131,37 @@ public class JettyHttpServer extends AbstractServerProvider {
}
}
- private HandlerCollection getHandlerCollection(ServerConfig serverConfig,
- List<JDiscServerConnector> connectors,
- ServletHolder jdiscServlet) {
- ServletContextHandler servletContextHandler = createServletContextHandler();
- servletContextHandler.addServlet(jdiscServlet, "/*");
-
- var proxyHandler = new HealthCheckProxyHandler(connectors);
- proxyHandler.setHandler(servletContextHandler);
-
- List<ConnectorConfig> connectorConfigs = connectors.stream().map(JDiscServerConnector::connectorConfig).collect(toList());
- var authEnforcer = new TlsClientAuthenticationEnforcer(connectorConfigs);
- authEnforcer.setHandler(proxyHandler);
-
- GzipHandler gzipHandler = newGzipHandler(serverConfig);
- gzipHandler.setHandler(authEnforcer);
-
- var statisticsCollector = new HttpResponseStatisticsCollector(serverConfig.metric());
- statisticsCollector.setHandler(gzipHandler);
-
- StatisticsHandler statisticsHandler = newStatisticsHandler();
- statisticsHandler.setHandler(statisticsCollector);
-
- HandlerCollection handlerCollection = new HandlerCollection();
- handlerCollection.setHandlers(new Handler[] { statisticsHandler });
- return handlerCollection;
+ private HandlerCollection createRootHandler(
+ ServerConfig serverCfg, List<JDiscServerConnector> connectors, ServletHolder jdiscServlet) {
+ List<ConnectorConfig> connectorCfgs = connectors.stream().map(JDiscServerConnector::connectorConfig).toList();
+ List<ContextHandler> perConnectorHandlers = new ArrayList<>();
+ for (JDiscServerConnector connector : connectors) {
+ ConnectorConfig connectorCfg = connector.connectorConfig();
+ List<HandlerWrapper> chain = new ArrayList<>();
+ chain.add(newGenericStatisticsHandler());
+ chain.add(newResponseStatisticsHandler(serverCfg));
+ chain.add(newGzipHandler(serverCfg));
+ if (connectorCfg.tlsClientAuthEnforcer().enable()) {
+ chain.add(newTlsClientAuthEnforcerHandler(connectorCfgs));
+ }
+ if (connectorCfg.healthCheckProxy().enable()) {
+ chain.add(newHealthCheckProxyHandler(connectors));
+ } else {
+ chain.add(newServletHandler(jdiscServlet));
+ }
+ ContextHandler connectorRoot = newConnectorContextHandler(connector, connectorCfg);
+ addChainToRoot(connectorRoot, chain);
+ perConnectorHandlers.add(connectorRoot);
+ }
+ return new ContextHandlerCollection(perConnectorHandlers.toArray(new ContextHandler[0]));
}
- private ServletContextHandler createServletContextHandler() {
- ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.NO_SECURITY | ServletContextHandler.NO_SESSIONS);
- servletContextHandler.setContextPath("/");
- servletContextHandler.setDisplayName(getDisplayName(listenedPorts));
- return servletContextHandler;
+ private static void addChainToRoot(ContextHandler root, List<HandlerWrapper> chain) {
+ HandlerWrapper parent = root;
+ for (HandlerWrapper h : chain) {
+ parent.setHandler(h);
+ parent = h;
+ }
}
private static String getDisplayName(List<Integer> ports) {
@@ -229,13 +223,44 @@ public class JettyHttpServer extends AbstractServerProvider {
Server server() { return server; }
- private StatisticsHandler newStatisticsHandler() {
+ private ServletContextHandler newServletHandler(ServletHolder servlet) {
+ var h = new ServletContextHandler(ServletContextHandler.NO_SECURITY | ServletContextHandler.NO_SESSIONS);
+ h.setContextPath("/");
+ h.setDisplayName(getDisplayName(listenedPorts));
+ h.addServlet(servlet, "/*");
+ return h;
+ }
+
+ private static ContextHandler newConnectorContextHandler(JDiscServerConnector connector, ConnectorConfig connectorCfg) {
+ ContextHandler ctxHandler = new ContextHandler();
+ List<String> allowedServerNames = connectorCfg.serverName().allowed();
+ if (allowedServerNames.isEmpty()) {
+ ctxHandler.setVirtualHosts(new String[]{"@%s".formatted(connector.getName())});
+ } else {
+ ctxHandler.setVirtualHosts(allowedServerNames.toArray(new String[0]));
+ }
+ return ctxHandler;
+ }
+
+ private static HealthCheckProxyHandler newHealthCheckProxyHandler(List<JDiscServerConnector> connectors) {
+ return new HealthCheckProxyHandler(connectors);
+ }
+
+ private static TlsClientAuthenticationEnforcer newTlsClientAuthEnforcerHandler(List<ConnectorConfig> connectorCfgs) {
+ return new TlsClientAuthenticationEnforcer(connectorCfgs);
+ }
+
+ private static HttpResponseStatisticsCollector newResponseStatisticsHandler(ServerConfig cfg) {
+ return new HttpResponseStatisticsCollector(cfg.metric());
+ }
+
+ private static StatisticsHandler newGenericStatisticsHandler() {
StatisticsHandler statisticsHandler = new StatisticsHandler();
statisticsHandler.statsReset();
return statisticsHandler;
}
- private GzipHandler newGzipHandler(ServerConfig serverConfig) {
+ private static GzipHandler newGzipHandler(ServerConfig serverConfig) {
GzipHandler gzipHandler = new GzipHandlerWithVaryHeaderFixed();
gzipHandler.setCompressionLevel(serverConfig.responseCompressionLevel());
gzipHandler.setInflateBufferSize(8 * 1024);
diff --git a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def
index c0ad425fcc7..ecbc451ead1 100644
--- a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def
+++ b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def
@@ -132,3 +132,5 @@ http2.maxConcurrentStreams int default=4096
# Override the default server name when authority is missing from request.
serverName.fallback string default=""
+# The list of accepted server names. Empty list to accept any. Elements follows format of 'serverName.default'.
+serverName.allowed[] string