Skip to content

Commit

Permalink
Add finer-grained configuration options to governator-jetty. (#395)
Browse files Browse the repository at this point in the history
* Add finer-grained configuration options to governator-jetty.

* Some updates from PR feedback.

* Preserve existing webAppResourceBase behavior while supporting classpath resource base.
  • Loading branch information
JackOfMostTrades authored and tcellucci committed Jun 29, 2019
1 parent 6f30d10 commit 72a2602
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ public interface Archaius2JettyConfig extends JettyConfig {
*/
@DefaultValue("/")
String getWebAppContextPath();

@DefaultValue("true")
boolean isUnencryptedSocketEnabled();

@DefaultValue("16384")
int getRequestHeaderSizeBytes();

String getBindToHost();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ public class DefaultJettyConfig implements JettyConfig {

private String webAppContextPath = "/";

private boolean unencryptedSocketEnabled = true;

private int requestHeaderSizeBytes = 16384;

private String bindToHost = null;

@Override
public int getPort() {
return port;
Expand All @@ -39,6 +45,21 @@ public String getWebAppContextPath() {
return webAppContextPath;
}

@Override
public boolean isUnencryptedSocketEnabled() {
return unencryptedSocketEnabled;
}

@Override
public int getRequestHeaderSizeBytes() {
return requestHeaderSizeBytes;
}

@Override
public String getBindToHost() {
return bindToHost;
}

public DefaultJettyConfig setPort(int port) {
this.port = port;
return this;
Expand Down Expand Up @@ -67,4 +88,19 @@ public DefaultJettyConfig setWebAppContextPath(String webAppContextPath) {
this.webAppContextPath = webAppContextPath;
return this;
}

public DefaultJettyConfig setUnencryptedSocketEnabled(boolean unencryptedSocketEnabled) {
this.unencryptedSocketEnabled = unencryptedSocketEnabled;
return this;
}

public DefaultJettyConfig setRequestHeaderSizeBytes(int requestHeaderSizeBytes) {
this.requestHeaderSizeBytes = requestHeaderSizeBytes;
return this;
}

public DefaultJettyConfig setBindToHost(String bindToHost) {
this.bindToHost = bindToHost;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,10 @@ public interface JettyConfig {
* @return the web app context path
*/
default String getWebAppContextPath() { return "/"; }


boolean isUnencryptedSocketEnabled();

int getRequestHeaderSizeBytes();

String getBindToHost();
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@

package com.netflix.governator.guice.jetty;

import java.util.EnumSet;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.servlet.DispatcherType;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.ProvisionException;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.servlet.GuiceFilter;
import com.netflix.governator.AbstractLifecycleListener;
import com.netflix.governator.LifecycleManager;
import com.netflix.governator.LifecycleShutdownSignal;
import com.netflix.governator.spi.LifecycleListener;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
Expand All @@ -23,15 +28,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.ProvisionException;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.servlet.GuiceFilter;
import com.netflix.governator.AbstractLifecycleListener;
import com.netflix.governator.LifecycleManager;
import com.netflix.governator.LifecycleShutdownSignal;
import com.netflix.governator.spi.LifecycleListener;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.servlet.DispatcherType;
import java.net.MalformedURLException;
import java.util.EnumSet;
import java.util.Set;

/**
* Installing JettyModule will create a Jetty web server within the context
Expand Down Expand Up @@ -82,6 +85,10 @@ private JettyConfig getConfig() {
*
*/
public final class JettyModule extends AbstractModule {

public final static String UNENCRYPTED_CONNECTOR_NAME = "unencrypted";

private final static String CLASSPATH_RESOURCE_PREFIX = "classpath:";
private final static Logger LOG = LoggerFactory.getLogger(JettyModule.class);

/**
Expand All @@ -100,7 +107,14 @@ public JettyRunner(Server server, final LifecycleManager manager) {
LOG.info("Jetty server starting");
try {
server.start();
port = ((ServerConnector)server.getConnectors()[0]).getLocalPort();
int port = -1;
for (Connector connector : server.getConnectors()) {
if (connector.getName().equals(UNENCRYPTED_CONNECTOR_NAME)) {
port = ((ServerConnector)connector).getLocalPort();
break;
}
}
this.port = port;
LOG.info("Jetty server on port {} started", port);
} catch (Exception e) {
try {
Expand Down Expand Up @@ -183,7 +197,21 @@ protected void configure() {
@Singleton
private Server getServer(OptionalJettyConfig optionalConfig, Set<JettyConnectorProvider> jettyConnectors) {
JettyConfig config = optionalConfig.getJettyConfig();
Server server = new Server(config.getPort());
Server server = new Server();

Resource webAppResourceBase = null;
if (config.getWebAppResourceBase() != null && !config.getWebAppResourceBase().isEmpty()) {
if (config.getWebAppResourceBase().startsWith(CLASSPATH_RESOURCE_PREFIX)) {
webAppResourceBase = Resource.newClassPathResource(config.getWebAppResourceBase().substring(CLASSPATH_RESOURCE_PREFIX.length()));
} else {
try {
webAppResourceBase = Resource.newResource(config.getWebAppResourceBase());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
}

Resource staticResourceBase = Resource.newClassPathResource(config.getStaticResourceBase());
if (staticResourceBase != null) {
// Set up a full web app since we have static content. We require the app to have its static content
Expand All @@ -194,7 +222,7 @@ private Server getServer(OptionalJettyConfig optionalConfig, Set<JettyConnectorP
webAppContext.setThrowUnavailableOnStartupException(true);
webAppContext.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
webAppContext.addServlet(DefaultServlet.class, "/");
webAppContext.setResourceBase(config.getWebAppResourceBase());
webAppContext.setBaseResource(webAppResourceBase);
webAppContext.setContextPath(config.getWebAppContextPath());
webAppContext.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, ".*\\.jar$");
webAppContext.setConfigurations(new Configuration[]{
Expand All @@ -210,15 +238,34 @@ private Server getServer(OptionalJettyConfig optionalConfig, Set<JettyConnectorP
new ServletContextHandler(server, config.getWebAppContextPath(), ServletContextHandler.SESSIONS);
servletContextHandler.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
servletContextHandler.addServlet(DefaultServlet.class, "/");
servletContextHandler.setResourceBase(config.getWebAppResourceBase());
servletContextHandler.setBaseResource(webAppResourceBase);
}

if (config.isUnencryptedSocketEnabled()) {
ServerConnector connector = new ServerConnector(server);
connector.setName(UNENCRYPTED_CONNECTOR_NAME);
connector.setPort(config.getPort());
if (config.getBindToHost() != null && !config.getBindToHost().isEmpty()) {
connector.setHost(config.getBindToHost());
}
HttpConfiguration httpConfiguration = ((HttpConnectionFactory)connector.getConnectionFactory(HttpVersion.HTTP_1_1.asString())).getHttpConfiguration();
httpConfiguration.setRequestHeaderSize(config.getRequestHeaderSizeBytes());
server.addConnector(connector);
}

if (jettyConnectors != null) {
for (JettyConnectorProvider connectorProvider : jettyConnectors) {
server.addConnector(connectorProvider.getConnector(server));
Connector connector = connectorProvider.getConnector(server);
if (connector != null) {
server.addConnector(connector);
}
}
}

if (server.getConnectors().length == 0) {
throw new IllegalStateException("No connectors have been configured. Either set unencryptedSocketEnabled=true or bind a JettyConnectorProvider");
}

return server;
}

Expand Down

0 comments on commit 72a2602

Please sign in to comment.