diff --git a/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyRequestAPIData.java b/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyRequestAPIData.java index c5f80ead6..27793348c 100644 --- a/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyRequestAPIData.java +++ b/runtime/runtime_impl_jetty9/src/main/java/com/google/apphosting/runtime/jetty9/JettyRequestAPIData.java @@ -67,12 +67,12 @@ import java.util.stream.Stream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; - import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.util.HostPort; /** * Implementation for the {@link RequestAPIData} to allow for the Jetty {@link Request} to be used @@ -286,7 +286,7 @@ public JettyRequestAPIData( traceContext = TraceContextProto.getDefaultInstance(); } - String finalUserIp = userIp; + String normalizeUserIp = HostPort.normalizeHost(userIp); this.httpServletRequest = new HttpServletRequestWrapper(httpServletRequest) { @@ -332,17 +332,12 @@ public boolean isSecure() { @Override public String getRemoteAddr() { - return finalUserIp; - } - - @Override - public String getServerName() { - return UNSPECIFIED_IP; + return normalizeUserIp; } @Override public String getRemoteHost() { - return finalUserIp; + return normalizeUserIp; } @Override diff --git a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/RemoteAddressTest.java b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/RemoteAddressTest.java index f2ade9ba8..461e0c9b4 100644 --- a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/RemoteAddressTest.java +++ b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty9/RemoteAddressTest.java @@ -25,6 +25,7 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -54,6 +55,7 @@ public static Collection data() { private final boolean httpMode; private final String environment; private RuntimeContext runtime; + private String url; public RemoteAddressTest(String environment, boolean httpMode) { this.environment = environment; @@ -67,6 +69,7 @@ public void before() throws Exception { copyAppToDir(app, temp.getRoot().toPath()); httpClient.start(); runtime = runtimeContext(); + url = runtime.jettyUrl("/"); System.err.println("==== Using Environment: " + environment + " " + httpMode + " ===="); } @@ -77,20 +80,85 @@ public void after() throws Exception { } @Test - public void test() throws Exception { - String url = runtime.jettyUrl("/"); + public void testWithHostHeader() throws Exception { ContentResponse response = httpClient.newRequest(url) + .header("Host", "foobar:1234") .header("X-AppEngine-User-IP", "203.0.113.1") .send(); assertThat(response.getStatus(), equalTo(HttpStatus.OK_200)); String contentReceived = response.getContentAsString(); assertThat(contentReceived, containsString("getRemoteAddr: 203.0.113.1")); + assertThat(contentReceived, containsString("getRemoteHost: 203.0.113.1")); + assertThat(contentReceived, containsString("getRemotePort: 0")); assertThat(contentReceived, containsString("getLocalAddr: 0.0.0.0")); - assertThat(contentReceived, containsString("getServerPort: " + runtime.getPort())); + assertThat(contentReceived, containsString("getLocalName: 0.0.0.0")); + assertThat(contentReceived, containsString("getLocalPort: 0")); + assertThat(contentReceived, containsString("getServerName: foobar")); + assertThat(contentReceived, containsString("getServerPort: 1234")); + } + + @Test + public void testWithIPv6() throws Exception { + // Test the host header to be IPv6 with a port. + ContentResponse response = httpClient.newRequest(url) + .header("Host", "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:1234") + .header("X-AppEngine-User-IP", "203.0.113.1") + .send(); + assertThat(response.getStatus(), equalTo(HttpStatus.OK_200)); + String contentReceived = response.getContentAsString(); + assertThat(contentReceived, containsString("getRemoteAddr: 203.0.113.1")); + assertThat(contentReceived, containsString("getRemoteHost: 203.0.113.1")); + assertThat(contentReceived, containsString("getRemotePort: 0")); + assertThat(contentReceived, containsString("getLocalAddr: 0.0.0.0")); + assertThat(contentReceived, containsString("getLocalName: 0.0.0.0")); + assertThat(contentReceived, containsString("getLocalPort: 0")); + assertThat(contentReceived, containsString("getServerName: [2001:db8:85a3:8d3:1319:8a2e:370:7348]")); + assertThat(contentReceived, containsString("getServerPort: 1234")); + + // Test the user IP to be IPv6 with a port. + response = httpClient.newRequest(url) + .header("Host", "203.0.113.1:1234") + .header("X-AppEngine-User-IP", "2001:db8:85a3:8d3:1319:8a2e:370:7348") + .send(); + assertThat(response.getStatus(), equalTo(HttpStatus.OK_200)); + contentReceived = response.getContentAsString(); + if ("jetty94".equals(environment)) { + assertThat(contentReceived, containsString("getRemoteAddr: [2001:db8:85a3:8d3:1319:8a2e:370:7348]")); + assertThat(contentReceived, containsString("getRemoteHost: [2001:db8:85a3:8d3:1319:8a2e:370:7348]")); + } + else { + assertThat(contentReceived, containsString("getRemoteAddr: 2001:db8:85a3:8d3:1319:8a2e:370:7348")); + assertThat(contentReceived, containsString("getRemoteHost: 2001:db8:85a3:8d3:1319:8a2e:370:7348")); + } + assertThat(contentReceived, containsString("getRemotePort: 0")); + assertThat(contentReceived, containsString("getLocalAddr: 0.0.0.0")); + assertThat(contentReceived, containsString("getLocalName: 0.0.0.0")); + assertThat(contentReceived, containsString("getLocalPort: 0")); + assertThat(contentReceived, containsString("getServerName: 203.0.113.1")); + assertThat(contentReceived, containsString("getServerPort: 1234")); + } + + @Test + public void testWithoutHostHeader() throws Exception { + String url = runtime.jettyUrl("/"); + + ContentResponse response = httpClient.newRequest(url) + .version(HttpVersion.HTTP_1_0) + .header("X-AppEngine-User-IP", "203.0.113.1") + .onRequestHeaders(request -> request.getHeaders().remove("Host")) + .send(); + + assertThat(response.getStatus(), equalTo(HttpStatus.OK_200)); + String contentReceived = response.getContentAsString(); + assertThat(contentReceived, containsString("getRemoteAddr: 203.0.113.1")); + assertThat(contentReceived, containsString("getRemoteHost: 203.0.113.1")); assertThat(contentReceived, containsString("getRemotePort: 0")); + assertThat(contentReceived, containsString("getLocalAddr: 0.0.0.0")); + assertThat(contentReceived, containsString("getLocalName: 0.0.0.0")); assertThat(contentReceived, containsString("getLocalPort: 0")); - assertThat(contentReceived, containsString("getServerName: 0.0.0.0")); + assertThat(contentReceived, containsString("getServerName: 127.0.0.1")); + assertThat(contentReceived, containsString("getServerPort: " + runtime.getPort())); } private RuntimeContext runtimeContext() throws Exception { diff --git a/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE10RemoteAddrServlet.java b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE10RemoteAddrServlet.java index 50f772aaa..cf86915f7 100644 --- a/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE10RemoteAddrServlet.java +++ b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE10RemoteAddrServlet.java @@ -28,10 +28,13 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws resp.setContentType("text/plain"); PrintWriter writer = resp.getWriter(); writer.println("getRemoteAddr: " + req.getRemoteAddr()); - writer.println("getLocalAddr: " + req.getLocalAddr()); - writer.println("getServerPort: " + req.getServerPort()); + writer.println("getRemoteHost: " + req.getRemoteHost()); writer.println("getRemotePort: " + req.getRemotePort()); + writer.println("getLocalAddr: " + req.getLocalAddr()); + writer.println("getLocalName: " + req.getLocalName()); writer.println("getLocalPort: " + req.getLocalPort()); writer.println("getServerName: " + req.getServerName()); + writer.println("getServerPort: " + req.getServerPort()); + } } diff --git a/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE8RemoteAddrServlet.java b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE8RemoteAddrServlet.java index cb2338b57..a4b792f46 100644 --- a/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE8RemoteAddrServlet.java +++ b/runtime/testapps/src/main/java/com/google/apphosting/runtime/jetty9/remoteaddrapp/EE8RemoteAddrServlet.java @@ -28,10 +28,12 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws resp.setContentType("text/plain"); PrintWriter writer = resp.getWriter(); writer.println("getRemoteAddr: " + req.getRemoteAddr()); - writer.println("getLocalAddr: " + req.getLocalAddr()); - writer.println("getServerPort: " + req.getServerPort()); + writer.println("getRemoteHost: " + req.getRemoteHost()); writer.println("getRemotePort: " + req.getRemotePort()); + writer.println("getLocalAddr: " + req.getLocalAddr()); + writer.println("getLocalName: " + req.getLocalName()); writer.println("getLocalPort: " + req.getLocalPort()); writer.println("getServerName: " + req.getServerName()); + writer.println("getServerPort: " + req.getServerPort()); } }