I've crafted a simple patch which extends the API of the embedded HTTP
server to support virtual hosts. The patch is designed to add the new
functionality without breaking existing implementations which do not
support virtual hosts, or code which uses the HttpServer API today. It
does not include an implementation; however, the default implementation
should be easy to extend, from a brief look over the code.
The patch is attached. Please let me know what you think.
- DML
diff -r dde3fe2e8164 src/share/classes/com/sun/net/httpserver/HostMatcher.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/net/httpserver/HostMatcher.java Fri Dec 04 14:10:23 2009 -0600
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+
+/**
+ * A matcher which determines whether some incoming request matches a virtual
+ * host registration. See {...@link HttpServer#createVirtualHost(HostMatcher)} for
+ * more information about virtual host registration.
+ *
+ * @since 1.7
+ */
+public interface HostMatcher {
+ /**
+ * Determine whether a HTTP request matches a virtual host registration.
+ *
+ * @param exchange the request exchange
+ * @return {...@code true} if the request matches, {...@code false} otherwise
+ */
+ boolean matches(HttpExchange exchange);
+}
diff -r dde3fe2e8164 src/share/classes/com/sun/net/httpserver/HttpHost.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/net/httpserver/HttpHost.java Fri Dec 04 14:10:23 2009 -0600
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+
+/**
+ * This class implements a simple HTTP host. A HttpHost may be "real" or "virtual".
+ * A "real" host is one which is bound to an IP address and extends the {...@link HttpServer}
+ * subclass. A "virtual" host allows for more than one set of registered contexts
+ * per physical server, differentiated by host name, IP address, or other criteria.
+ * <p>
+ * One or more {...@link HttpHandler} objects must be associated with a host
+ * in order to process requests. Each such HttpHandler is registered
+ * with a root URI path which represents the
+ * location of the application or service on this server. The mapping of a handler
+ * to a {...@code HttpHost} is essentially equivalent to the mapping of a handler to a
+ * {...@link HttpServer}.
+ *
+ * @since 1.7
+ */
+public abstract class HttpHost {
+ /**
+ * Creates a {...@code HttpContext}. A {...@code HttpContext} represents a mapping from a
+ * URI path to a exchange handler on this {...@code HttpHost}. Once created, all requests
+ * received by the server for the path will be handled by calling
+ * the given handler object. The context is identified by the path, and
+ * can later be removed from the server using this with the {...@link #removeContext(String)} method.
+ * <p>
+ * The path specifies the root URI path for this context. The first character of path must be
+ * {...@code '/'}. <p>
+ * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
+ * to HttpContext instances.
+ * @param path the root URI path to associate the context with
+ * @param handler the handler to invoke for incoming requests.
+ * @throws IllegalArgumentException if path is invalid, or if a context
+ * already exists for this path
+ * @throws NullPointerException if either path, or handler are <code>null</code>
+ */
+ public abstract HttpContext createContext (String path, HttpHandler handler) ;
+
+ /**
+ * Creates a {...@code HttpContext} without initially specifying a handler. The handler must later be specified using
+ * {...@link com.sun.net.httpserver.HttpContext#setHandler(com.sun.net.httpserver.HttpHandler)}. A {...@code HttpContext} represents a mapping from a
+ * URI path to an exchange handler on this {...@code HttpHost}. Once created, and when
+ * the handler has been set, all requests
+ * received by the server for the path will be handled by calling
+ * the handler object. The context is identified by the path, and
+ * can later be removed from the server using this with the {...@link #removeContext(String)} method.
+ * <p>
+ * The path specifies the root URI path for this context. The first character of path must be
+ * {...@code '/'}. <p>
+ * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
+ * to HttpContext instances.
+ * @param path the root URI path to associate the context with
+ * @throws IllegalArgumentException if path is invalid, or if a context
+ * already exists for this path
+ * @throws NullPointerException if path is <code>null</code>
+ */
+ public abstract HttpContext createContext (String path) ;
+
+ /**
+ * Removes the context identified by the given path from the server.
+ * Removing a context does not affect exchanges currently being processed
+ * but prevents new ones from being accepted.
+ * @param path the path of the handler to remove
+ * @throws IllegalArgumentException if no handler corresponding to this
+ * path exists.
+ * @throws NullPointerException if path is <code>null</code>
+ */
+ public abstract void removeContext (String path) throws IllegalArgumentException ;
+
+ /**
+ * Removes the given context from the server.
+ * Removing a context does not affect exchanges currently being processed
+ * but prevents new ones from being accepted.
+ * @param context the context to remove
+ * @throws NullPointerException if context is <code>null</code>
+ */
+ public abstract void removeContext (HttpContext context) ;
+}
diff -r dde3fe2e8164 src/share/classes/com/sun/net/httpserver/HttpServer.java
--- a/src/share/classes/com/sun/net/httpserver/HttpServer.java Wed Feb 25 14:32:01 2009 +0000
+++ b/src/share/classes/com/sun/net/httpserver/HttpServer.java Fri Dec 04 14:10:23 2009 -0600
@@ -87,7 +87,7 @@
* @since 1.6
*/
-public abstract class HttpServer {
+public abstract class HttpServer extends HttpHost {
/**
*/
@@ -187,64 +187,36 @@
*/
public abstract void stop (int delay);
- /**
- * Creates a HttpContext. A HttpContext represents a mapping from a
- * URI path to a exchange handler on this HttpServer. Once created, all requests
- * received by the server for the path will be handled by calling
- * the given handler object. The context is identified by the path, and
- * can later be removed from the server using this with the {...@link #removeContext(String)} method.
- * <p>
- * The path specifies the root URI path for this context. The first character of path must be
- * '/'. <p>
- * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
- * to HttpContext instances.
- * @param path the root URI path to associate the context with
- * @param handler the handler to invoke for incoming requests.
- * @throws IllegalArgumentException if path is invalid, or if a context
- * already exists for this path
- * @throws NullPointerException if either path, or handler are <code>null</code>
- */
- public abstract HttpContext createContext (String path, HttpHandler handler) ;
+ /** {...@inheritdoc} */
+ public abstract HttpContext createContext (final String path, final HttpHandler handler);
+
+ /** {...@inheritdoc} */
+ public abstract HttpContext createContext (final String path);
+
+ /** {...@inheritdoc} */
+ public abstract void removeContext (final String path) throws IllegalArgumentException;
+
+ /** {...@inheritdoc} */
+ public abstract void removeContext (final HttpContext context);
/**
- * Creates a HttpContext without initially specifying a handler. The handler must later be specified using
- * {...@link HttpContext#setHandler(HttpHandler)}. A HttpContext represents a mapping from a
- * URI path to an exchange handler on this HttpServer. Once created, and when
- * the handler has been set, all requests
- * received by the server for the path will be handled by calling
- * the handler object. The context is identified by the path, and
- * can later be removed from the server using this with the {...@link #removeContext(String)} method.
+ * Creates a virtual host with the given matcher. Each incoming request is
+ * tested against all registered virtual host matchers to determine whether
+ * the request should be handled by a context from a virtual host, or from
+ * the main {...@code HttpServer} instance.
* <p>
- * The path specifies the root URI path for this context. The first character of path must be
- * '/'. <p>
- * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
- * to HttpContext instances.
- * @param path the root URI path to associate the context with
- * @throws IllegalArgumentException if path is invalid, or if a context
- * already exists for this path
- * @throws NullPointerException if path is <code>null</code>
+ * The base implementation
+ * throws {...@code java.lang.UnsupportedOperationException} to avoid breaking
+ * backwards compatibility with existing implementations.
+ *
+ * @param matcher the virtual host matcher to use
+ * @return the virtual host
+ *
+ * @since 1.7
*/
- public abstract HttpContext createContext (String path) ;
-
- /**
- * Removes the context identified by the given path from the server.
- * Removing a context does not affect exchanges currently being processed
- * but prevents new ones from being accepted.
- * @param path the path of the handler to remove
- * @throws IllegalArgumentException if no handler corresponding to this
- * path exists.
- * @throws NullPointerException if path is <code>null</code>
- */
- public abstract void removeContext (String path) throws IllegalArgumentException ;
-
- /**
- * Removes the given context from the server.
- * Removing a context does not affect exchanges currently being processed
- * but prevents new ones from being accepted.
- * @param context the context to remove
- * @throws NullPointerException if context is <code>null</code>
- */
- public abstract void removeContext (HttpContext context) ;
+ public HttpHost createVirtualHost(final HostMatcher matcher) {
+ throw new UnsupportedOperationException("Virutal hosts not supported by this implementation");
+ }
/**
* returns the address this server is listening on
diff -r dde3fe2e8164 src/share/classes/sun/net/httpserver/HttpServerImpl.java
--- a/src/share/classes/sun/net/httpserver/HttpServerImpl.java Wed Feb 25 14:32:01 2009 +0000
+++ b/src/share/classes/sun/net/httpserver/HttpServerImpl.java Fri Dec 04 14:10:23 2009 -0600
@@ -86,6 +86,10 @@
server.removeContext (context);
}
+ public HttpHost createVirtualHost(final HostMatcher matcher) {
+ return server.createVirtualHost(matcher);
+ }
+
public InetSocketAddress getAddress() {
return server.getAddress();
}