diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index bcc13aa3cdd..2fced56d1a8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java @@ -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()); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java index 3454c7869ec..6866e5e49a1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java @@ -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 getConnectedEndPoints(); + + + /* ------------------------------------------------------------ */ + /** + * Get the connector name if set. + *

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(); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 4d15352b28d..3d5fad459cb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -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; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java index b8fe723dec0..f9d07f47b83 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java @@ -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 diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index 6de3b7e48bf..1e50dd1249d 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -71,7 +71,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope private static final Logger LOG = Log.getLogger(ServletHolder.class); /* ---------------------------------------------------------------- */ - private int _initOrder; + private int _initOrder = -1; private boolean _initOnStartup=false; private Map _roleMap; private String _forcedPath; @@ -179,7 +179,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope */ public void setInitOrder(int order) { - _initOnStartup=order>0; + _initOnStartup=order>=0; _initOrder = order; } @@ -329,7 +329,6 @@ public class ServletHolder extends Holder implements UserIdentity.Scope throws Exception { super.initialize(); - if (_extInstance || _initOnStartup) { try diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java index 4c06368b4bd..b923e53d8cb 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java @@ -130,8 +130,8 @@ public class ServletContextHandlerTest holder0.setInitOrder(0); _server.start(); - assertEquals(2,__testServlets.get()); - assertThat(holder0.getServletInstance(),nullValue()); + assertEquals(3,__testServlets.get()); + assertThat(holder0.getServletInstance(),notNullValue(Servlet.class)); _server.stop(); assertEquals(0,__testServlets.get());