{-# LANGUAGE FlexibleContexts #-} module Network.Salvia.Handler.VirtualHosting where import Data.List.Split import Data.List import Data.Maybe import Network.Protocol.Uri import Network.Protocol.Http import Network.Salvia.Handler.Dispatching import Network.Salvia.Interface {- | Dispatcher based on the host part of the `hostname' request header. Everything not part of the real hostname (like the port number) will be ignored. When the expected hostname starts with a dot (like ".mydomain.com") this indicates that all sub-domains of this domain will match as well. -} hVirtualHosting :: HttpM Request m => ListDispatcher String m b hVirtualHosting = hListDispatch (hRequestDispatch hostname (\a -> False `maybe` (match a))) where match e f = case parseAuthority f of Right (Authority _ hst _) -> case (e, hst) of ('.':_, Hostname (Domain d)) -> filter (not . null) (splitOn "." e) `isSuffixOf` d (_, Hostname d) -> e == show d (_, RegName r) -> e == r (_, IP i) -> e == show i _ -> False {- | Dispatcher based on the port number of the `hostname' request header. When no port number is available in the hostname header port 80 will be assumed. -} hPortRouter :: HttpM Request m => ListDispatcher Int m b hPortRouter = hListDispatch (hRequestDispatch hostname (\a -> False `maybe` (match a))) where match e f = case parseAuthority f of Right (Authority _ _ prt) -> fromMaybe 80 prt == e _ -> False