403360 Named connectors

This commit is contained in:
Greg Wilkins 2013-04-08 09:25:54 +10:00
parent 120b8c9839
commit 44ec0b3f49
4 changed files with 127 additions and 10 deletions

View File

@ -151,6 +151,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
private long _idleTimeout = 30000;
private String _defaultProtocol;
private ConnectionFactory _defaultConnectionFactory;
private String _name;
/**
@ -524,11 +525,29 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
return _scheduler;
}
@Override
public String getName()
{
return _name;
}
/* ------------------------------------------------------------ */
/**
* Set a connector name. A context may be configured with
* virtual hosts in the form "@contextname" and will only serve
* requests from the named connector,
* @param name A connector name.
*/
public void setName(String name)
{
_name=name;
}
@Override
public String toString()
{
return String.format("%s@%x{%s}",
getClass().getSimpleName(),
_name==null?getClass().getSimpleName():_name,
hashCode(),
getDefaultProtocol());
}

View File

@ -24,6 +24,7 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Graceful;
@ -90,4 +91,15 @@ public interface Connector extends LifeCycle, Graceful
* @return immutable collection of connected endpoints
*/
public Collection<EndPoint> getConnectedEndPoints();
/* ------------------------------------------------------------ */
/**
* Get the connector name if set.
* <p>A {@link ContextHandler} may be configured with
* virtual hosts in the form "@connectorName" and will only serve
* requests from the named connector.
* @return The connector name or null.
*/
public String getName();
}

View File

@ -65,6 +65,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.ClassLoaderDump;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
@ -280,7 +281,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
*
* @param vhosts
* Array of virtual hosts that this context responds to. A null host name or null/empty array means any hostname is acceptable. Host names may be
* String representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
* String representation of IP addresses. Host names may start with '*.' to wildcard one level of names. Hosts may start with '@', in which case they
* will match the {@link Connector#getName()} for the request.
*/
public void setVirtualHosts(String[] vhosts)
{
@ -872,18 +874,29 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
boolean match = false;
for (int i = 0; !match && i < _vhosts.length; i++)
loop: for (String contextVhost:_vhosts)
{
String contextVhost = _vhosts[i];
if (contextVhost == null)
if (contextVhost == null || contextVhost.length()==0)
continue;
if (contextVhost.startsWith("*."))
char c=contextVhost.charAt(0);
switch (c)
{
// wildcard only at the beginning, and only for one additional subdomain level
match = contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - 2);
case '*':
if (contextVhost.startsWith("*."))
// wildcard only at the beginning, and only for one additional subdomain level
match = contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - 2);
break;
case '@':
String name=baseRequest.getHttpChannel().getConnector().getName();
match=name!=null && contextVhost.length()==name.length()+1 && contextVhost.endsWith(name);
break;
default:
match = contextVhost.equalsIgnoreCase(vhost);
}
else
match = contextVhost.equalsIgnoreCase(vhost);
if (match)
break loop;
}
if (!match)
return false;

View File

@ -118,6 +118,79 @@ public class ContextHandlerTest
}
}
@Test
public void testNamedConnector() throws Exception
{
Server server = new Server();
LocalConnector connector = new LocalConnector(server);
LocalConnector connectorN = new LocalConnector(server);
connectorN.setName("name");
server.setConnectors(new Connector[] { connector, connectorN });
ContextHandler contextA = new ContextHandler("/");
contextA.setVirtualHosts(new String[]{"www.example.com" });
IsHandledHandler handlerA = new IsHandledHandler();
contextA.setHandler(handlerA);
ContextHandler contextB = new ContextHandler("/");
IsHandledHandler handlerB = new IsHandledHandler();
contextB.setHandler(handlerB);
contextB.setVirtualHosts(new String[]{ "@name" });
ContextHandler contextC = new ContextHandler("/");
IsHandledHandler handlerC = new IsHandledHandler();
contextC.setHandler(handlerC);
HandlerCollection c = new HandlerCollection();
c.addHandler(contextA);
c.addHandler(contextB);
c.addHandler(contextC);
server.setHandler(c);
server.start();
try
{
connector.getResponses("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
assertTrue(handlerA.isHandled());
assertFalse(handlerB.isHandled());
assertFalse(handlerC.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
connector.getResponses("GET / HTTP/1.0\n" + "Host: localhost\n\n");
assertFalse(handlerA.isHandled());
assertFalse(handlerB.isHandled());
assertTrue(handlerC.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
connectorN.getResponses("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
assertTrue(handlerA.isHandled());
assertFalse(handlerB.isHandled());
assertFalse(handlerC.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
connectorN.getResponses("GET / HTTP/1.0\n" + "Host: localhost\n\n");
assertFalse(handlerA.isHandled());
assertTrue(handlerB.isHandled());
assertFalse(handlerC.isHandled());
handlerA.reset();
handlerB.reset();
handlerC.reset();
}
finally
{
server.stop();
}
}
@Test
public void testContextGetContext() throws Exception