Addresses #3562
## Ports the `ipaccess` being added as a module from jetty 10 you can now do `java -jar start.jar --add-to-start=inetaccess` to add the inetaccess handler to your jetty config. ## Allows you to specify a list of connector names that the `InetAccessHandler` applies to This is important for those who run jetty using `start.jar` to make it possible to do things like have an open HTTPS connector but a whitelist restricted HTTP connector. Example: `etc/jetty-inetaccess.xml` ``` <?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="exclude"><Arg>127.0.0.128-127.0.0.129</Arg></Call> <Call name="includeConnectorName"><Arg>http</Arg></Call> </New> </Arg> </Call> </Configure> ``` You can now `java -jar start.jar --add-to-start=https` and `java -jar start.jar --add-to-start=inetaccess` And you can now choose what inetaccess handler rules apply to http versus https. ## Adds a basic `InetAccessHandler` Unit Test Cover a few of the basic features of InetAccessHandler so it can have some coverage. Signed-off-by: Nicholas DiPiazza <nicholas.dipiazza@lucidworks.com>
This commit is contained in:
parent
205c4dc498
commit
1f4189eb19
|
@ -0,0 +1,23 @@
|
||||||
|
<?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">
|
||||||
|
|
||||||
|
<!-- include - Inclusive list of Inet address range to allow through. -->
|
||||||
|
<!--<Call name="include"><Arg>127.0.0.1-127.0.0.255</Arg></Call>-->
|
||||||
|
|
||||||
|
<!-- exclude - Exclusive list of Inet address ranges to block. -->
|
||||||
|
<!--<Call name="exclude"><Arg>127.0.0.128-127.0.0.129</Arg></Call>-->
|
||||||
|
|
||||||
|
<!-- includeConnectorName - This access handler will only apply to these connector names. -->
|
||||||
|
<!--<Call name="includeConnectorName"><Arg>http</Arg></Call>-->
|
||||||
|
|
||||||
|
<!-- excludeConnectorName - This access handler will not apply to these connector names. -->
|
||||||
|
<!--<Call name="excludeConnectorName"><Arg>tls</Arg></Call>-->
|
||||||
|
</New>
|
||||||
|
</Arg>
|
||||||
|
</Call>
|
||||||
|
</Configure>
|
|
@ -0,0 +1,14 @@
|
||||||
|
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.
|
||||||
|
|
||||||
|
[tags]
|
||||||
|
handler
|
||||||
|
|
||||||
|
[depend]
|
||||||
|
server
|
||||||
|
|
||||||
|
[xml]
|
||||||
|
etc/jetty-inetaccess.xml
|
|
@ -32,6 +32,7 @@ import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.server.HttpChannel;
|
import org.eclipse.jetty.server.HttpChannel;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.util.IPAddressMap;
|
import org.eclipse.jetty.util.IPAddressMap;
|
||||||
|
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
@ -347,40 +348,11 @@ public class IPAccessHandler extends HandlerWrapper
|
||||||
/**
|
/**
|
||||||
* Dump the handler configuration
|
* Dump the handler configuration
|
||||||
*/
|
*/
|
||||||
@Override
|
public void dump(Appendable out, String indent) throws IOException
|
||||||
public String dump()
|
|
||||||
{
|
{
|
||||||
StringBuilder buf = new StringBuilder();
|
dumpObjects(out, indent,
|
||||||
|
DumpableCollection.from("white", _white),
|
||||||
buf.append(toString());
|
DumpableCollection.from("black", _black),
|
||||||
buf.append(" WHITELIST:\n");
|
DumpableCollection.from("whiteListByPath", _whiteListByPath));
|
||||||
dump(buf, _white);
|
|
||||||
buf.append(toString());
|
|
||||||
buf.append(" BLACKLIST:\n");
|
|
||||||
dump(buf, _black);
|
|
||||||
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Dump a pattern map into a StringBuilder buffer
|
|
||||||
*
|
|
||||||
* @param buf buffer
|
|
||||||
* @param patternMap pattern map to dump
|
|
||||||
*/
|
|
||||||
protected void dump(StringBuilder buf, PathMap<IPAddressMap<Boolean>> patternMap)
|
|
||||||
{
|
|
||||||
for (String path: patternMap.keySet())
|
|
||||||
{
|
|
||||||
for (String addr: patternMap.get(path).keySet())
|
|
||||||
{
|
|
||||||
buf.append("# ");
|
|
||||||
buf.append(addr);
|
|
||||||
buf.append("|");
|
|
||||||
buf.append(path);
|
|
||||||
buf.append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.server.HttpChannel;
|
import org.eclipse.jetty.server.HttpChannel;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
|
import org.eclipse.jetty.util.IncludeExclude;
|
||||||
import org.eclipse.jetty.util.IncludeExcludeSet;
|
import org.eclipse.jetty.util.IncludeExcludeSet;
|
||||||
import org.eclipse.jetty.util.InetAddressSet;
|
import org.eclipse.jetty.util.InetAddressSet;
|
||||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||||
|
@ -39,16 +40,32 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
/**
|
/**
|
||||||
* InetAddress Access Handler
|
* InetAddress Access Handler
|
||||||
* <p>
|
* <p>
|
||||||
* Controls access to the wrapped handler using the real remote IP. Control is provided
|
* Controls access to the wrapped handler using the real remote IP. Control is
|
||||||
* by and {@link IncludeExcludeSet} over a {@link InetAddressSet}. This handler
|
* provided by and {@link IncludeExcludeSet} over a {@link InetAddressSet}. This
|
||||||
* uses the real internet address of the connection, not one reported in the forwarded
|
* handler uses the real internet address of the connection, not one reported in
|
||||||
* for headers, as this cannot be as easily forged.
|
* 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
|
public class InetAccessHandler extends HandlerWrapper
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(InetAccessHandler.class);
|
private static final Logger LOG = Log.getLogger(InetAccessHandler.class);
|
||||||
|
|
||||||
private final IncludeExcludeSet<String, InetAddress> _set = new IncludeExcludeSet<>(InetAddressSet.class);
|
private final IncludeExcludeSet<String, InetAddress> _set = new IncludeExcludeSet<>(InetAddressSet.class);
|
||||||
|
private final IncludeExclude<String> _connectorNames = new IncludeExclude<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all the includes, excludes, included connector names and excluded
|
||||||
|
* connector names.
|
||||||
|
*/
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
_set.clear();
|
||||||
|
_connectorNames.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Includes an InetAddress pattern
|
* Includes an InetAddress pattern
|
||||||
|
@ -94,11 +111,52 @@ public class InetAccessHandler extends HandlerWrapper
|
||||||
_set.exclude(patterns);
|
_set.exclude(patterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes a connector name.
|
||||||
|
*
|
||||||
|
* @param name Connector name to include in this handler.
|
||||||
|
*/
|
||||||
|
public void includeConnectorName(String name)
|
||||||
|
{
|
||||||
|
_connectorNames.include(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excludes a connector name.
|
||||||
|
*
|
||||||
|
* @param name Connector name to exclude in this handler.
|
||||||
|
*/
|
||||||
|
public void excludeConnectorName(String name)
|
||||||
|
{
|
||||||
|
_connectorNames.exclude(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes connector names.
|
||||||
|
*
|
||||||
|
* @param names Connector names to include in this handler.
|
||||||
|
*/
|
||||||
|
public void includeConnectorNames(String... names)
|
||||||
|
{
|
||||||
|
_connectorNames.include(names);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excludes connector names.
|
||||||
|
*
|
||||||
|
* @param names Connector names to exclude in this handler.
|
||||||
|
*/
|
||||||
|
public void excludeConnectorNames(String... names)
|
||||||
|
{
|
||||||
|
_connectorNames.exclude(names);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the incoming request against the whitelist and blacklist
|
* Checks the incoming request against the whitelist and blacklist
|
||||||
*/
|
*/
|
||||||
@Override
|
@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))
|
// Get the real remote IP (not the one set by the forwarded headers (which may be forged))
|
||||||
HttpChannel channel = baseRequest.getHttpChannel();
|
HttpChannel channel = baseRequest.getHttpChannel();
|
||||||
|
@ -108,7 +166,7 @@ public class InetAccessHandler extends HandlerWrapper
|
||||||
if (endp != null)
|
if (endp != null)
|
||||||
{
|
{
|
||||||
InetSocketAddress address = endp.getRemoteAddress();
|
InetSocketAddress address = endp.getRemoteAddress();
|
||||||
if (address != null && !isAllowed(address.getAddress(), request))
|
if (address != null && !isAllowed(address.getAddress(), baseRequest, request))
|
||||||
{
|
{
|
||||||
response.sendError(HttpStatus.FORBIDDEN_403);
|
response.sendError(HttpStatus.FORBIDDEN_403);
|
||||||
baseRequest.setHandled(true);
|
baseRequest.setHandled(true);
|
||||||
|
@ -123,23 +181,46 @@ public class InetAccessHandler extends HandlerWrapper
|
||||||
/**
|
/**
|
||||||
* Checks if specified address and request are allowed by current InetAddress rules.
|
* Checks if specified address and request are allowed by current InetAddress rules.
|
||||||
*
|
*
|
||||||
* @param address the inetAddress to check
|
* @param address the inetAddress to check
|
||||||
* @param request the request to check
|
* @param baseRequest the base request to check
|
||||||
|
* @param request the HttpServletRequest request to check
|
||||||
* @return true if inetAddress and request are allowed
|
* @return true if inetAddress and request are allowed
|
||||||
*/
|
*/
|
||||||
protected boolean isAllowed(InetAddress address, HttpServletRequest request)
|
protected boolean isAllowed(InetAddress address, Request baseRequest, HttpServletRequest request)
|
||||||
{
|
{
|
||||||
boolean allowed = _set.test(address);
|
String connectorName = baseRequest.getHttpChannel().getConnector().getName();
|
||||||
|
boolean allowed = !isMatchingConnectorName(connectorName) || _set.test(address);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("{} {} {} for {}", this, allowed ? "allowed" : "denied", address, request);
|
LOG.debug("{} {} {} for {}", this, allowed ? "allowed" : "denied", address, request);
|
||||||
return allowed;
|
return allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this is a connector name that applies to this access handler.
|
||||||
|
*
|
||||||
|
* @return true if connector name is applicable given connectorNames property
|
||||||
|
*/
|
||||||
|
protected boolean isMatchingConnectorName(String connectorName)
|
||||||
|
{
|
||||||
|
boolean hasConnectorNames = !_connectorNames.getIncluded().isEmpty();
|
||||||
|
if (connectorName == null)
|
||||||
|
{
|
||||||
|
return !hasConnectorNames;
|
||||||
|
}
|
||||||
|
if (hasConnectorNames && !_connectorNames.getIncluded().contains(connectorName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !_connectorNames.getExcluded().contains(connectorName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dump(Appendable out, String indent) throws IOException
|
public void dump(Appendable out, String indent) throws IOException
|
||||||
{
|
{
|
||||||
dumpObjects(out, indent,
|
dumpObjects(out, indent,
|
||||||
DumpableCollection.from("included",_set.getIncluded()),
|
DumpableCollection.from("included", _set.getIncluded()),
|
||||||
DumpableCollection.from("excluded",_set.getExcluded()));
|
DumpableCollection.from("excluded", _set.getExcluded()),
|
||||||
|
DumpableCollection.from("includedConnectorNames", _connectorNames.getIncluded()),
|
||||||
|
DumpableCollection.from("excludedConnectorNames", _connectorNames.getExcluded()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,273 @@
|
||||||
|
package org.eclipse.jetty.server.handler;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
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.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;
|
||||||
|
|
||||||
|
public class InetHandlerTest
|
||||||
|
{
|
||||||
|
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 host, String uri, 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.includeConnectorName(inc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String exc : excludeConnectors.split(";", -1)) {
|
||||||
|
if (exc.length() > 0) {
|
||||||
|
_handler.excludeConnectorName(exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String request = "GET " + uri + " HTTP/1.1\n" + "Host: " + host + "\n\n";
|
||||||
|
Socket socket = new Socket("127.0.0.1", _connector.getLocalPort());
|
||||||
|
socket.setSoTimeout(5000);
|
||||||
|
try {
|
||||||
|
OutputStream output = socket.getOutputStream();
|
||||||
|
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
|
||||||
|
output.write(request.getBytes(StandardCharsets.UTF_8));
|
||||||
|
output.flush();
|
||||||
|
|
||||||
|
Response response = readResponse(input);
|
||||||
|
Object[] params = new Object[] { "Request WBHUC", include, exclude, includeConnectors, excludeConnectors,
|
||||||
|
host, uri, code, "Response", response.getCode() };
|
||||||
|
assertEquals(code, response.getCode(), Arrays.deepToString(params));
|
||||||
|
} finally {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected Response readResponse(BufferedReader reader) throws IOException
|
||||||
|
{
|
||||||
|
// Simplified parser for HTTP responses
|
||||||
|
String line = reader.readLine();
|
||||||
|
if (line == null)
|
||||||
|
throw new EOFException();
|
||||||
|
Matcher responseLine = Pattern.compile("HTTP/1\\.1\\s+(\\d+)").matcher(line);
|
||||||
|
assertTrue(responseLine.lookingAt());
|
||||||
|
String code = responseLine.group(1);
|
||||||
|
|
||||||
|
Map<String, String> headers = new LinkedHashMap<>();
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (line.trim().length() == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Matcher header = Pattern.compile("([^:]+):\\s*(.*)").matcher(line);
|
||||||
|
assertTrue(header.lookingAt());
|
||||||
|
String headerName = header.group(1);
|
||||||
|
String headerValue = header.group(2);
|
||||||
|
headers.put(headerName.toLowerCase(Locale.ENGLISH), headerValue.toLowerCase(Locale.ENGLISH));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder body = new StringBuilder();
|
||||||
|
if (headers.containsKey("content-length")) {
|
||||||
|
int length = Integer.parseInt(headers.get("content-length"));
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
char c = (char) reader.read();
|
||||||
|
body.append(c);
|
||||||
|
}
|
||||||
|
} else if ("chunked".equals(headers.get("transfer-encoding"))) {
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if ("0".equals(line)) {
|
||||||
|
line = reader.readLine();
|
||||||
|
assertEquals("", line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = Integer.parseInt(line, 16);
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
char c = (char) reader.read();
|
||||||
|
body.append(c);
|
||||||
|
}
|
||||||
|
line = reader.readLine();
|
||||||
|
assertEquals("", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(code, headers, body.toString().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected class Response
|
||||||
|
{
|
||||||
|
private final String code;
|
||||||
|
private final Map<String, String> headers;
|
||||||
|
private final String body;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
private Response(String code, Map<String, String> headers, String body)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
this.headers = headers;
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public Map<String, String> getHeaders()
|
||||||
|
{
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String getBody()
|
||||||
|
{
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(code).append("\r\n");
|
||||||
|
for (Map.Entry<String, String> entry : headers.entrySet())
|
||||||
|
builder.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
|
||||||
|
builder.append("\r\n");
|
||||||
|
builder.append(body);
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public static Stream<Arguments> data()
|
||||||
|
{
|
||||||
|
Object[][] data = new Object[][] {
|
||||||
|
// Empty lists
|
||||||
|
{ "", "", "", "", "127.0.0.1", "/", "200" }, { "", "", "", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
|
||||||
|
// test simple filters
|
||||||
|
{ "127.0.0.1", "", "", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1", "", "", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "192.0.0.1", "", "", "", "127.0.0.1", "/", "403" },
|
||||||
|
{ "192.0.0.1", "", "", "", "127.0.0.1", "/dump/info", "403" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "", "", "127.0.0.1", "/", "403" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "", "", "127.0.0.1", "/dump/info", "403" },
|
||||||
|
|
||||||
|
// test connector name filters
|
||||||
|
{ "127.0.0.1", "", "http", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1", "", "http", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "http", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "http", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "192.0.0.1", "", "http", "", "127.0.0.1", "/", "403" },
|
||||||
|
{ "192.0.0.1", "", "http", "", "127.0.0.1", "/dump/info", "403" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "http", "", "127.0.0.1", "/", "403" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "http", "", "127.0.0.1", "/dump/info", "403" },
|
||||||
|
|
||||||
|
{ "127.0.0.1", "", "nothttp", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1", "", "nothttp", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "nothttp", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "nothttp", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "192.0.0.1", "", "nothttp", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "192.0.0.1", "", "nothttp", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "nothttp", "", "127.0.0.1", "/", "200" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "nothttp", "", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
|
||||||
|
{ "127.0.0.1", "", "", "http", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1", "", "", "http", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "", "http", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "", "http", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "192.0.0.1", "", "", "http", "127.0.0.1", "/", "200" },
|
||||||
|
{ "192.0.0.1", "", "", "http", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "", "http", "127.0.0.1", "/", "200" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "", "http", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
|
||||||
|
{ "127.0.0.1", "", "", "nothttp", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1", "", "", "nothttp", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "", "nothttp", "127.0.0.1", "/", "200" },
|
||||||
|
{ "127.0.0.1-127.0.0.254", "", "", "nothttp", "127.0.0.1", "/dump/info", "200" },
|
||||||
|
{ "192.0.0.1", "", "", "nothttp", "127.0.0.1", "/", "403" },
|
||||||
|
{ "192.0.0.1", "", "", "nothttp", "127.0.0.1", "/dump/info", "403" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "", "nothttp", "127.0.0.1", "/", "403" },
|
||||||
|
{ "192.0.0.1-192.0.0.254", "", "", "nothttp", "127.0.0.1", "/dump/info", "403" },
|
||||||
|
|
||||||
|
};
|
||||||
|
return Arrays.asList(data).stream().map(Arguments::of);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue