From b3947ea0b8013d64c0d530b2cc98fe4d02e3efb2 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 3 Jan 2014 11:20:52 -0700 Subject: [PATCH] 424762 - ShutdownHandler hardcodes "127.0.0.1" and cannot be used with IPv6 + Adding Request.getRemoteInetSocketAddress() to allow for better use of java built-ins for localhost / loopback checks. --- .../org/eclipse/jetty/server/Request.java | 18 +++++++++++++- .../jetty/server/handler/ShutdownHandler.java | 24 +++++++++---------- .../server/handler/ShutdownHandlerTest.java | 13 +++++++--- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 1717effd4f9..df679b4ffab 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -987,6 +987,22 @@ public class Request implements HttpServletRequest return _context.getRealPath(path); } + /* ------------------------------------------------------------ */ + /** + * Access the underlying Remote {@link InetSocketAddress} for this request. + * + * @return the remote {@link InetSocketAddress} for this request, or null if the request has no remote (see {@link ServletRequest#getRemoteAddr()} for + * conditions that result in no remote address) + */ + public InetSocketAddress getRemoteInetSocketAddress() + { + InetSocketAddress remote = _remote; + if (remote == null) + remote = _channel.getRemoteAddress(); + + return remote; + } + /* ------------------------------------------------------------ */ /* * @see javax.servlet.ServletRequest#getRemoteAddr() @@ -1907,7 +1923,7 @@ public class Request implements HttpServletRequest { _remote = addr; } - + /* ------------------------------------------------------------ */ /** * @param requestedSessionId diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java index 768ddda7d9c..e946fb670e7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.server.handler; import java.io.IOException; import java.net.HttpURLConnection; +import java.net.InetSocketAddress; import java.net.SocketException; import java.net.URL; @@ -132,7 +133,6 @@ public class ShutdownHandler extends HandlerWrapper } } - @SuppressWarnings("resource") private String getServerUrl() { NetworkConnector connector=null; @@ -176,18 +176,18 @@ public class ShutdownHandler extends HandlerWrapper } if (!hasCorrectSecurityToken(request)) { - LOG.warn("Unauthorized shutdown attempt from " + getRemoteAddr(request)); + LOG.warn("Unauthorized tokenless shutdown attempt from " + request.getRemoteAddr()); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return; } - if (!requestFromLocalhost(request)) + if (!requestFromLocalhost(baseRequest)) { - LOG.warn("Unauthorized shutdown attempt from " + getRemoteAddr(request)); + LOG.warn("Unauthorized non-loopback shutdown attempt from " + request.getRemoteAddr()); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return; } - LOG.info("Shutting down by request from " + getRemoteAddr(request)); + LOG.info("Shutting down by request from " + request.getRemoteAddr()); final Server server=getServer(); new Thread() @@ -211,14 +211,14 @@ public class ShutdownHandler extends HandlerWrapper }.start(); } - private boolean requestFromLocalhost(HttpServletRequest request) + private boolean requestFromLocalhost(Request request) { - return "127.0.0.1".equals(getRemoteAddr(request)); - } - - protected String getRemoteAddr(HttpServletRequest request) - { - return request.getRemoteAddr(); + InetSocketAddress addr = request.getRemoteInetSocketAddress(); + if (addr == null) + { + return false; + } + return addr.getAddress().isLoopbackAddress(); } private boolean hasCorrectSecurityToken(HttpServletRequest request) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java index 9c93643a4f7..6a04671d074 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java @@ -22,12 +22,15 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import java.net.Inet4Address; +import java.net.InetSocketAddress; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.LifeCycle; @@ -38,6 +41,7 @@ import org.mockito.MockitoAnnotations; public class ShutdownHandlerTest { + @Mock private Request baseRequest; @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @@ -86,7 +90,8 @@ public class ShutdownHandlerTest } }); - shutdownHandler.handle("/shutdown",null,request,response); + when(baseRequest.getRemoteInetSocketAddress()).thenReturn(new InetSocketAddress(Inet4Address.getLoopbackAddress(),45454)); + shutdownHandler.handle("/shutdown",baseRequest,request,response); boolean stopped = countDown.await(1000, TimeUnit.MILLISECONDS); //wait up to 1 sec to stop assertTrue("Server lifecycle stop listener called", stopped); assertEquals("Server should be stopped","STOPPED",server.getState()); @@ -97,7 +102,8 @@ public class ShutdownHandlerTest { setDefaultExpectations(); when(request.getParameter("token")).thenReturn("anothertoken"); - shutdownHandler.handle("/shutdown",null,request,response); + when(baseRequest.getRemoteInetSocketAddress()).thenReturn(new InetSocketAddress(Inet4Address.getLoopbackAddress(),45454)); + shutdownHandler.handle("/shutdown",baseRequest,request,response); assertEquals("Server should be running","STARTED",server.getState()); } @@ -106,7 +112,8 @@ public class ShutdownHandlerTest { setDefaultExpectations(); when(request.getRemoteAddr()).thenReturn("192.168.3.3"); - shutdownHandler.handle("/shutdown",null,request,response); + when(baseRequest.getRemoteInetSocketAddress()).thenReturn(new InetSocketAddress(Inet4Address.getByName("192.168.3.3"),45454)); + shutdownHandler.handle("/shutdown",baseRequest,request,response); assertEquals("Server should be running","STARTED",server.getState()); }