Issue #1785 Added vhost@connectorname format for AND behaviour

Signed-off-by: Steve Bolton <steve@boltn.com>
This commit is contained in:
Steve Bolton 2018-04-06 20:06:51 -04:00
parent ea6d18f919
commit a30ed56ac1
2 changed files with 195 additions and 27 deletions

View File

@ -970,38 +970,39 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (_vhosts != null && _vhosts.length > 0)
{
String vhost = normalizeHostname(baseRequest.getServerName());
boolean match = false;
boolean connectorName = false;
boolean connectorMatch = false;
for (String contextVhost:_vhosts)
String connectorName = baseRequest.getHttpChannel().getConnector().getName();
for (String contextVhost : _vhosts)
{
if (contextVhost == null || contextVhost.length()==0)
if (contextVhost == null || contextVhost.length() == 0)
continue;
char c=contextVhost.charAt(0);
switch (c)
{
case '*':
if (contextVhost.startsWith("*."))
// wildcard only at the beginning, and only for one additional subdomain level
match = match || contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - 2);
break;
case '@':
connectorName=true;
String name=baseRequest.getHttpChannel().getConnector().getName();
boolean m=name!=null && contextVhost.length()==name.length()+1 && contextVhost.endsWith(name);
match = match || m;
connectorMatch = connectorMatch || m;
break;
default:
match = match || contextVhost.equalsIgnoreCase(vhost);
}
int connectorPos = contextVhost.indexOf('@') + 1;
if (connectorPos > 0)
{
// If connector specifier in vhost entry and no match then continue to next entry
// no need to check host
if (connectorName == null || !contextVhost.regionMatches(true,connectorPos,connectorName,0,connectorName.length()))
continue;
// If we matched connector and no host portion was specified we match
if (connectorPos == 1)
return true;
}
// At this point either connector was specified and there was a connector match,
// we then check host portion, or no connector was specified in entry so we check
// whole original vhost entry
if (contextVhost.startsWith("*."))
{
// wildcard only at the beginning, and only for one additional subdomain level
if (contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - (connectorPos + 2)))
return true;
}
else if (contextVhost.regionMatches(true,0,vhost,0,contextVhost.length() - connectorPos))
return true;
}
if (!match || connectorName && !connectorMatch)
return false;
// vhosts were specified but no matches so fail
return false;
}
// If no vhost entries we always match
return true;
}

View File

@ -138,10 +138,41 @@ public class ContextHandlerTest
IsHandledHandler handlerC = new IsHandledHandler();
contextC.setHandler(handlerC);
ContextHandler contextD = new ContextHandler("/");
IsHandledHandler handlerD = new IsHandledHandler();
contextD.setHandler(handlerD);
contextD.setVirtualHosts(new String[]{ "www.example.com@name" });
ContextHandler contextE = new ContextHandler("/");
IsHandledHandler handlerE = new IsHandledHandler();
contextE.setHandler(handlerE);
contextE.setVirtualHosts(new String[]{ "*.example.com" });
ContextHandler contextF = new ContextHandler("/");
IsHandledHandler handlerF = new IsHandledHandler();
contextF.setHandler(handlerF);
contextF.setVirtualHosts(new String[]{ "*.example.com@name" });
ContextHandler contextG = new ContextHandler("/");
IsHandledHandler handlerG = new IsHandledHandler();
contextG.setHandler(handlerG);
contextG.setVirtualHosts(new String[]{ "*.com@name" });
ContextHandler contextH = new ContextHandler("/");
IsHandledHandler handlerH = new IsHandledHandler();
contextH.setHandler(handlerH);
contextH.setVirtualHosts(new String[]{ "*.com" });
HandlerCollection c = new HandlerCollection();
c.addHandler(contextA);
c.addHandler(contextB);
c.addHandler(contextC);
c.addHandler(contextD);
c.addHandler(contextE);
c.addHandler(contextF);
c.addHandler(contextG);
c.addHandler(contextH);
server.setHandler(c);
server.start();
@ -151,39 +182,175 @@ public class ContextHandlerTest
Assert.assertTrue(handlerA.isHandled());
Assert.assertFalse(handlerB.isHandled());
Assert.assertFalse(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertFalse(handlerE.isHandled());
Assert.assertFalse(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
connector.getResponse("GET / HTTP/1.0\n" + "Host: localhost\n\n");
Assert.assertFalse(handlerA.isHandled());
Assert.assertFalse(handlerB.isHandled());
Assert.assertTrue(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertFalse(handlerE.isHandled());
Assert.assertFalse(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
connectorN.getResponse("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
Assert.assertTrue(handlerA.isHandled());
Assert.assertFalse(handlerB.isHandled());
Assert.assertFalse(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertFalse(handlerE.isHandled());
Assert.assertFalse(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
connectorN.getResponse("GET / HTTP/1.0\n" + "Host: localhost\n\n");
Assert.assertFalse(handlerA.isHandled());
Assert.assertTrue(handlerB.isHandled());
Assert.assertFalse(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertFalse(handlerE.isHandled());
Assert.assertFalse(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
}
finally
{
server.stop();
}
// Reversed order to check priority when multiple matches
HandlerCollection d = new HandlerCollection();
d.addHandler(contextH);
d.addHandler(contextG);
d.addHandler(contextF);
d.addHandler(contextE);
d.addHandler(contextD);
d.addHandler(contextC);
d.addHandler(contextB);
d.addHandler(contextA);
server.setHandler(d);
server.start();
try
{
connector.getResponse("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
Assert.assertFalse(handlerA.isHandled());
Assert.assertFalse(handlerB.isHandled());
Assert.assertFalse(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertTrue(handlerE.isHandled());
Assert.assertFalse(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
connector.getResponse("GET / HTTP/1.0\n" + "Host: localhost\n\n");
Assert.assertFalse(handlerA.isHandled());
Assert.assertFalse(handlerB.isHandled());
Assert.assertTrue(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertFalse(handlerE.isHandled());
Assert.assertFalse(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
connectorN.getResponse("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
Assert.assertFalse(handlerA.isHandled());
Assert.assertFalse(handlerB.isHandled());
Assert.assertFalse(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertFalse(handlerE.isHandled());
Assert.assertTrue(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
connectorN.getResponse("GET / HTTP/1.0\n" + "Host: localhost\n\n");
Assert.assertFalse(handlerA.isHandled());
Assert.assertFalse(handlerB.isHandled());
Assert.assertTrue(handlerC.isHandled());
Assert.assertFalse(handlerD.isHandled());
Assert.assertFalse(handlerE.isHandled());
Assert.assertFalse(handlerF.isHandled());
Assert.assertFalse(handlerG.isHandled());
Assert.assertFalse(handlerH.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
handlerD.reset();
handlerE.reset();
handlerF.reset();
handlerG.reset();
handlerH.reset();
}
finally
{
server.stop();
}
}