Class VirtualHostManager

java.lang.Object
com.ns.tcpframework.VirtualHostManager

public class VirtualHostManager extends Object
Manages virtual host configurations and resolves hostnames to their corresponding virtual hosts.

The VirtualHostManager acts as a registry and resolver for name-based virtual hosting, maintaining a collection of virtual host configurations and selecting the appropriate configuration based on the HTTP Host header in incoming requests. This enables a single HTTP server instance to serve multiple domains or websites with distinct configurations.

Key responsibilities:

  • Virtual host registration and storage
  • Hostname-to-configuration resolution with case-insensitive matching
  • Default virtual host fallback for unmatched hostnames
  • SSE handler discovery across all virtual hosts

Hostname matching behavior:

  • Hostnames are normalized to lowercase for case-insensitive matching
  • Exact hostname match takes precedence
  • Default virtual host is returned when no match is found
  • Port numbers should be stripped from hostnames before lookup

Usage example:

// Create default virtual host
VirtualHostConfig defaultHost = new VirtualHostConfig("default", "/var/www/default");

// Create manager
VirtualHostManager manager = new VirtualHostManager(defaultHost);

// Register virtual hosts
VirtualHostConfig exampleHost = new VirtualHostConfig("example.com", "/var/www/example");
manager.registerVirtualHost(exampleHost);

VirtualHostConfig apiHost = new VirtualHostConfig("api.example.com", "/var/www/api");
manager.registerVirtualHost(apiHost);

// Resolve during request handling
String requestHost = request.getHost(); // "example.com"
VirtualHostConfig host = manager.getVirtualHost(requestHost);

Thread-safety: This class is not inherently thread-safe. Virtual hosts should be registered during initialization before concurrent request handling begins. The getVirtualHost(String) method can be safely called concurrently once registration is complete.

See Also:
  • Constructor Details

    • VirtualHostManager

      public VirtualHostManager(VirtualHostConfig defaultVirtualHost)
      Constructs a VirtualHostManager with the specified default virtual host.

      The default virtual host is used as a fallback when hostname resolution fails, ensuring that all requests can be processed even if no matching virtual host is found. This is essential for handling:

      • Requests with missing or malformed Host headers
      • Requests to unregistered hostnames
      • HTTP/1.0 requests that may not include a Host header

      After construction, virtual hosts can be registered using registerVirtualHost(VirtualHostConfig).

      Parameters:
      defaultVirtualHost - The virtual host configuration to use as a fallback when no matching host is found. Must not be null.
  • Method Details

    • registerVirtualHost

      public void registerVirtualHost(VirtualHostConfig vhost)
      Registers a virtual host configuration with this manager.

      The virtual host's hostname is extracted and normalized to lowercase before being stored in the registry. This enables case-insensitive hostname matching during request handling.

      If a virtual host with the same hostname (case-insensitive) already exists, it will be replaced with the new configuration. This allows for dynamic reconfiguration if needed, though this is uncommon in production environments.

      Virtual hosts should typically be registered during server initialization before request handling begins to avoid race conditions.

      Parameters:
      vhost - The virtual host configuration to register. Must not be null. The hostname from vhost.getHost() is used as the key.
    • getVirtualHost

      public VirtualHostConfig getVirtualHost(String host)
      Resolves a hostname to its corresponding virtual host configuration.

      This method performs case-insensitive hostname matching by normalizing the provided hostname to lowercase before lookup. If no matching virtual host is found, the default virtual host is returned as a fallback.

      Hostname resolution process:

      1. Convert the requested hostname to lowercase
      2. Look up the hostname in the virtual hosts registry
      3. Return the matched configuration, or the default if no match found

      Expected hostname format: The hostname should be the bare domain name without port numbers (e.g., "example.com" not "example.com:8080"). Port stripping should be performed by the caller before invoking this method.

      This method is designed to be called during request handling for each incoming HTTP request to determine which virtual host should process the request.

      Parameters:
      host - The hostname to resolve (e.g., "example.com", "www.example.com"). Must not be null. Should not include port numbers. Case-insensitive.
      Returns:
      The matching VirtualHostConfig if found, or the default virtual host if no match exists. Never returns null.
    • getVirtualHosts

      public Map<String, VirtualHostConfig> getVirtualHosts()
      Gets the map of all registered virtual host configurations.

      The returned map contains lowercase hostname-to-configuration mappings for all registered virtual hosts (excluding the default host). Modifying this map will affect hostname resolution, though direct modification is not recommended - use registerVirtualHost(VirtualHostConfig) instead.

      This method is primarily useful for:

      • Iterating over all configured virtual hosts
      • Discovering SSE handlers across virtual hosts
      • Administrative or monitoring operations
      Returns:
      A map of lowercase hostnames to VirtualHostConfig objects. Never null, but may be empty if no virtual hosts have been registered.
    • getSSEHandler

      public SSEHandler getSSEHandler()
      Finds and returns the first SSE handler from any registered virtual host.

      This method searches through all registered virtual hosts (not including the default host) to find a virtual host that has an SSEHandler registered on its router. The first SSE handler found is returned.

      This method is useful for:

      • Initializing the ServerLogger with SSE broadcast capability
      • Broadcasting server-wide events to connected clients
      • Checking if SSE functionality is available in the server configuration

      Discovery behavior:

      • Iterates through registered virtual hosts in no particular order
      • Returns the first non-null SSE handler found
      • Returns null if no virtual host has an SSE handler registered
      • Does not check the default virtual host

      Note: If multiple SSE handlers are registered across different virtual hosts, only one will be returned. For server-wide broadcasting, typically only one SSE endpoint should be configured.

      Returns:
      The first SSEHandler found in any registered virtual host, or null if no SSE handler is registered on any virtual host.
      See Also: