Jetty-12 : Fixing ContextHandlerCollectionTest (#8322)

* Fixing ContextHandlerCollectionTest

* Disabling array Indentation checkstyle

+ Doesn't play nice with Java 17 new switch/case usages.
This commit is contained in:
Joakim Erdfelt 2022-07-20 16:42:45 -05:00 committed by GitHub
parent 68ddee69af
commit b241446e66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 286 additions and 264 deletions

View File

@ -77,9 +77,11 @@
</module>
<!-- Indentation Rules -->
<!-- Disabled: does not support Java 17 new switch/case
<module name="Indentation">
<property name="arrayInitIndent" value="8"/>
</module>
-->
<!-- Interface Type Parameter Name -->
<module name="InterfaceTypeParameterName">

View File

@ -253,14 +253,14 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
* representation of IP addresses. Host names may start with '*.' to wildcard one level of names. Hosts and wildcard hosts may be followed with
* '@connectorname', in which case they will match only if the the {@link Connector#getName()} for the request also matches. If an entry is just
* '@connectorname' it will match any host if that connector was used. Note - In previous versions if one or more connectorname only entries existed
* and non of the connectors matched the handler would not match regardless of any hostname entries. If there is one or more connectorname only
* and none of the connectors matched the handler would not match regardless of any hostname entries. If there is one or more connectorname only
* entries and one or more host only entries but no hostname and connector entries we assume the old behavior and will log a warning. The warning
* can be removed by removing the host entries that were previously being ignored, or modifying to include a hostname and connectorname entry.
*/
@ManagedAttribute(value = "Virtual hosts accepted by the context", readonly = true)
public List<String> getVirtualHosts()
{
return _vhosts.stream().map(VHost::getVHost).collect(Collectors.toList());
return _vhosts.stream().map(VHost::getName).collect(Collectors.toList());
}
@Override
@ -536,9 +536,7 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
if (_vhosts.isEmpty())
return true;
// TODO is this correct?
String host = request.getHttpURI().getHost();
String host = normalizeHostname(request.getHttpURI().getHost());
String connectorName = request.getConnectionMetaData().getConnector().getName();
for (VHost vhost : _vhosts)
@ -750,11 +748,21 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
b.append('{');
if (getDisplayName() != null)
b.append(getDisplayName()).append(',');
b.append(getContextPath()).append(',').append(getResourceBase()).append(',').append(isAvailable());
b.append(getContextPath());
b.append(",b=").append(getResourceBase());
b.append(",a=").append(_availability.get());
for (String vh : vhosts)
if (!vhosts.isEmpty())
{
b.append(',').append(vh);
b.append(",vh=[");
b.append(String.join(",", vhosts));
b.append(']');
}
Handler nestedHandler = getHandler();
if (nestedHandler != null)
{
b.append(",h=");
b.append(nestedHandler);
}
b.append('}');
@ -1040,5 +1048,23 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
{
return _vHost;
}
String getName()
{
if (_vConnector != null)
return '@' + _vConnector;
else
return _vHost;
}
@Override
public String toString()
{
return "VHost{" +
"_vHost='" + _vHost + '\'' +
", _wild=" + _wild +
", _vConnector='" + _vConnector + '\'' +
'}';
}
}
}

View File

@ -14,7 +14,6 @@
package org.eclipse.jetty.server.handler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -248,7 +247,7 @@ public class ContextHandlerCollection extends Handler.Collection
private static final class Branch
{
private final Handler _handler;
private final ContextHandler[] _contexts;
private final List<ContextHandler> _contexts;
Branch(Handler handler)
{
@ -256,16 +255,15 @@ public class ContextHandlerCollection extends Handler.Collection
if (handler instanceof ContextHandler)
{
_contexts = new ContextHandler[]{(ContextHandler)handler};
_contexts = List.of((ContextHandler)handler);
}
else if (handler instanceof Handler.Container)
{
List<ContextHandler> contexts = ((Handler.Container)handler).getDescendants(ContextHandler.class);
_contexts = new ContextHandler[contexts.size()];
System.arraycopy(contexts, 0, _contexts, 0, contexts.size());
_contexts = new ArrayList<>(contexts);
}
else
_contexts = new ContextHandler[0];
_contexts = List.of();
}
Set<String> getContextPaths()
@ -288,7 +286,7 @@ public class ContextHandlerCollection extends Handler.Collection
return false;
}
ContextHandler[] getContextHandlers()
List<ContextHandler> getContextHandlers()
{
return _contexts;
}
@ -301,7 +299,7 @@ public class ContextHandlerCollection extends Handler.Collection
@Override
public String toString()
{
return String.format("{%s,%s}", _handler, Arrays.asList(_contexts));
return String.format("{%s,%s}", _handler, _contexts);
}
}

