diff --git a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/Archaius2JettyConfig.java b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/Archaius2JettyConfig.java index 6a4ea574..1e6cfaff 100644 --- a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/Archaius2JettyConfig.java +++ b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/Archaius2JettyConfig.java @@ -6,6 +6,8 @@ @Configuration(prefix="governator.jetty.embedded") public interface Archaius2JettyConfig extends JettyConfig { + String getHost(); + @DefaultValue("8080") int getPort(); diff --git a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/DefaultJettyConfig.java b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/DefaultJettyConfig.java index 9cb09d5c..d2f675ee 100644 --- a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/DefaultJettyConfig.java +++ b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/DefaultJettyConfig.java @@ -5,6 +5,8 @@ @Singleton public class DefaultJettyConfig implements JettyConfig { private int port = 8080; + + private String host; // Where static files live. We pass this to Jetty for class path scanning to find the exact directory. // The default is to use resources supported by the servlet 3.0 spec. @@ -14,6 +16,11 @@ public class DefaultJettyConfig implements JettyConfig { private String webAppContextPath = "/"; + @Override + public String getHost() { + return host; + } + @Override public int getPort() { return port; @@ -39,6 +46,11 @@ public String getWebAppContextPath() { return webAppContextPath; } + public DefaultJettyConfig setHost(String host) { + this.host = host; + return this; + } + public DefaultJettyConfig setPort(int port) { this.port = port; return this; diff --git a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyConfig.java b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyConfig.java index 800f753a..18dbbd23 100644 --- a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyConfig.java +++ b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyConfig.java @@ -2,6 +2,8 @@ public interface JettyConfig { + String getHost(); + int getPort(); /** diff --git a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyModule.java b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyModule.java index 33d21960..059cc113 100644 --- a/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyModule.java +++ b/governator-jetty/src/main/java/com/netflix/governator/guice/jetty/JettyModule.java @@ -1,6 +1,8 @@ package com.netflix.governator.guice.jetty; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.util.EnumSet; import java.util.Set; @@ -183,7 +185,12 @@ protected void configure() { @Singleton private Server getServer(OptionalJettyConfig optionalConfig, Set jettyConnectors) { JettyConfig config = optionalConfig.getJettyConfig(); - Server server = new Server(config.getPort()); + Server server; + if (config.getHost() != null) { + server = new Server(new InetSocketAddress(config.getHost(), config.getPort())); + } else { + server = new Server(config.getPort()); + } 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 diff --git a/governator-jetty/src/test/java/com/netflix/governator/guice/jetty/JettyServerTest.java b/governator-jetty/src/test/java/com/netflix/governator/guice/jetty/JettyServerTest.java index 7db708f0..e1144c60 100644 --- a/governator-jetty/src/test/java/com/netflix/governator/guice/jetty/JettyServerTest.java +++ b/governator-jetty/src/test/java/com/netflix/governator/guice/jetty/JettyServerTest.java @@ -120,6 +120,37 @@ JettyConfig getConfig() { injector.close(); } + + @Test + public void testExplicitHostConnectorBinding() throws Exception { + LifecycleInjector injector = InjectorBuilder.fromModules( + new SampleServletModule(), + new ShutdownHookModule(), + Modules.override(new JettyModule()) + .with(new AbstractModule() { + @Override + protected void configure() { + } + + @Provides + JettyConfig getConfig() { + // Use ephemeral ports + return new DefaultJettyConfig().setPort(0).setHost("127.0.0.1"); + } + }) + ).createInjector(); + + Server server = injector.getInstance(Server.class); + Assert.assertEquals(1, server.getConnectors().length); + + int port = ((ServerConnector)server.getConnectors()[0]).getLocalPort(); + + // Do a plaintext GET and verify that the default connector works + String response = doGet(String.format("http://127.0.0.1:%d/", port), null); + Assert.assertTrue(response.startsWith("hello ")); + + injector.close(); + } private static String doGet(String url, KeyStore sslTrustStore) throws Exception {