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.
This commit is contained in:
Joakim Erdfelt 2014-01-03 11:20:52 -07:00
parent 333ac73d5e
commit b3947ea0b8
3 changed files with 39 additions and 16 deletions

View File

@ -987,6 +987,22 @@ public class Request implements HttpServletRequest
return _context.getRealPath(path); 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() * @see javax.servlet.ServletRequest#getRemoteAddr()
@ -1907,7 +1923,7 @@ public class Request implements HttpServletRequest
{ {
_remote = addr; _remote = addr;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param requestedSessionId * @param requestedSessionId

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.server.handler;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.SocketException; import java.net.SocketException;
import java.net.URL; import java.net.URL;
@ -132,7 +133,6 @@ public class ShutdownHandler extends HandlerWrapper
} }
} }
@SuppressWarnings("resource")
private String getServerUrl() private String getServerUrl()
{ {
NetworkConnector connector=null; NetworkConnector connector=null;
@ -176,18 +176,18 @@ public class ShutdownHandler extends HandlerWrapper
} }
if (!hasCorrectSecurityToken(request)) 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); response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return; 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); response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return; return;
} }
LOG.info("Shutting down by request from " + getRemoteAddr(request)); LOG.info("Shutting down by request from " + request.getRemoteAddr());
final Server server=getServer(); final Server server=getServer();
new Thread() new Thread()
@ -211,14 +211,14 @@ public class ShutdownHandler extends HandlerWrapper
}.start(); }.start();
} }
private boolean requestFromLocalhost(HttpServletRequest request) private boolean requestFromLocalhost(Request request)
{ {
return "127.0.0.1".equals(getRemoteAddr(request)); InetSocketAddress addr = request.getRemoteInetSocketAddress();
} if (addr == null)
{
protected String getRemoteAddr(HttpServletRequest request) return false;
{ }
return request.getRemoteAddr(); return addr.getAddress().isLoopbackAddress();
} }
private boolean hasCorrectSecurityToken(HttpServletRequest request) private boolean hasCorrectSecurityToken(HttpServletRequest request)

View File

@ -22,12 +22,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.component.LifeCycle;
@ -38,6 +41,7 @@ import org.mockito.MockitoAnnotations;
public class ShutdownHandlerTest public class ShutdownHandlerTest
{ {
@Mock private Request baseRequest;
@Mock private HttpServletRequest request; @Mock private HttpServletRequest request;
@Mock private HttpServletResponse response; @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 boolean stopped = countDown.await(1000, TimeUnit.MILLISECONDS); //wait up to 1 sec to stop
assertTrue("Server lifecycle stop listener called", stopped); assertTrue("Server lifecycle stop listener called", stopped);
assertEquals("Server should be stopped","STOPPED",server.getState()); assertEquals("Server should be stopped","STOPPED",server.getState());
@ -97,7 +102,8 @@ public class ShutdownHandlerTest
{ {
setDefaultExpectations(); setDefaultExpectations();
when(request.getParameter("token")).thenReturn("anothertoken"); 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()); assertEquals("Server should be running","STARTED",server.getState());
} }
@ -106,7 +112,8 @@ public class ShutdownHandlerTest
{ {
setDefaultExpectations(); setDefaultExpectations();
when(request.getRemoteAddr()).thenReturn("192.168.3.3"); 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()); assertEquals("Server should be running","STARTED",server.getState());
} }