Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x
Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
commit
2d5984da20
|
@ -27,6 +27,7 @@ import javax.servlet.ServletRequest;
|
|||
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.security.Credential;
|
||||
|
@ -34,7 +35,7 @@ import org.eclipse.jetty.util.security.Credential;
|
|||
/**
|
||||
* AbstractLoginService
|
||||
*/
|
||||
public abstract class AbstractLoginService extends AbstractLifeCycle implements LoginService
|
||||
public abstract class AbstractLoginService extends ContainerLifeCycle implements LoginService
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractLoginService.class);
|
||||
|
||||
|
@ -116,6 +117,11 @@ public abstract class AbstractLoginService extends AbstractLifeCycle implements
|
|||
/* ------------------------------------------------------------ */
|
||||
protected abstract UserPrincipal loadUserInfo (String username);
|
||||
|
||||
protected AbstractLoginService()
|
||||
{
|
||||
addBean(_identityService);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.security.LoginService#getName()
|
||||
|
@ -135,6 +141,7 @@ public abstract class AbstractLoginService extends AbstractLifeCycle implements
|
|||
{
|
||||
if (isRunning())
|
||||
throw new IllegalStateException("Running");
|
||||
updateBean(_identityService, identityService);
|
||||
_identityService = identityService;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,8 @@ public class HashLoginService extends AbstractLoginService
|
|||
*/
|
||||
public void setUserStore(UserStore userStore)
|
||||
{
|
||||
this._userStore = userStore;
|
||||
updateBean(_userStore, userStore);
|
||||
_userStore = userStore;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -179,12 +180,29 @@ public class HashLoginService extends AbstractLoginService
|
|||
PropertyUserStore propertyUserStore = new PropertyUserStore();
|
||||
propertyUserStore.setHotReload(hotReload);
|
||||
propertyUserStore.setConfig(_config);
|
||||
propertyUserStore.start();
|
||||
_userStore = propertyUserStore;
|
||||
setUserStore(propertyUserStore);
|
||||
_userStoreAutoCreate = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To facilitate testing.
|
||||
* @return the UserStore
|
||||
*/
|
||||
UserStore getUserStore ()
|
||||
{
|
||||
return _userStore;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* To facilitate testing.
|
||||
* @return true if a UserStore has been created from a config, false if a UserStore was provided.
|
||||
*/
|
||||
boolean isUserStoreAutoCreate ()
|
||||
{
|
||||
return _userStoreAutoCreate;
|
||||
}
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
|
||||
|
@ -193,8 +211,10 @@ public class HashLoginService extends AbstractLoginService
|
|||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
if (_userStore != null && _userStoreAutoCreate)
|
||||
_userStore.stop();
|
||||
_userStore = null;
|
||||
if ( _userStoreAutoCreate)
|
||||
{
|
||||
setUserStore(null);
|
||||
_userStoreAutoCreate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.security;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
/**
|
||||
* Tests of the HashLoginService.
|
||||
*/
|
||||
public class HashLoginServiceTest
|
||||
{
|
||||
@Test
|
||||
public void testAutoCreatedUserStore() throws Exception
|
||||
{
|
||||
HashLoginService loginService = new HashLoginService("foo", MavenTestingUtils.getTestResourceFile("foo.properties").getAbsolutePath());
|
||||
assertThat(loginService.getIdentityService(), is(notNullValue()));
|
||||
loginService.start();
|
||||
assertTrue(loginService.getUserStore().isStarted());
|
||||
assertTrue(loginService.isUserStoreAutoCreate());
|
||||
|
||||
loginService.stop();
|
||||
assertFalse(loginService.isUserStoreAutoCreate());
|
||||
assertThat(loginService.getUserStore(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvidedUserStore() throws Exception
|
||||
{
|
||||
HashLoginService loginService = new HashLoginService("foo");
|
||||
assertThat(loginService.getIdentityService(), is(notNullValue()));
|
||||
UserStore store = new UserStore();
|
||||
loginService.setUserStore(store);
|
||||
assertFalse(store.isStarted());
|
||||
loginService.start();
|
||||
assertTrue(loginService.getUserStore().isStarted());
|
||||
assertFalse(loginService.isUserStoreAutoCreate());
|
||||
|
||||
loginService.stop();
|
||||
|
||||
assertFalse(loginService.isUserStoreAutoCreate());
|
||||
assertFalse(store.isStarted());
|
||||
assertThat(loginService.getUserStore(), is(notNullValue()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
ken=123
|
||||
amy=456
|
|
@ -1,3 +1,5 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[description]
|
||||
Enable the InetAccessHandler to apply a include/exclude
|
||||
control of the remote IP of requests.
|
||||
|
@ -9,7 +11,22 @@ handler
|
|||
server
|
||||
|
||||
[files]
|
||||
basehome:modules/inetaccess/inetaccess.xml|etc/inetaccess.xml
|
||||
basehome:modules/inetaccess/jetty-inetaccess.xml|etc/jetty-inetaccess.xml
|
||||
|
||||
[xml]
|
||||
etc/inetaccess.xml
|
||||
etc/jetty-inetaccess.xml
|
||||
|
||||
[ini-template]
|
||||
|
||||
## List of InetAddress patterns to include
|
||||
#jetty.inetaccess.include=127.0.0.1,127.0.0.2
|
||||
|
||||
## List of InetAddress patterns to exclude
|
||||
#jetty.inetaccess.exclude=127.0.0.1,127.0.0.2
|
||||
|
||||
## List of Connector names to include
|
||||
#jetty.inetaccess.includeConnectors=http
|
||||
|
||||
## List of Connector names to exclude
|
||||
#jetty.inetaccess.excludeConnectors=tls
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
<Call name="insertHandler">
|
||||
<Arg>
|
||||
<New id="InetAccessHandler" class="org.eclipse.jetty.server.handler.InetAccessHandler">
|
||||
<Call name="include">
|
||||
<Arg>
|
||||
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||
<Arg><Property name="jetty.inetaccess.include" default=""/></Arg>
|
||||
</Call>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="exclude">
|
||||
<Arg>
|
||||
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||
<Arg><Property name="jetty.inetaccess.exclude" default=""/></Arg>
|
||||
</Call>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="includeConnectors">
|
||||
<Arg>
|
||||
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||
<Arg><Property name="jetty.inetaccess.includeConnectors" default=""/></Arg>
|
||||
</Call>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="excludeConnectors">
|
||||
<Arg>
|
||||
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||
<Arg><Property name="jetty.inetaccess.excludeConnectors" default=""/></Arg>
|
||||
</Call>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -30,6 +30,7 @@ import org.eclipse.jetty.http.HttpStatus;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.IncludeExclude;
|
||||
import org.eclipse.jetty.util.IncludeExcludeSet;
|
||||
import org.eclipse.jetty.util.InetAddressSet;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
|
@ -39,16 +40,32 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
/**
|
||||
* InetAddress Access Handler
|
||||
* <p>
|
||||
* Controls access to the wrapped handler using the real remote IP. Control is provided
|
||||
* by and {@link IncludeExcludeSet} over a {@link InetAddressSet}. This handler
|
||||
* uses the real internet address of the connection, not one reported in the forwarded
|
||||
* for headers, as this cannot be as easily forged.
|
||||
* Controls access to the wrapped handler using the real remote IP. Control is
|
||||
* provided by and {@link IncludeExcludeSet} over a {@link InetAddressSet}. This
|
||||
* handler uses the real internet address of the connection, not one reported in
|
||||
* the forwarded for headers, as this cannot be as easily forged.
|
||||
* <p>
|
||||
* Additionally, there may be times when you want to only apply this handler to
|
||||
* a subset of your connectors. In this situation you can use
|
||||
* <b>connectorNames</b> to specify the connector names that you want this IP
|
||||
* access filter to apply to.
|
||||
*/
|
||||
public class InetAccessHandler extends HandlerWrapper
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(InetAccessHandler.class);
|
||||
|
||||
private final IncludeExcludeSet<String, InetAddress> _set = new IncludeExcludeSet<>(InetAddressSet.class);
|
||||
private final IncludeExcludeSet<String, InetAddress> _addrs = new IncludeExcludeSet<>(InetAddressSet.class);
|
||||
private final IncludeExclude<String> _names = new IncludeExclude<>();
|
||||
|
||||
/**
|
||||
* Clears all the includes, excludes, included connector names and excluded
|
||||
* connector names.
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
_addrs.clear();
|
||||
_names.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes an InetAddress pattern
|
||||
|
@ -58,7 +75,7 @@ public class InetAccessHandler extends HandlerWrapper
|
|||
*/
|
||||
public void include(String pattern)
|
||||
{
|
||||
_set.include(pattern);
|
||||
_addrs.include(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,7 +86,7 @@ public class InetAccessHandler extends HandlerWrapper
|
|||
*/
|
||||
public void include(String... patterns)
|
||||
{
|
||||
_set.include(patterns);
|
||||
_addrs.include(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,7 +97,7 @@ public class InetAccessHandler extends HandlerWrapper
|
|||
*/
|
||||
public void exclude(String pattern)
|
||||
{
|
||||
_set.exclude(pattern);
|
||||
_addrs.exclude(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,14 +108,55 @@ public class InetAccessHandler extends HandlerWrapper
|
|||
*/
|
||||
public void exclude(String... patterns)
|
||||
{
|
||||
_set.exclude(patterns);
|
||||
_addrs.exclude(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes a connector name.
|
||||
*
|
||||
* @param name Connector name to include in this handler.
|
||||
*/
|
||||
public void includeConnector(String name)
|
||||
{
|
||||
_names.include(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Excludes a connector name.
|
||||
*
|
||||
* @param name Connector name to exclude in this handler.
|
||||
*/
|
||||
public void excludeConnector(String name)
|
||||
{
|
||||
_names.exclude(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes connector names.
|
||||
*
|
||||
* @param names Connector names to include in this handler.
|
||||
*/
|
||||
public void includeConnectors(String... names)
|
||||
{
|
||||
_names.include(names);
|
||||
}
|
||||
|
||||
/**
|
||||
* Excludes connector names.
|
||||
*
|
||||
* @param names Connector names to exclude in this handler.
|
||||
*/
|
||||
public void excludeConnectors(String... names)
|
||||
{
|
||||
_names.exclude(names);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the incoming request against the whitelist and blacklist
|
||||
*/
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
// Get the real remote IP (not the one set by the forwarded headers (which may be forged))
|
||||
HttpChannel channel = baseRequest.getHttpChannel();
|
||||
|
@ -108,7 +166,7 @@ public class InetAccessHandler extends HandlerWrapper
|
|||
if (endp != null)
|
||||
{
|
||||
InetSocketAddress address = endp.getRemoteAddress();
|
||||
if (address != null && !isAllowed(address.getAddress(), request))
|
||||
if (address != null && !isAllowed(address.getAddress(), baseRequest, request))
|
||||
{
|
||||
response.sendError(HttpStatus.FORBIDDEN_403);
|
||||
baseRequest.setHandled(true);
|
||||
|
@ -123,23 +181,30 @@ public class InetAccessHandler extends HandlerWrapper
|
|||
/**
|
||||
* Checks if specified address and request are allowed by current InetAddress rules.
|
||||
*
|
||||
* @param address the inetAddress to check
|
||||
* @param request the request to check
|
||||
* @param addr the inetAddress to check
|
||||
* @param baseRequest the base request to check
|
||||
* @param request the HttpServletRequest request to check
|
||||
* @return true if inetAddress and request are allowed
|
||||
*/
|
||||
protected boolean isAllowed(InetAddress address, HttpServletRequest request)
|
||||
protected boolean isAllowed(InetAddress addr, Request baseRequest, HttpServletRequest request)
|
||||
{
|
||||
boolean allowed = _set.test(address);
|
||||
String name = baseRequest.getHttpChannel().getConnector().getName();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} {} {} for {}", this, allowed ? "allowed" : "denied", address, request);
|
||||
return allowed;
|
||||
{
|
||||
Boolean allowedByName = _names.isIncludedAndNotExcluded(name);
|
||||
Boolean allowedByAddr = _addrs.isIncludedAndNotExcluded(addr);
|
||||
LOG.debug("{} allowedByName={} allowedByAddr={} for {}/{}", this, allowedByName, allowedByAddr, addr, request);
|
||||
}
|
||||
return _names.test(name) && _addrs.test(addr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
dumpObjects(out, indent,
|
||||
DumpableCollection.from("included",_set.getIncluded()),
|
||||
DumpableCollection.from("excluded",_set.getExcluded()));
|
||||
new DumpableCollection("included", _addrs.getIncluded()),
|
||||
new DumpableCollection("excluded", _addrs.getExcluded()),
|
||||
new DumpableCollection("includedConnector", _names.getIncluded()),
|
||||
new DumpableCollection("excludedConnector", _names.getExcluded()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http.tools.HttpTester;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class InetAccessHandlerTest
|
||||
{
|
||||
private static Server _server;
|
||||
private static ServerConnector _connector;
|
||||
private static InetAccessHandler _handler;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception
|
||||
{
|
||||
_server = new Server();
|
||||
_connector = new ServerConnector(_server);
|
||||
_connector.setName("http");
|
||||
_server.setConnectors(new Connector[]
|
||||
{ _connector });
|
||||
|
||||
_handler = new InetAccessHandler();
|
||||
_handler.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setStatus(HttpStatus.OK_200);
|
||||
}
|
||||
});
|
||||
_server.setHandler(_handler);
|
||||
_server.start();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() throws Exception
|
||||
{
|
||||
_server.stop();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testHandler(String include, String exclude, String includeConnectors, String excludeConnectors, String code)
|
||||
throws Exception
|
||||
{
|
||||
_handler.clear();
|
||||
for (String inc : include.split(";", -1))
|
||||
{
|
||||
if (inc.length() > 0)
|
||||
{
|
||||
_handler.include(inc);
|
||||
}
|
||||
}
|
||||
for (String exc : exclude.split(";", -1))
|
||||
{
|
||||
if (exc.length() > 0)
|
||||
{
|
||||
_handler.exclude(exc);
|
||||
}
|
||||
}
|
||||
for (String inc : includeConnectors.split(";", -1))
|
||||
{
|
||||
if (inc.length() > 0)
|
||||
{
|
||||
_handler.includeConnector(inc);
|
||||
}
|
||||
}
|
||||
for (String exc : excludeConnectors.split(";", -1))
|
||||
{
|
||||
if (exc.length() > 0)
|
||||
{
|
||||
_handler.excludeConnector(exc);
|
||||
}
|
||||
}
|
||||
|
||||
try (Socket socket = new Socket("127.0.0.1", _connector.getLocalPort());)
|
||||
{
|
||||
socket.setSoTimeout(5000);
|
||||
|
||||
HttpTester.Request request = HttpTester.newRequest();
|
||||
request.setMethod("GET");
|
||||
request.setURI("/path");
|
||||
request.setHeader("Host","127.0.0.1");
|
||||
request.setVersion(HttpVersion.HTTP_1_0);
|
||||
|
||||
ByteBuffer output = request.generate();
|
||||
socket.getOutputStream().write(output.array(),output.arrayOffset()+output.position(),output.remaining());
|
||||
HttpTester.Input input = HttpTester.from(socket.getInputStream());
|
||||
HttpTester.Response response = HttpTester.parseResponse(input);
|
||||
Object[] params = new Object[]
|
||||
{ "Request WBHUC", include, exclude, includeConnectors, excludeConnectors, code, "Response", response.getStatus() };
|
||||
assertEquals(Integer.parseInt(code), response.getStatus(), Arrays.deepToString(params));
|
||||
}
|
||||
}
|
||||
|
||||
public static Stream<Arguments> data()
|
||||
{
|
||||
Object[][] data = new Object[][]
|
||||
{
|
||||
// Empty lists
|
||||
{ "", "", "", "", "200" },
|
||||
|
||||
// test simple filters
|
||||
{ "127.0.0.1", "", "", "", "200" },
|
||||
{ "127.0.0.1-127.0.0.254", "", "", "", "200" },
|
||||
{ "192.0.0.1", "", "", "", "403" },
|
||||
{ "192.0.0.1-192.0.0.254", "", "", "", "403" },
|
||||
|
||||
// test connector name filters
|
||||
{ "127.0.0.1", "", "http", "", "200" },
|
||||
{ "127.0.0.1-127.0.0.254", "", "http", "", "200" },
|
||||
{ "192.0.0.1", "", "http", "", "403" },
|
||||
{ "192.0.0.1-192.0.0.254", "", "http", "", "403" },
|
||||
|
||||
{ "127.0.0.1", "", "nothttp", "", "403" },
|
||||
{ "127.0.0.1-127.0.0.254", "", "nothttp", "", "403" },
|
||||
{ "192.0.0.1", "", "nothttp", "", "403" },
|
||||
{ "192.0.0.1-192.0.0.254", "", "nothttp", "", "403" },
|
||||
|
||||
{ "127.0.0.1", "", "", "http", "403" },
|
||||
{ "127.0.0.1-127.0.0.254", "", "", "http", "403" },
|
||||
{ "192.0.0.1", "", "", "http", "403" },
|
||||
{ "192.0.0.1-192.0.0.254", "", "", "http", "403" },
|
||||
|
||||
{ "127.0.0.1", "", "", "nothttp", "200" },
|
||||
{ "127.0.0.1-127.0.0.254", "", "", "nothttp", "200" },
|
||||
{ "192.0.0.1", "", "", "nothttp", "403" },
|
||||
{ "192.0.0.1-192.0.0.254", "", "", "nothttp", "403" },
|
||||
|
||||
};
|
||||
return Arrays.asList(data).stream().map(Arguments::of);
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ public class IncludeExcludeSet<T,P> implements Predicate<P>
|
|||
private final Predicate<P> _includePredicate;
|
||||
private final Set<T> _excludes;
|
||||
private final Predicate<P> _excludePredicate;
|
||||
|
||||
|
||||
private static class SetContainsPredicate<T> implements Predicate<T>
|
||||
{
|
||||
private final Set<T> set;
|
||||
|
@ -162,14 +162,14 @@ public class IncludeExcludeSet<T,P> implements Predicate<P>
|
|||
|
||||
/**
|
||||
* Test Included and not Excluded
|
||||
* @param t The item to test
|
||||
* @return Boolean.TRUE if t is included, Boolean.FALSE if t is excluded and null if neither
|
||||
* @param item The item to test
|
||||
* @return Boolean.TRUE if item is included, Boolean.FALSE if item is excluded and null if neither
|
||||
*/
|
||||
public Boolean isIncludedAndNotExcluded(P t)
|
||||
public Boolean isIncludedAndNotExcluded(P item)
|
||||
{
|
||||
if (_excludePredicate.test(t))
|
||||
if (_excludePredicate.test(item))
|
||||
return Boolean.FALSE;
|
||||
if (_includePredicate.test(t))
|
||||
if (_includePredicate.test(item))
|
||||
return Boolean.TRUE;
|
||||
|
||||
return null;
|
||||
|
@ -204,7 +204,11 @@ public class IncludeExcludeSet<T,P> implements Predicate<P>
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{i=%s,ip=%s,e=%s,ep=%s}",this.getClass().getSimpleName(),hashCode(),_includes,_includePredicate,_excludes,_excludePredicate);
|
||||
return String.format("%s@%x{i=%s,ip=%s,e=%s,ep=%s}",this.getClass().getSimpleName(),hashCode(),
|
||||
_includes,
|
||||
_includePredicate==_includes?"SELF":_includePredicate,
|
||||
_excludes,
|
||||
_excludePredicate==_excludes?"SELF":_excludePredicate);
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
|
|
|
@ -394,7 +394,11 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP
|
|||
public int getReservedThreads()
|
||||
{
|
||||
if (isStarted())
|
||||
return getBean(ReservedThreadExecutor.class).getCapacity();
|
||||
{
|
||||
ReservedThreadExecutor reservedThreadExecutor = getBean(ReservedThreadExecutor.class);
|
||||
if (reservedThreadExecutor != null)
|
||||
return reservedThreadExecutor.getCapacity();
|
||||
}
|
||||
return _reservedThreads;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,17 +18,16 @@
|
|||
|
||||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DumpableCollectionTest
|
||||
{
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
public class DumpableTest
|
||||
{
|
||||
@Test
|
||||
public void testNullDumpableCollection () throws Exception
|
||||
{
|
|
@ -23,6 +23,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
@ -36,6 +37,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jetty.util.ArrayTernaryTrie;
|
||||
import org.eclipse.jetty.util.IncludeExcludeSet;
|
||||
|
@ -708,21 +710,7 @@ public class ClassMatcher extends AbstractSet<String>
|
|||
{
|
||||
try
|
||||
{
|
||||
Boolean byName = _patterns.isIncludedAndNotExcluded(clazz.getName());
|
||||
if (Boolean.FALSE.equals(byName))
|
||||
return byName; // Already excluded so no need to check location.
|
||||
URI location = TypeUtil.getLocationOfClass(clazz);
|
||||
Boolean byLocation = location == null ? null
|
||||
: _locations.isIncludedAndNotExcluded(location);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("match {} from {} byName={} byLocation={} in {}",clazz,location,byName,byLocation,this);
|
||||
|
||||
// Combine the tri-state match of both IncludeExclude Sets
|
||||
boolean included = Boolean.TRUE.equals(byName) || Boolean.TRUE.equals(byLocation)
|
||||
|| (byName==null && !_patterns.hasIncludes() && byLocation==null && !_locations.hasIncludes());
|
||||
boolean excluded = Boolean.FALSE.equals(byName) || Boolean.FALSE.equals(byLocation);
|
||||
return included && !excluded;
|
||||
return combine(_patterns, clazz.getName(), _locations, ()->TypeUtil.getLocationOfClass(clazz));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -740,29 +728,33 @@ public class ClassMatcher extends AbstractSet<String>
|
|||
// Treat path elements as packages for name matching
|
||||
name=name.replace("/",".");
|
||||
|
||||
Boolean byName = _patterns.isIncludedAndNotExcluded(name);
|
||||
if (Boolean.FALSE.equals(byName))
|
||||
return byName; // Already excluded so no need to check location.
|
||||
|
||||
// Try to find a file path for location matching
|
||||
Boolean byLocation = null;
|
||||
try
|
||||
return combine(_patterns, name, _locations, ()->
|
||||
{
|
||||
URI jarUri = URIUtil.getJarSource(url.toURI());
|
||||
if ("file".equalsIgnoreCase(jarUri.getScheme()))
|
||||
try
|
||||
{
|
||||
byLocation = _locations.isIncludedAndNotExcluded(jarUri);
|
||||
return URIUtil.getJarSource(url.toURI());
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean combine(IncludeExcludeSet<Entry, String> names, String name, IncludeExcludeSet<Entry, URI> locations, Supplier<URI> location)
|
||||
{
|
||||
Boolean byName = names.isIncludedAndNotExcluded(name);
|
||||
if (Boolean.FALSE==byName)
|
||||
return false;
|
||||
|
||||
Boolean byLocation = locations.isIncludedAndNotExcluded(location.get());
|
||||
if (Boolean.FALSE==byLocation)
|
||||
return false;
|
||||
|
||||
return Boolean.TRUE.equals(byName)
|
||||
|| Boolean.TRUE.equals(byLocation)
|
||||
|| !(names.hasIncludes() || locations.hasIncludes());
|
||||
}
|
||||
|
||||
// Combine the tri-state match of both IncludeExclude Sets
|
||||
boolean included = Boolean.TRUE.equals(byName) || Boolean.TRUE.equals(byLocation)
|
||||
|| (byName==null && !_patterns.hasIncludes() && byLocation==null && !_locations.hasIncludes());
|
||||
boolean excluded = Boolean.FALSE.equals(byName) || Boolean.FALSE.equals(byLocation);
|
||||
return included && !excluded;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue