{-# LANGUAGE OverloadedStrings, DeriveGeneric #-} module SessionID ( SessionID, mkSessionID, sessionLogFile, withSessionID, sessionIDUrl, ) where import Serialization import System.FilePath import Data.Text import System.IO import Network.Wai.Handler.Warp (Port) import Network.WebSockets hiding (Message) import qualified Data.Aeson import Data.Maybe -- | A SessionID is the base name of the log file to use, -- and may not contain any path information. newtype SessionID = SessionID FilePath deriving (Show, Eq, Ord, Generic) instance ToJSON SessionID instance FromJSON SessionID instance WebSocketsData SessionID where -- fromDataMessage = fromLazyByteString . fromDataMessage fromLazyByteString = fromMaybe (error "bad SessionID") . Data.Aeson.decode toLazyByteString = Data.Aeson.encode -- | Smart constructor that enforces legal SessionID contents. -- -- The passed Text can either be the bare SessionID, or it can be an URL -- which ends with the SessionID. mkSessionID :: Text -> Maybe SessionID mkSessionID t = let s = unpack t in if "http" `isPrefixOf` t then Just $ SessionID $ takeFileName s else if takeFileName s == s then Just $ SessionID s else Nothing sessionLogFile :: FilePath -> SessionID -> FilePath sessionLogFile dir (SessionID f) = dir "debug-me." ++ f ++ ".log" -- | Allocate a new SessionID and return an open Handle to its log file. withSessionID :: FilePath -> ((Handle, SessionID) -> IO a) -> IO a withSessionID dir a = do -- TODO find an unused log file and open it let sid = SessionID "1" withFile "debug-me-server.log" WriteMode $ \h -> a (h, sid) type UrlString = String sessionIDUrl :: SessionID -> String -> Port -> UrlString sessionIDUrl (SessionID f) host port = "http://" ++ host ++ ":" ++ show port ++ "/" ++ f