View File

@ -13,59 +13,106 @@
package org.eclipse.jetty.server.handler;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.fail;
public class ContextHandlerCollectionTest
{
/* TODO
@Test
public void testVirtualHosts() throws Exception
public static Stream<Arguments> virtualHostCases()
{
return Stream.of(
Arguments.of(0, "www.example.com.", "/ctx", "-", HttpStatus.MOVED_PERMANENTLY_301),
Arguments.of(0, "www.example.com.", "/ctx/", "A", HttpStatus.OK_200),
Arguments.of(0, "www.example.com.", "/ctx/info", "A", HttpStatus.OK_200),
Arguments.of(0, "www.example.com", "/ctx/info", "A", HttpStatus.OK_200),
Arguments.of(0, "alias.example.com", "/ctx/info", "A", HttpStatus.OK_200),
Arguments.of(1, "www.example.com.", "/ctx/info", "A", HttpStatus.OK_200),
Arguments.of(1, "www.example.com", "/ctx/info", "A", HttpStatus.OK_200),
Arguments.of(1, "alias.example.com", "/ctx/info", "A", HttpStatus.OK_200),
Arguments.of(1, "www.other.com", "/ctx", "-", HttpStatus.MOVED_PERMANENTLY_301),
Arguments.of(1, "www.other.com", "/ctx/", "B", HttpStatus.OK_200),
Arguments.of(1, "www.other.com", "/ctx/info", "B", HttpStatus.OK_200),
Arguments.of(0, "www.other.com", "/ctx/info", "C", HttpStatus.OK_200),
Arguments.of(0, "www.example.com", "/ctxinfo", "D", HttpStatus.OK_200),
Arguments.of(1, "unknown.com", "/unknown", "D", HttpStatus.OK_200),
Arguments.of(0, "alias.example.com", "/ctx/foo/info", "E", HttpStatus.OK_200),
Arguments.of(0, "alias.example.com", "/ctxlong/info", "F", HttpStatus.OK_200)
);
}
@ParameterizedTest
@MethodSource("virtualHostCases")
public void testVirtualHosts(int useConnectorNum, String host, String uri, String handlerRef, int expectedStatus, TestInfo testInfo) throws Exception
{
Server server = new Server();
LocalConnector connector0 = new LocalConnector(server);
LocalConnector connector1 = new LocalConnector(server);
connector1.setName("connector1");
server.setConnectors(new Connector[]
{connector0, connector1});
server.addConnector(connector0);
server.addConnector(connector1);
ContextHandler contextA = new ContextHandler("/ctx");
contextA.setVirtualHosts(new String[]
{"www.example.com", "alias.example.com"});
IsHandledHandler handlerA = new IsHandledHandler("A");
contextA.setHandler(handlerA);
contextA.setAllowNullPathInfo(true);
contextA.setVirtualHosts(List.of("www.example.com", "alias.example.com"));
contextA.setHandler(new IsHandledHandler("A"));
ContextHandler contextB = new ContextHandler("/ctx");
IsHandledHandler handlerB = new IsHandledHandler("B");
contextB.setHandler(handlerB);
contextB.setVirtualHosts(new String[]
{"*.other.com", "@connector1"});
contextB.setHandler(new IsHandledHandler("B"));
contextB.setVirtualHosts(List.of("*.other.com@connector1"));
ContextHandler contextC = new ContextHandler("/ctx");
IsHandledHandler handlerC = new IsHandledHandler("C");
contextC.setHandler(handlerC);
contextC.setHandler(new IsHandledHandler("C"));
ContextHandler contextD = new ContextHandler("/");
IsHandledHandler handlerD = new IsHandledHandler("D");
contextD.setHandler(handlerD);
contextD.setHandler(new IsHandledHandler("D"));
ContextHandler contextE = new ContextHandler("/ctx/foo");
IsHandledHandler handlerE = new IsHandledHandler("E");
contextE.setHandler(handlerE);
contextE.setHandler(new IsHandledHandler("E"));
ContextHandler contextF = new ContextHandler("/ctxlong");
IsHandledHandler handlerF = new IsHandledHandler("F");
contextF.setHandler(handlerF);
contextF.setHandler(new IsHandledHandler("F"));
ContextHandlerCollection c = new ContextHandlerCollection();
c.addHandler(contextA);
c.addHandler(contextB);
c.addHandler(contextC);
HandlerList list = new HandlerList();
list.addHandler(contextE);
list.addHandler(contextF);
list.addHandler(contextD);
c.addHandler(list);
Handler.Collection handlers = new Handler.Collection();
handlers.addHandler(contextE);
handlers.addHandler(contextF);
handlers.addHandler(contextD);
c.addHandler(handlers);
server.setHandler(c);
@ -73,58 +120,29 @@ public class ContextHandlerCollectionTest
{
server.start();
Object[][] tests = new Object[][]{
{connector0, "www.example.com.", "/ctx", handlerA},
{connector0, "www.example.com.", "/ctx/", handlerA},
{connector0, "www.example.com.", "/ctx/info", handlerA},
{connector0, "www.example.com", "/ctx/info", handlerA},
{connector0, "alias.example.com", "/ctx/info", handlerA},
{connector1, "www.example.com.", "/ctx/info", handlerA},
{connector1, "www.example.com", "/ctx/info", handlerA},
{connector1, "alias.example.com", "/ctx/info", handlerA},
{connector1, "www.other.com", "/ctx", null},
{connector1, "www.other.com", "/ctx/", handlerB},
{connector1, "www.other.com", "/ctx/info", handlerB},
{connector0, "www.other.com", "/ctx/info", handlerC},
{connector0, "www.example.com", "/ctxinfo", handlerD},
{connector1, "unknown.com", "/unknown", handlerD},
{connector0, "alias.example.com", "/ctx/foo/info", handlerE},
{connector0, "alias.example.com", "/ctxlong/info", handlerF},
LocalConnector connector = switch (useConnectorNum)
{
case 0 -> connector0;
case 1 -> connector1;
default -> fail("Unsupported connector number: " + useConnectorNum);
};
for (int i = 0; i < tests.length; i++)
String rawRequest = ("""
GET %s HTTP/1.1\r
Host: %s\r
Connection: close\r
\r
""").formatted(uri, host);
String rawResponse = connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat(testInfo.getDisplayName(), response.getStatus(), is(expectedStatus));
if (response.getStatus() == HttpStatus.OK_200)
{
Object[] test = tests[i];
LocalConnector connector = (LocalConnector)test[0];
String host = (String)test[1];
String uri = (String)test[2];
IsHandledHandler handler = (IsHandledHandler)test[3];
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
String t = String.format("test %d %s@%s --> %s | %s%n", i, uri, host, connector.getName(), handler);
String response = connector.getResponse("GET " + uri + " HTTP/1.0\nHost: " + host + "\n\n");
if (handler == null)
{
assertThat(t, response, Matchers.containsString(" 302 "));
}
else
{
assertThat(t, response, endsWith(handler.toString()));
if (!handler.isHandled())
{
fail("FAILED " + t + "\n" + response);
}
}
assertThat(testInfo.getDisplayName(), response.getContent(), endsWith(handlerRef));
assertThat(testInfo.getDisplayName(), response.get("X-IsHandled-Name"), is(handlerRef));
}
}
finally
@ -133,14 +151,115 @@ public class ContextHandlerCollectionTest
}
}
@Test
public void testVirtualHostWildcard() throws Exception
public static Stream<Arguments> virtualHostWildcardMatchedCases()
{
List<Arguments> args = new ArrayList<>();
List<String> contextHosts;
contextHosts = List.of();
args.add(Arguments.of(contextHosts, "example.com"));
args.add(Arguments.of(contextHosts, ".example.com"));
args.add(Arguments.of(contextHosts, "vhost.example.com"));
contextHosts = List.of("example.com", "*.example.com");
args.add(Arguments.of(contextHosts, "example.com"));
args.add(Arguments.of(contextHosts, ".example.com"));
args.add(Arguments.of(contextHosts, "vhost.example.com"));
contextHosts = List.of("*.example.com");
args.add(Arguments.of(contextHosts, "vhost.example.com"));
args.add(Arguments.of(contextHosts, ".example.com"));
contextHosts = List.of("*.sub.example.com");
args.add(Arguments.of(contextHosts, "vhost.sub.example.com"));
args.add(Arguments.of(contextHosts, ".sub.example.com"));
return args.stream();
}
@ParameterizedTest
@MethodSource("virtualHostWildcardMatchedCases")
public void testVirtualHostWildcardMatched(List<String> contextHosts, String requestHost) throws Exception
{
Server server = new Server();
LocalConnector connector = new LocalConnector(server);
server.setConnectors(new Connector[]{connector});
ContextHandler context = new ContextHandler("/");
context.setVirtualHosts(contextHosts);
context.setHandler(new IsHandledHandler("H"));
ContextHandlerCollection c = new ContextHandlerCollection();
c.addHandler(context);
server.setHandler(c);
try
{
server.start();
String rawRequest = """
GET / HTTP/1.1\r
Host: %s\r
Connection:close\r
\r
""".formatted(requestHost);
String rawResponse = connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat("Response status for [GET " + requestHost + "]", response.getStatus(), is(HttpStatus.OK_200));
assertThat("Response body for [GET " + requestHost + "]", response.getContent(), is("H"));
assertThat("Response Header for [GET " + requestHost + "]", response.get("X-IsHandled-Name"), is("H"));
}
finally
{
server.stop();
}
}
public static Stream<Arguments> virtualHostWildcardNoMatchCases()
{
List<Arguments> args = new ArrayList<>();
List<String> contextHosts;
contextHosts = List.of("example.com", "*.example.com");
args.add(Arguments.of(contextHosts, "badexample.com"));
args.add(Arguments.of(contextHosts, ".badexample.com"));
args.add(Arguments.of(contextHosts, "vhost.badexample.com"));
contextHosts = List.of("*.");
args.add(Arguments.of(contextHosts, "anything.anything"));
contextHosts = List.of("*.example.com");
args.add(Arguments.of(contextHosts, "vhost.www.example.com"));
args.add(Arguments.of(contextHosts, "example.com"));
args.add(Arguments.of(contextHosts, "www.vhost.example.com"));
contextHosts = List.of("*.sub.example.com");
args.add(Arguments.of(contextHosts, ".example.com"));
args.add(Arguments.of(contextHosts, "sub.example.com"));
args.add(Arguments.of(contextHosts, "vhost.example.com"));
contextHosts = List.of("example.*.com", "example.com.*");
args.add(Arguments.of(contextHosts, "example.vhost.com"));
args.add(Arguments.of(contextHosts, "example.com.vhost"));
args.add(Arguments.of(contextHosts, "example.com"));
return args.stream();
}
@ParameterizedTest
@MethodSource("virtualHostWildcardNoMatchCases")
public void testVirtualHostWildcardNoMatch(List<String> contextHosts, String requestHost) throws Exception
{
Server server = new Server();
LocalConnector connector = new LocalConnector(server);
server.setConnectors(new Connector[]{connector});
ContextHandler context = new ContextHandler("/");
context.setVirtualHosts(contextHosts);
IsHandledHandler handler = new IsHandledHandler("H");
context.setHandler(handler);
@ -153,35 +272,22 @@ public class ContextHandlerCollectionTest
try
{
server.start();
checkWildcardHost(true, server, null, new String[]{"example.com", ".example.com", "vhost.example.com"});
checkWildcardHost(false, server, new String[]{null}, new String[]{
"example.com", ".example.com", "vhost.example.com"
});
checkWildcardHost(true, server, new String[]{"example.com", "*.example.com"}, new String[]{
"example.com", ".example.com", "vhost.example.com"
});
checkWildcardHost(false, server, new String[]{"example.com", "*.example.com"}, new String[]{
"badexample.com", ".badexample.com", "vhost.badexample.com"
});
String rawRequest = """
GET / HTTP/1.1\r
Host: %s\r
Connection:close\r
\r
""".formatted(requestHost);
checkWildcardHost(false, server, new String[]{"*."}, new String[]{"anything.anything"});
String rawResponse = connector.getResponse(rawRequest);
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat("Response status for [GET " + requestHost + "]", response.getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat("Response body for [GET " + requestHost + "]", response.getContent(), containsString("<h2>HTTP ERROR 404 Not Found</h2>"));
assertThat("Response Header for [GET " + requestHost + "]", response.get("X-IsHandled-Name"), nullValue());
checkWildcardHost(true, server, new String[]{"*.example.com"}, new String[]{"vhost.example.com", ".example.com"});
checkWildcardHost(false, server, new String[]{"*.example.com"}, new String[]{
"vhost.www.example.com", "example.com", "www.vhost.example.com"
});
checkWildcardHost(true, server, new String[]{"*.sub.example.com"}, new String[]{
"vhost.sub.example.com", ".sub.example.com"
});
checkWildcardHost(false, server, new String[]{"*.sub.example.com"}, new String[]{
".example.com", "sub.example.com", "vhost.example.com"
});
checkWildcardHost(false, server, new String[]{"example.*.com", "example.com.*"}, new String[]{
"example.vhost.com", "example.com.vhost", "example.com"
});
connector.getResponse(rawRequest);
assertFalse(handler.isHandled(), "'" + requestHost + "' should not have been handled.");
}
finally
{
@ -189,33 +295,8 @@ public class ContextHandlerCollectionTest
}
}
private void checkWildcardHost(boolean succeed, Server server, String[] contextHosts, String[] requestHosts) throws Exception
{
LocalConnector connector = (LocalConnector)server.getConnectors()[0];
ContextHandlerCollection handlerCollection = (ContextHandlerCollection)server.getHandler();
ContextHandler context = (ContextHandler)handlerCollection.getHandlers()[0];
IsHandledHandler handler = (IsHandledHandler)context.getHandler();
context.setVirtualHosts(contextHosts);
// trigger this manually
handlerCollection.mapContexts();
for (String host : requestHosts)
{
// System.err.printf("host=%s in %s%n",host,contextHosts==null?Collections.emptyList():Arrays.asList(contextHosts));
String response = connector.getResponse("GET / HTTP/1.0\n" + "Host: " + host + "\nConnection:close\n\n");
// System.err.println(response);
if (succeed)
assertTrue(handler.isHandled(), "'" + host + "' should have been handled.");
else
assertFalse(handler.isHandled(), "'" + host + "' should not have been handled.");
handler.reset();
}
}
@Test
public void testFindContainer() throws Exception
public void testFindContainer()
{
Server server = new Server();
@ -225,7 +306,7 @@ public class ContextHandlerCollectionTest
ContextHandler contextB = new ContextHandler("/b");
IsHandledHandler handlerB = new IsHandledHandler("B");
HandlerWrapper wrapperB = new HandlerWrapper();
Handler.Wrapper wrapperB = new Handler.Wrapper();
wrapperB.setHandler(handlerB);
contextB.setHandler(wrapperB);
@ -239,16 +320,16 @@ public class ContextHandlerCollectionTest
collection.addHandler(contextB);
collection.addHandler(contextC);
HandlerWrapper wrapper = new HandlerWrapper();
Handler.Wrapper wrapper = new Handler.Wrapper();
wrapper.setHandler(collection);
server.setHandler(wrapper);
assertEquals(wrapper, AbstractHandlerContainer.findContainerOf(server, HandlerWrapper.class, handlerA));
assertEquals(contextA, AbstractHandlerContainer.findContainerOf(server, ContextHandler.class, handlerA));
assertEquals(contextB, AbstractHandlerContainer.findContainerOf(server, ContextHandler.class, handlerB));
assertEquals(wrapper, AbstractHandlerContainer.findContainerOf(server, HandlerWrapper.class, handlerB));
assertEquals(contextB, AbstractHandlerContainer.findContainerOf(collection, HandlerWrapper.class, handlerB));
assertEquals(wrapperB, AbstractHandlerContainer.findContainerOf(contextB, HandlerWrapper.class, handlerB));
assertEquals(wrapper, Handler.AbstractContainer.findContainerOf(server, Handler.Wrapper.class, handlerA));
assertEquals(contextA, Handler.AbstractContainer.findContainerOf(server, ContextHandler.class, handlerA));
assertEquals(contextB, Handler.AbstractContainer.findContainerOf(server, ContextHandler.class, handlerB));
assertEquals(wrapper, Handler.AbstractContainer.findContainerOf(server, Handler.Wrapper.class, handlerB));
assertEquals(contextB, Handler.AbstractContainer.findContainerOf(collection, Handler.Wrapper.class, handlerB));
assertEquals(wrapperB, Handler.AbstractContainer.findContainerOf(contextB, Handler.Wrapper.class, handlerB));
}
@Test
@ -264,18 +345,18 @@ public class ContextHandlerCollectionTest
ContextHandler left = new ContextHandler("/left");
left.setHandler(new IsHandledHandler("left"));
HandlerList centre = new HandlerList();
Handler.Collection centre = new Handler.Collection();
ContextHandler centreLeft = new ContextHandler("/leftcentre");
centreLeft.setHandler(new IsHandledHandler("left of centre"));
ContextHandler centreRight = new ContextHandler("/rightcentre");
centreRight.setHandler(new IsHandledHandler("right of centre"));
centre.setHandlers(new Handler[]{centreLeft, new WrappedHandler(centreRight)});
centre.setHandlers(List.of(centreLeft, new WrappedHandler(centreRight)));
ContextHandler right = new ContextHandler("/right");
right.setHandler(new IsHandledHandler("right"));
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[]{root, left, centre, new WrappedHandler(right)});
contexts.setHandlers(List.of(root, left, centre, new WrappedHandler(right)));
server.setHandler(contexts);
server.start();
@ -311,65 +392,6 @@ public class ContextHandlerCollectionTest
assertThat(response, containsString("Wrapped: TRUE"));
}
@Test
public void testAsyncWrappedContext() throws Exception
{
Server server = new Server();
LocalConnector connector = new LocalConnector(server);
server.setConnectors(new Connector[]{connector});
ContextHandler root = new ContextHandler("/");
root.setHandler(new AsyncHandler("root"));
ContextHandler left = new ContextHandler("/left");
left.setHandler(new AsyncHandler("left"));
ContextHandler centreLeft = new ContextHandler("/leftcentre");
centreLeft.setHandler(new AsyncHandler("left of centre"));
ContextHandler centreRight = new ContextHandler("/rightcentre");
centreRight.setHandler(new AsyncHandler("right of centre"));
HandlerList centre = new HandlerList(centreLeft, new WrappedHandler(centreRight));
ContextHandler right = new ContextHandler("/right");
right.setHandler(new AsyncHandler("right"));
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[]{root, left, centre, new WrappedHandler(right)});
server.setHandler(contexts);
server.start();
String response = connector.getResponse("GET / HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));
assertThat(response, endsWith("root"));
assertThat(response, not(containsString("Wrapped: TRUE")));
response = connector.getResponse("GET /foobar/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));
assertThat(response, endsWith("root"));
assertThat(response, not(containsString("Wrapped: TRUE")));
response = connector.getResponse("GET /left/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));
assertThat(response, endsWith("left"));
assertThat(response, not(containsString("Wrapped: TRUE")));
response = connector.getResponse("GET /leftcentre/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));
assertThat(response, endsWith("left of centre"));
assertThat(response, not(containsString("Wrapped: TRUE")));
response = connector.getResponse("GET /rightcentre/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));
assertThat(response, endsWith("right of centre"));
assertThat(response, containsString("Wrapped: ASYNC"));
response = connector.getResponse("GET /right/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));
assertThat(response, endsWith("right"));
assertThat(response, containsString("Wrapped: ASYNC"));
}
private static final class WrappedHandler extends Handler.Wrapper
{
WrappedHandler(Handler handler)
@ -378,17 +400,24 @@ public class ContextHandlerCollectionTest
}
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
public Request.Processor handle(Request request) throws Exception
{
if (response.containsHeader("Wrapped"))
response.getHeaders().put("Wrapped", "ASYNC");
else
response.getHeaders().put("Wrapped", "TRUE");
super.handle(target, baseRequest, request, response);
Request.Processor processor = super.handle(request);
if (processor == null)
return null;
return (req, resp, callback) ->
{
if (resp.getHeaders().contains("Wrapped"))
resp.getHeaders().put("Wrapped", "ASYNC");
else
resp.getHeaders().put("Wrapped", "TRUE");
processor.process(req, resp, callback);
};
}
}
private static final class IsHandledHandler extends AbstractHandler
private static final class IsHandledHandler extends Handler.Abstract
{
private boolean handled;
private final String name;
@ -404,11 +433,15 @@ public class ContextHandlerCollectionTest
}
@Override
public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
public Request.Processor handle(Request request)
{
baseRequest.setHandled(true);
this.handled = true;
response.getWriter().print(name);
return (req, resp, callback) ->
{
this.handled = true;
resp.getHeaders().put("X-IsHandled-Name", name);
ByteBuffer nameBuffer = BufferUtil.toBuffer(name, StandardCharsets.UTF_8);
resp.write(true, nameBuffer, callback);
};
}
public void reset()
@ -422,41 +455,4 @@ public class ContextHandlerCollectionTest
return name;
}
}
private static final class AsyncHandler extends AbstractHandler
{
private final String name;
public AsyncHandler(String string)
{
name = string;
}
@Override
public void handle(String s, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
String n = (String)baseRequest.getAttribute("async");
if (n == null)
{
AsyncContext async = baseRequest.startAsync();
async.setTimeout(1000);
baseRequest.setAttribute("async", name);
async.dispatch();
}
else
{
response.getWriter().print(n);
}
}
@Override
public String toString()
{
return name;
}
}
*/
}