packages feed

HAppSHelpers-0.9: HAppS/Helpers/ParseRequest.hs

module HAppS.Helpers.ParseRequest where

import HAppS.Server.HTTP.Types
import Text.StringTemplate.Helpers
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as M
import Data.String.Utils (split)
{- |
Try to return the "home page" of a happs server, basically, the host plus an optional path.
The "smart" part is trying to deal sanely with HAppS serving behind apache mod rewrite,
a common situation for me at least
because it lets you have multiple happs servers listening on different ports, all
looking to the casual user like they are being served on port 80, and also unblocked by firewalls.
-}
smartAppUrl :: String -> Request -> String
smartAppUrl path' rq =
  let forwardinghost = getHeaderVal "x-forwarded-server" rq
      vanillahost = getHeaderVal "host" rq
      apphost = case forwardinghost of
        Right h -> h
        Left _ -> case vanillahost of
          Right h -> h
          Left _ -> "getAppUrlCantDetermineHost" --ugly way to propogate error!
      -- trim starting slash if necessary
      path = case path' of
               "" -> ""
               '/':cs -> cs
               x -> x
  in render1 [("apphost",apphost),("path",path)] "http://$apphost$/$path$"



{- | 
getHost = getHeaderVal \"host\" 

returns host with port numbers, if anything other than default 80
-}
getHost :: Request -> Either String String
getHost = getHeaderVal "host" 

{- |
retrieve val of header for key supplied, or an error message if the key isn't found
-}
getHeaderVal :: String -> Request -> Either String String
getHeaderVal headerKey rq = maybe (Left $ "getHeaderVal, bad headerKey: " ++ headerKey)
                                         ( Right . B.unpack . head . hValue )
                                         ( M.lookup ( B.pack headerKey ) . rqHeaders $ rq )

{- | 
host with port number stripped out, if any. 

Useful, for example, for getting the right address to ssh to. 
-}
getDomain :: Request -> Either String String
getDomain rq = do
  h <- getHost rq
  let parts = split ":" h
  case parts of
        [d] -> Right d
        [d,p] -> Right d
        xs -> Left $ "getDomain, bad domain: " ++ h