From 34c439f6947b9876a4c957df70fc42efcb6af932 Mon Sep 17 00:00:00 2001 From: Roberto E. Escobar Date: Thu, 26 Feb 2015 13:48:23 -0700 Subject: feature[ats_ATS181002]: Add Jetty request forwarding support Add jetty.server.name [serverName:port] Add jetty.http.is.forwarded [true/false] Add jetty.http.is.forwarded [true/false] Jetty server configuration options to support servers sitting behind reverse proxy server. Change-Id: I692a9a876ca7076859cd6654fc569504d16ee841 --- .../eclipse/osee/http/jetty/AllJettyTestSuite.java | 6 +- .../osee/http/jetty/JettyForwardedServerTest.java | 202 +++++++++++++++++++++ .../osee/http/jetty/JettyServerBuilderTest.java | 53 ++++++ .../org/eclipse/osee/http/jetty/JettyConfig.java | 53 +++++- .../eclipse/osee/http/jetty/JettyConstants.java | 6 + .../org/eclipse/osee/http/jetty/JettyServer.java | 15 ++ .../http/jetty/internal/JettyServerFactory.java | 22 ++- 7 files changed, 352 insertions(+), 5 deletions(-) create mode 100644 plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyForwardedServerTest.java diff --git a/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/AllJettyTestSuite.java b/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/AllJettyTestSuite.java index e2bd1b3a38b..f83952810ed 100644 --- a/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/AllJettyTestSuite.java +++ b/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/AllJettyTestSuite.java @@ -17,7 +17,11 @@ import org.junit.runners.Suite; * @author Roberto E. Escobar */ @RunWith(Suite.class) -@Suite.SuiteClasses({JettyServerBuilderTest.class, JettyServerTest.class, JettyJdbcSessionServerTest.class}) +@Suite.SuiteClasses({ + JettyServerBuilderTest.class, + JettyServerTest.class, + JettyJdbcSessionServerTest.class, + JettyForwardedServerTest.class}) public class AllJettyTestSuite { // Test Suite } diff --git a/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyForwardedServerTest.java b/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyForwardedServerTest.java new file mode 100644 index 00000000000..7e570ba9b5f --- /dev/null +++ b/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyForwardedServerTest.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2015 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.http.jetty; + +import static org.eclipse.jetty.http.HttpHeaders.X_FORWARDED_HOST; +import static org.eclipse.jetty.http.HttpHeaders.X_FORWARDED_PROTO; +import static org.junit.Assert.assertEquals; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.MediaType; +import org.eclipse.osee.jaxrs.client.JaxRsClient; +import org.eclipse.osee.jaxrs.client.JaxRsWebTarget; +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +/** + * Test case for {@link JettyServer} + * + * @author Roberto E. Escobar + */ +public class JettyForwardedServerTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TestName testMethod = new TestName(); + + private JettyServer httpServer; + + @After + public void tearDown() { + if (httpServer != null) { + httpServer.stop(); + } + } + + @Test + public void testHttpForwardThroughHeader() throws IOException { + File workingDir = folder.newFolder("jetty.dir." + testMethod.getMethodName()); + httpServer = JettyServer.newBuilder()// + .useRandomHttpPort(true)// + .workingDirectory(workingDir.getAbsolutePath())// + .httpForwarded(true)// + .build() // + .addServlet("test", new ServerNameServlet()); + + httpServer.start(); + + int httpPort = httpServer.getConfig().getHttpPort(); + String address = String.format("http://localhost:%s/test", httpPort); + + JaxRsWebTarget target = JaxRsClient.newClient().target(address); + + // Request with no forwarding headers + Data data = target.request(MediaType.APPLICATION_JSON_TYPE).get(Data.class); + + assertEquals("http", data.getScheme()); + assertEquals("localhost", data.getName()); + assertEquals(httpPort, data.getPort()); + + String reverseProxyAddress = "myserver1:34"; + String reverseProxyProtocol = "https"; + + // Request from forwarding server + data = target.request(MediaType.APPLICATION_JSON_TYPE)// + .header(X_FORWARDED_HOST, reverseProxyAddress)// + .header(X_FORWARDED_PROTO, reverseProxyProtocol)// + .get(Data.class); + + assertEquals(reverseProxyProtocol, data.getScheme()); + assertEquals("myserver1", data.getName()); + assertEquals(34, data.getPort()); + + reverseProxyAddress = "myserver2"; + reverseProxyProtocol = "http"; + + // Request from another forwarding server + data = target.request(MediaType.APPLICATION_JSON_TYPE)// + .header(X_FORWARDED_HOST, reverseProxyAddress)// + .header(X_FORWARDED_PROTO, reverseProxyProtocol)// + .get(Data.class); + + assertEquals(reverseProxyProtocol, data.getScheme()); + assertEquals("myserver2", data.getName()); + assertEquals(80, data.getPort()); + } + + @Test + public void testHttpStaticServerName() throws IOException { + String serverName = "static_server_name:45"; + + File workingDir = folder.newFolder("jetty.dir." + testMethod.getMethodName()); + httpServer = JettyServer.newBuilder()// + .useRandomHttpPort(true)// + .workingDirectory(workingDir.getAbsolutePath())// + .serverName(serverName)// + .build() // + .addServlet("test", new ServerNameServlet()); + + httpServer.start(); + + int httpPort = httpServer.getConfig().getHttpPort(); + String address = String.format("http://localhost:%s/test", httpPort); + + JaxRsWebTarget target = JaxRsClient.newClient().target(address); + + // Request with no forwarding headers + Data data = target.request(MediaType.APPLICATION_JSON_TYPE).get(Data.class); + + assertEquals("http", data.getScheme()); + assertEquals("static_server_name", data.getName()); + assertEquals(45, data.getPort()); + + String reverseProxyAddress = "myserver1:34"; + String reverseProxyProtocol = "https"; + + // Request from forwarding server -- host header should be ignored since we are using a static server name + data = target.request(MediaType.APPLICATION_JSON_TYPE)// + .header(X_FORWARDED_HOST, reverseProxyAddress)// + .header(X_FORWARDED_PROTO, reverseProxyProtocol)// + .get(Data.class); + + assertEquals("https", data.getScheme()); + assertEquals("static_server_name", data.getName()); + assertEquals(45, data.getPort()); + } + + public static class Data { + private String scheme; + private String name; + private int port; + + public String getScheme() { + return scheme; + } + + public String getName() { + return name; + } + + public int getPort() { + return port; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + public void setName(String name) { + this.name = name; + } + + public void setPort(int port) { + this.port = port; + } + + } + + private static class ServerNameServlet extends HttpServlet { + + private static final long serialVersionUID = 1744534541625281931L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType(MediaType.APPLICATION_JSON); + PrintWriter writer = response.getWriter(); + writer.write("{\n"); + writer.write("\"scheme\":\""); + writer.write(request.getScheme()); + writer.write("\",\n"); + writer.write("\"name\":\""); + writer.write(request.getServerName()); + writer.write("\",\n"); + writer.write("\"port\":"); + writer.write(String.valueOf(request.getServerPort())); + writer.write("\n"); + writer.write("}"); + } finally { + response.flushBuffer(); + } + } + + } +} diff --git a/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyServerBuilderTest.java b/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyServerBuilderTest.java index c354e115581..60ae44afbf3 100644 --- a/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyServerBuilderTest.java +++ b/plugins/org.eclipse.osee.http.jetty.test/src/org/eclipse/osee/http/jetty/JettyServerBuilderTest.java @@ -14,16 +14,19 @@ import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__CONTEXT_ import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__CONTEXT_SESSION_INACTIVE_INTERVAL; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_USE_RANDOM_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_NIO_AUTO_DETECT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_NIO_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_USE_RANDOM_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__MULTIPLE_SLASH_TO_SINGLE; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__OTHER_INFO; +import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SERVER_NAME; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SSL_KEYPASSWORD; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SSL_KEYSTORE; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SSL_KEYSTORETYPE; @@ -36,10 +39,12 @@ import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__CONTEXT_PATH; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__CONTEXT_SESSION_INACTIVE_INTERVAL; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_USE_RANDOM_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_NIO_AUTO_DETECT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_NIO_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_PORT; @@ -80,6 +85,7 @@ import org.mockito.MockitoAnnotations; */ public class JettyServerBuilderTest { + private static final String SERVER_NAME = "myserver.com"; private static final String CONTEXT = "mycontext"; private static final int SESSION_INACTIVE_INTERVAL = 10000; @@ -130,6 +136,9 @@ public class JettyServerBuilderTest { public void testDefaults() { JettyConfig config = builder; + assertEquals(DEFAULT_JETTY__SERVER_NAME, config.getServerName()); + assertEquals(false, config.hasServerName()); + assertEquals(DEFAULT_JETTY__CONTEXT_PATH, config.getContextPath()); assertEquals(DEFAULT_JETTY__CONTEXT_SESSION_INACTIVE_INTERVAL, config.getContextSessioninactiveinterval()); assertEquals(DEFAULT_JETTY__HTTP_HOST, config.getHttpHost()); @@ -153,11 +162,14 @@ public class JettyServerBuilderTest { assertEquals(DEFAULT_JETTY__SSL_NEEDS_CLIENT_AUTH, config.isSslNeedClientAuth()); assertEquals(DEFAULT_JETTY__SSL_WANTS_CLIENT_AUTH, config.isSslWantClientAuth()); assertEquals(DEFAULT_JETTY__MULTIPLE_SLASH_TO_SINGLE, config.isMultipleSlashToSingle()); + assertEquals(DEFAULT_JETTY__HTTP_IS_FORWARDED, config.isHttpForwarded()); + assertEquals(DEFAULT_JETTY__HTTPS_IS_FORWARDED, config.isHttpsForwarded()); assertTrue(config.getOtherProps().isEmpty()); } @Test public void testFields() { + builder.serverName(SERVER_NAME); builder.contextPath(CONTEXT); builder.contextSessionInactiveInterval(SESSION_INACTIVE_INTERVAL); builder.autoDetectNioSupport(HTTP_NIO_AUTO_DETECT); @@ -183,10 +195,13 @@ public class JettyServerBuilderTest { builder.extraParams(map("a", 1, "b", 2)); builder.logging(true); builder.replaceMultipleSlashesWithSingle(false); + builder.httpForwarded(false); + builder.httpsForwarded(false); JettyServer actual = builder.build(); JettyConfig config = actual.getConfig(); + assertEquals(SERVER_NAME, config.getServerName()); assertEquals(CONTEXT, config.getContextPath()); assertEquals(SESSION_INACTIVE_INTERVAL, config.getContextSessioninactiveinterval()); assertEquals(HTTP_HOST, config.getHttpHost()); @@ -210,6 +225,8 @@ public class JettyServerBuilderTest { assertEquals(SSL_WANTS_CLIENT_AUTH, config.isSslWantClientAuth()); assertEquals(WORKING_DIRECTORY, config.getWorkingDirectory()); assertEquals(false, config.isMultipleSlashToSingle()); + assertEquals(false, config.isHttpForwarded()); + assertEquals(false, config.isHttpsForwarded()); verify(sessionManager).setMaxInactiveInterval(config.getContextSessioninactiveinterval()); assertMapEquals(config.getOtherProps(), "a", 1, "b", 2); @@ -217,6 +234,8 @@ public class JettyServerBuilderTest { builder.useRandomHttpPort(true); builder.useRandomHttpsPort(true); builder.replaceMultipleSlashesWithSingle(true); + builder.httpForwarded(true); + builder.httpsForwarded(true); actual = builder.build(); config = actual.getConfig(); @@ -230,12 +249,16 @@ public class JettyServerBuilderTest { assertEquals(true, config.isRandomHttpPort()); assertEquals(true, config.isRandomHttpsPort()); assertEquals(true, config.isMultipleSlashToSingle()); + assertEquals(true, config.isHttpForwarded()); + assertEquals(true, config.isHttpsForwarded()); } @Test public void testConfigProperties() { Map props = new HashMap(); + add(props, JettyConstants.JETTY__SERVER_NAME, SERVER_NAME); + add(props, JETTY__HTTP_NIO_ENABLED, HTTP_NIO_ENABLED); add(props, JETTY__HTTP_NIO_AUTO_DETECT, HTTP_NIO_AUTO_DETECT); add(props, JETTY__HTTP_ENABLED, HTTP_ENABLED); @@ -258,6 +281,8 @@ public class JettyServerBuilderTest { add(props, JETTY__OTHER_INFO, OTHER_INFO); add(props, JETTY__WORKING_DIRECTORY, WORKING_DIRECTORY); add(props, JETTY__MULTIPLE_SLASH_TO_SINGLE, false); + add(props, JETTY__HTTP_IS_FORWARDED, false); + add(props, JETTY__HTTPS_IS_FORWARDED, false); add(props, "a", 1); add(props, "b", 2); @@ -270,6 +295,8 @@ public class JettyServerBuilderTest { JettyServer actual = builder.build(); JettyConfig config = actual.getConfig(); + assertEquals(SERVER_NAME, config.getServerName()); + assertEquals(CONTEXT, config.getContextPath()); assertEquals(SESSION_INACTIVE_INTERVAL, config.getContextSessioninactiveinterval()); assertEquals(HTTP_HOST, config.getHttpHost()); @@ -293,6 +320,8 @@ public class JettyServerBuilderTest { assertEquals(SSL_WANTS_CLIENT_AUTH, config.isSslWantClientAuth()); assertEquals(WORKING_DIRECTORY, config.getWorkingDirectory()); assertEquals(false, config.isMultipleSlashToSingle()); + assertEquals(false, config.isHttpForwarded()); + assertEquals(false, config.isHttpsForwarded()); verify(sessionManager).setMaxInactiveInterval(config.getContextSessioninactiveinterval()); assertMapEquals(config.getOtherProps(), "a", "1", "b", "2"); @@ -304,6 +333,8 @@ public class JettyServerBuilderTest { add(props, JETTY__HTTPS_USE_RANDOM_PORT, true); add(props, JETTY__MULTIPLE_SLASH_TO_SINGLE, true); + add(props, JETTY__HTTP_IS_FORWARDED, true); + add(props, JETTY__HTTPS_IS_FORWARDED, true); builder.properties(props); @@ -319,10 +350,13 @@ public class JettyServerBuilderTest { assertEquals(true, config.isRandomHttpPort()); assertEquals(true, config.isRandomHttpsPort()); assertEquals(true, config.isMultipleSlashToSingle()); + assertEquals(true, config.isHttpForwarded()); + assertEquals(true, config.isHttpsForwarded()); } @Test public void testNoChangeAfterBuild() { + builder.serverName(SERVER_NAME); builder.contextPath(CONTEXT); builder.contextSessionInactiveInterval(SESSION_INACTIVE_INTERVAL); builder.autoDetectNioSupport(HTTP_NIO_AUTO_DETECT); @@ -348,10 +382,14 @@ public class JettyServerBuilderTest { builder.extraParams(map("a", 1, "b", 2)); builder.logging(true); builder.replaceMultipleSlashesWithSingle(false); + builder.httpForwarded(true); + builder.httpsForwarded(true); JettyServer actual = builder.build(); JettyConfig config = actual.getConfig(); + assertEquals(SERVER_NAME, config.getServerName()); + assertEquals(CONTEXT, config.getContextPath()); assertEquals(SESSION_INACTIVE_INTERVAL, config.getContextSessioninactiveinterval()); assertEquals(HTTP_HOST, config.getHttpHost()); @@ -375,12 +413,16 @@ public class JettyServerBuilderTest { assertEquals(SSL_WANTS_CLIENT_AUTH, config.isSslWantClientAuth()); assertEquals(WORKING_DIRECTORY, config.getWorkingDirectory()); assertEquals(false, config.isMultipleSlashToSingle()); + assertEquals(true, config.isHttpForwarded()); + assertEquals(true, config.isHttpsForwarded()); verify(sessionManager).setMaxInactiveInterval(config.getContextSessioninactiveinterval()); assertMapEquals(config.getOtherProps(), "a", 1, "b", 2); builder.readProperties(Collections. emptyMap()); + assertEquals(SERVER_NAME, config.getServerName()); + assertEquals(CONTEXT, config.getContextPath()); assertEquals(SESSION_INACTIVE_INTERVAL, config.getContextSessioninactiveinterval()); assertEquals(HTTP_HOST, config.getHttpHost()); @@ -404,6 +446,8 @@ public class JettyServerBuilderTest { assertEquals(SSL_WANTS_CLIENT_AUTH, config.isSslWantClientAuth()); assertEquals(WORKING_DIRECTORY, config.getWorkingDirectory()); assertEquals(false, config.isMultipleSlashToSingle()); + assertEquals(true, config.isHttpForwarded()); + assertEquals(true, config.isHttpsForwarded()); verify(sessionManager).setMaxInactiveInterval(config.getContextSessioninactiveinterval()); assertMapEquals(config.getOtherProps(), "a", 1, "b", 2); @@ -411,6 +455,7 @@ public class JettyServerBuilderTest { @Test public void testFromConfig() { + builder.serverName(SERVER_NAME); builder.contextPath(CONTEXT); builder.contextSessionInactiveInterval(SESSION_INACTIVE_INTERVAL); builder.autoDetectNioSupport(HTTP_NIO_AUTO_DETECT); @@ -436,10 +481,13 @@ public class JettyServerBuilderTest { builder.extraParams(map("a", 1, "b", 2)); builder.logging(true); builder.replaceMultipleSlashesWithSingle(false); + builder.httpForwarded(true); + builder.httpsForwarded(true); JettyServer actual = builder.build(); JettyConfig config1 = actual.getConfig(); + assertEquals(SERVER_NAME, config1.getServerName()); assertEquals(CONTEXT, config1.getContextPath()); assertEquals(SESSION_INACTIVE_INTERVAL, config1.getContextSessioninactiveinterval()); assertEquals(HTTP_HOST, config1.getHttpHost()); @@ -463,6 +511,8 @@ public class JettyServerBuilderTest { assertEquals(SSL_WANTS_CLIENT_AUTH, config1.isSslWantClientAuth()); assertEquals(WORKING_DIRECTORY, config1.getWorkingDirectory()); assertEquals(false, config1.isMultipleSlashToSingle()); + assertEquals(true, config1.isHttpForwarded()); + assertEquals(true, config1.isHttpsForwarded()); verify(sessionManager).setMaxInactiveInterval(config1.getContextSessioninactiveinterval()); assertMapEquals(config1.getOtherProps(), "a", 1, "b", 2); @@ -470,6 +520,7 @@ public class JettyServerBuilderTest { JettyServer actual2 = JettyServer.fromConfig(config1); JettyConfig config2 = actual2.getConfig(); + assertEquals(SERVER_NAME, config2.getServerName()); assertEquals(CONTEXT, config2.getContextPath()); assertEquals(SESSION_INACTIVE_INTERVAL, config2.getContextSessioninactiveinterval()); assertEquals(HTTP_HOST, config2.getHttpHost()); @@ -493,6 +544,8 @@ public class JettyServerBuilderTest { assertEquals(SSL_WANTS_CLIENT_AUTH, config2.isSslWantClientAuth()); assertEquals(WORKING_DIRECTORY, config2.getWorkingDirectory()); assertEquals(false, config2.isMultipleSlashToSingle()); + assertEquals(true, config2.isHttpForwarded()); + assertEquals(true, config2.isHttpsForwarded()); verify(sessionManager).setMaxInactiveInterval(config2.getContextSessioninactiveinterval()); assertMapEquals(config1.getOtherProps(), "a", 1, "b", 2); diff --git a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConfig.java b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConfig.java index d07640da600..fa6a9cb89c7 100644 --- a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConfig.java +++ b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConfig.java @@ -14,16 +14,19 @@ import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__CONTEXT_ import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__CONTEXT_SESSION_INACTIVE_INTERVAL; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTPS_USE_RANDOM_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_NIO_AUTO_DETECT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_NIO_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__HTTP_USE_RANDOM_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__MULTIPLE_SLASH_TO_SINGLE; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__OTHER_INFO; +import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SERVER_NAME; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SSL_KEYPASSWORD; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SSL_KEYSTORE; import static org.eclipse.osee.http.jetty.JettyConstants.DEFAULT_JETTY__SSL_KEYSTORETYPE; @@ -36,16 +39,19 @@ import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__CONTEXT_PATH; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__CONTEXT_SESSION_INACTIVE_INTERVAL; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTPS_USE_RANDOM_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_HOST; +import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_IS_FORWARDED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_NIO_AUTO_DETECT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_NIO_ENABLED; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__HTTP_USE_RANDOM_PORT; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__MULTIPLE_SLASH_TO_SINGLE; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__OTHER_INFO; +import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__SERVER_NAME; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__SSL_KEYPASSWORD; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__SSL_KEYSTORE; import static org.eclipse.osee.http.jetty.JettyConstants.JETTY__SSL_KEYSTORETYPE; @@ -61,23 +67,27 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import org.eclipse.osee.framework.jdk.core.util.Strings; /** * @author Roberto E. Escobar */ public class JettyConfig { + private String serverName; private boolean nonBlockinIoEnabled; private boolean autoDetectNioSupport; private boolean isHttpEnabled; private int httpPort = -1; private String httpHost; + private boolean isHttpForwarded; private boolean useRandomHttpPort; private boolean isHttpsEnabled; private int httpsPort = -1; private String httpsHost; + private boolean isHttpsForwarded; private boolean useRandomHttpsPort; private String sslKeystore; @@ -104,6 +114,7 @@ public class JettyConfig { private void reset() { otherProps.clear(); + setServerName(DEFAULT_JETTY__SERVER_NAME); setAutoDetectNioSupport(DEFAULT_JETTY__HTTP_NIO_AUTO_DETECT); setNonBlockinIoEnabled(DEFAULT_JETTY__HTTP_NIO_ENABLED); @@ -114,11 +125,13 @@ public class JettyConfig { setHttpEnabled(DEFAULT_JETTY__HTTP_ENABLED); setHttpHost(DEFAULT_JETTY__HTTP_HOST); setHttpPort(DEFAULT_JETTY__HTTP_PORT); + setHttpForwarded(DEFAULT_JETTY__HTTP_IS_FORWARDED); setUseRandomHttpPort(DEFAULT_JETTY__HTTP_USE_RANDOM_PORT); setHttpsEnabled(DEFAULT_JETTY__HTTPS_ENABLED); setHttpsHost(DEFAULT_JETTY__HTTPS_HOST); setHttpsPort(DEFAULT_JETTY__HTTPS_PORT); + setHttpsForwarded(DEFAULT_JETTY__HTTPS_IS_FORWARDED); setUseRandomHttpsPort(DEFAULT_JETTY__HTTPS_USE_RANDOM_PORT); setSslKeypassword(DEFAULT_JETTY__SSL_KEYPASSWORD); @@ -135,6 +148,8 @@ public class JettyConfig { } void readProperties(Map src) { + setServerName(get(src, JETTY__SERVER_NAME, DEFAULT_JETTY__SERVER_NAME)); + setAutoDetectNioSupport(getBoolean(src, JETTY__HTTP_NIO_AUTO_DETECT, DEFAULT_JETTY__HTTP_NIO_AUTO_DETECT)); setNonBlockinIoEnabled(getBoolean(src, JETTY__HTTP_NIO_ENABLED, DEFAULT_JETTY__HTTP_NIO_ENABLED)); @@ -146,11 +161,13 @@ public class JettyConfig { setHttpEnabled(getBoolean(src, JETTY__HTTP_ENABLED, DEFAULT_JETTY__HTTP_ENABLED)); setHttpHost(get(src, JETTY__HTTP_HOST, DEFAULT_JETTY__HTTP_HOST)); setHttpPort(getInt(src, JETTY__HTTP_PORT, DEFAULT_JETTY__HTTP_PORT)); + setHttpForwarded(getBoolean(src, JETTY__HTTP_IS_FORWARDED, DEFAULT_JETTY__HTTP_IS_FORWARDED)); setUseRandomHttpPort(getBoolean(src, JETTY__HTTP_USE_RANDOM_PORT, DEFAULT_JETTY__HTTP_USE_RANDOM_PORT)); setHttpsEnabled(getBoolean(src, JETTY__HTTPS_ENABLED, DEFAULT_JETTY__HTTPS_ENABLED)); setHttpsHost(get(src, JETTY__HTTPS_HOST, DEFAULT_JETTY__HTTPS_HOST)); setHttpsPort(getInt(src, JETTY__HTTPS_PORT, DEFAULT_JETTY__HTTPS_PORT)); + setHttpsForwarded(getBoolean(src, JETTY__HTTPS_IS_FORWARDED, DEFAULT_JETTY__HTTPS_IS_FORWARDED)); setUseRandomHttpsPort(getBoolean(src, JETTY__HTTPS_USE_RANDOM_PORT, DEFAULT_JETTY__HTTPS_USE_RANDOM_PORT)); setSslKeypassword(get(src, JETTY__SSL_KEYPASSWORD, DEFAULT_JETTY__SSL_KEYPASSWORD)); @@ -179,16 +196,22 @@ public class JettyConfig { } protected void copy(JettyConfig other) { + this.serverName = other.serverName; this.nonBlockinIoEnabled = other.nonBlockinIoEnabled; this.autoDetectNioSupport = other.autoDetectNioSupport; + this.isHttpEnabled = other.isHttpEnabled; this.httpPort = other.httpPort; this.httpHost = other.httpHost; + this.isHttpForwarded = other.isHttpForwarded; this.useRandomHttpPort = other.useRandomHttpPort; + this.isHttpsEnabled = other.isHttpsEnabled; this.httpsPort = other.httpsPort; this.httpsHost = other.httpsHost; + this.isHttpsForwarded = other.isHttpsForwarded; this.useRandomHttpsPort = other.useRandomHttpsPort; + this.sslKeystore = other.sslKeystore; this.sslPassword = other.sslPassword; this.sslKeypassword = other.sslKeypassword; @@ -212,6 +235,14 @@ public class JettyConfig { /////////////////////////////////////////////// GETTERS + public String getServerName() { + return serverName; + } + + public boolean hasServerName() { + return Strings.isValid(getServerName()); + } + public boolean isHttpEnabled() { return isHttpEnabled; } @@ -224,6 +255,10 @@ public class JettyConfig { return httpHost; } + public boolean isHttpForwarded() { + return isHttpForwarded; + } + public boolean isHttpsEnabled() { return isHttpsEnabled; } @@ -236,6 +271,10 @@ public class JettyConfig { return httpsHost; } + public boolean isHttpsForwarded() { + return isHttpsForwarded; + } + public boolean isNonBlockinIoEnabled() { return nonBlockinIoEnabled; } @@ -312,6 +351,10 @@ public class JettyConfig { //////////////////////////////////////// SETTERS + void setServerName(String serverName) { + this.serverName = serverName; + } + void setAutoDetectNioSupport(boolean autoDetectNioSupport) { this.autoDetectNioSupport = autoDetectNioSupport; } @@ -332,6 +375,10 @@ public class JettyConfig { this.httpHost = httpHost; } + void setHttpForwarded(boolean isHttpForwarded) { + this.isHttpForwarded = isHttpForwarded; + } + void setHttpsEnabled(boolean isHttpsEnabled) { this.isHttpsEnabled = isHttpsEnabled; } @@ -344,6 +391,10 @@ public class JettyConfig { this.httpsHost = httpsHost; } + void setHttpsForwarded(boolean isHttpsForwarded) { + this.isHttpsForwarded = isHttpsForwarded; + } + void setSslKeystore(String sslKeystore) { this.sslKeystore = sslKeystore; } @@ -414,7 +465,7 @@ public class JettyConfig { @Override public String toString() { - return "JettyConfig [nonBlockinIoEnabled=" + nonBlockinIoEnabled + ", autoDetectNioSupport=" + autoDetectNioSupport + ", isHttpEnabled=" + isHttpEnabled + ", httpPort=" + httpPort + ", httpHost=" + httpHost + ", useRandomHttpPort=" + useRandomHttpPort + ", isHttpsEnabled=" + isHttpsEnabled + ", httpsPort=" + httpsPort + ", httpsHost=" + httpsHost + ", useRandomHttpsPort=" + useRandomHttpsPort + ", sslKeystore=" + sslKeystore + ", sslPassword=" + sslPassword + ", sslKeypassword=" + sslKeypassword + ", sslProtocol=" + sslProtocol + ", sslKeystoretype=" + sslKeystoretype + ", sslNeedClientAuth=" + sslNeedClientAuth + ", sslWantClientAuth=" + sslWantClientAuth + ", contextPath=" + contextPath + ", contextPathMultipleSlashToSingle=" + contextPathMultipleSlashToSingle + ", contextSessioninactiveinterval=" + contextSessioninactiveinterval + ", otherInfo=" + otherInfo + ", workingDirectory=" + workingDirectory + ", otherProps=" + otherProps + "]"; + return "JettyConfig [nonBlockinIoEnabled=" + nonBlockinIoEnabled + ", autoDetectNioSupport=" + autoDetectNioSupport + ", isHttpEnabled=" + isHttpEnabled + ", httpPort=" + httpPort + ", httpHost=" + httpHost + ", isHttpForwarded=" + isHttpForwarded + ", useRandomHttpPort=" + useRandomHttpPort + ", isHttpsEnabled=" + isHttpsEnabled + ", httpsPort=" + httpsPort + ", httpsHost=" + httpsHost + ", isHttpsForwarded=" + isHttpsForwarded + ", useRandomHttpsPort=" + useRandomHttpsPort + ", sslKeystore=" + sslKeystore + ", sslPassword=" + sslPassword + ", sslKeypassword=" + sslKeypassword + ", sslProtocol=" + sslProtocol + ", sslKeystoretype=" + sslKeystoretype + ", sslNeedClientAuth=" + sslNeedClientAuth + ", sslWantClientAuth=" + sslWantClientAuth + ", contextPath=" + contextPath + ", contextPathMultipleSlashToSingle=" + contextPathMultipleSlashToSingle + ", contextSessioninactiveinterval=" + contextSessioninactiveinterval + ", otherInfo=" + otherInfo + ", workingDirectory=" + workingDirectory + ", otherProps=" + otherProps + "]"; } } diff --git a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConstants.java b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConstants.java index d046c38a93f..28475b02345 100644 --- a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConstants.java +++ b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyConstants.java @@ -37,17 +37,20 @@ public final class JettyConstants { public static final String JETTY__ACCEPT_LOCAL_CONNECTIONS = "127.0.0.1"; public static final String JETTY__ACCEPT_REMOTE_CONNECTIONS = "0.0.0.0"; + public static final String JETTY__SERVER_NAME = qualify("name"); public static final String JETTY__HTTP_NIO_ENABLED = qualify("http.nio.enabled"); public static final String JETTY__HTTP_NIO_AUTO_DETECT = qualify("http.nio.enabled"); public static final String JETTY__HTTP_ENABLED = qualify("http.enabled"); public static final String JETTY__HTTP_PORT = qualify("http.port"); public static final String JETTY__HTTP_HOST = qualify("http.host"); + public static final String JETTY__HTTP_IS_FORWARDED = qualify("http.is.forwarded"); public static final String JETTY__HTTP_USE_RANDOM_PORT = qualify("http.use.random.port"); public static final String JETTY__HTTPS_ENABLED = qualify("https.enabled"); public static final String JETTY__HTTPS_HOST = qualify("https.host"); public static final String JETTY__HTTPS_PORT = qualify("https.port"); + public static final String JETTY__HTTPS_IS_FORWARDED = qualify("https.is.forwarded"); public static final String JETTY__HTTPS_USE_RANDOM_PORT = qualify("https.use.random.port"); public static final String JETTY__SSL_PROTOCOL = qualify("ssl.protocol"); @@ -65,6 +68,7 @@ public final class JettyConstants { public static final String JETTY__MULTIPLE_SLASH_TO_SINGLE = qualify("replace.multiple.slash.to.single"); //////////////////////////////////// Defaults + public static final String DEFAULT_JETTY__SERVER_NAME = null; public static final boolean DEFAULT_JETTY__HTTP_NIO_ENABLED = false; public static final boolean DEFAULT_JETTY__HTTP_NIO_AUTO_DETECT = true; @@ -72,11 +76,13 @@ public final class JettyConstants { public static final boolean DEFAULT_JETTY__HTTP_ENABLED = true; public static final int DEFAULT_JETTY__HTTP_PORT = 80; public static final String DEFAULT_JETTY__HTTP_HOST = JETTY__ACCEPT_REMOTE_CONNECTIONS; + public static final boolean DEFAULT_JETTY__HTTP_IS_FORWARDED = false; public static final boolean DEFAULT_JETTY__HTTP_USE_RANDOM_PORT = false; public static final boolean DEFAULT_JETTY__HTTPS_ENABLED = false; public static final String DEFAULT_JETTY__HTTPS_HOST = JETTY__ACCEPT_REMOTE_CONNECTIONS; public static final int DEFAULT_JETTY__HTTPS_PORT = 443; + public static final boolean DEFAULT_JETTY__HTTPS_IS_FORWARDED = false; public static final boolean DEFAULT_JETTY__HTTPS_USE_RANDOM_PORT = false; public static final String DEFAULT_JETTY__SSL_PROTOCOL = null; diff --git a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyServer.java b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyServer.java index da9337d392f..9975262aae8 100644 --- a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyServer.java +++ b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/JettyServer.java @@ -107,6 +107,11 @@ public abstract class JettyServer { return this; } + public Builder serverName(String serverName) { + setServerName(serverName); + return this; + } + public Builder autoDetectNioSupport(boolean autoDetect) { setAutoDetectNioSupport(autoDetect); return this; @@ -137,6 +142,11 @@ public abstract class JettyServer { return this; } + public Builder httpForwarded(boolean isForwarded) { + setHttpForwarded(isForwarded); + return this; + } + public Builder httpsEnabled(boolean httpsEnabled) { setHttpsEnabled(httpsEnabled); return this; @@ -152,6 +162,11 @@ public abstract class JettyServer { return this; } + public Builder httpsForwarded(boolean isForwarded) { + setHttpsForwarded(isForwarded); + return this; + } + public Builder nonBlockinIoEnabled(boolean enableNio) { setNonBlockinIoEnabled(enableNio); return this; diff --git a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/internal/JettyServerFactory.java b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/internal/JettyServerFactory.java index 77109cf976f..29fe02a9f44 100644 --- a/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/internal/JettyServerFactory.java +++ b/plugins/org.eclipse.osee.http.jetty/src/org/eclipse/osee/http/jetty/internal/JettyServerFactory.java @@ -16,6 +16,7 @@ import java.io.File; import java.util.Map; import java.util.Properties; import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.server.AbstractConnector; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.SessionManager; @@ -81,8 +82,8 @@ public class JettyServerFactory { return new JettyServerImpl(config, server, httpContext, httpPort, httpsPort, contextWorkDir); } - private Connector createHttpConnector(JettyConfig config) { - Connector connector = null; + private AbstractConnector createHttpConnector(JettyConfig config) { + AbstractConnector connector = null; if (config.isHttpEnabled()) { int httpPort = config.getHttpPort(); if (httpPort > 0) { @@ -103,6 +104,9 @@ public class JettyServerFactory { if (httpHost != null) { connector.setHost(httpHost); } + + configureForForwardedRequests(config, connector); + } else { throw newJettyException("http port cannot be less than = 0"); } @@ -133,7 +137,7 @@ public class JettyServerFactory { } @SuppressWarnings("deprecation") - private Connector createHttpsConnector(JettyConfig config) { + private AbstractConnector createHttpsConnector(JettyConfig config) { SslSocketConnector sslConnector = null; if (config.isHttpsEnabled()) { int httpsPort = config.getHttpsPort(); @@ -147,6 +151,8 @@ public class JettyServerFactory { sslConnector.setHost(httpHost); } + configureForForwardedRequests(config, sslConnector); + // configure SSL String keyStore = config.getSslKeystore(); if (keyStore != null) { @@ -182,6 +188,16 @@ public class JettyServerFactory { return sslConnector; } + private void configureForForwardedRequests(JettyConfig config, AbstractConnector connector) { + if (connector != null) { + if (config.hasServerName()) { + connector.setHostHeader(config.getServerName()); + } + boolean isForwarded = config.isHttpForwarded() || config.hasServerName(); + connector.setForwarded(isForwarded); + } + } + private ServletContextHandler createHttpContext(JettyConfig config) { ServletContextHandler httpContext = new ServletContextHandler(); MimeTypes mimeTypes = httpContext.getMimeTypes(); -- cgit v1.2.3