> module Frame.Server ( > server, > testServer > ) where > import qualified Frame.Router as Router > import Network.HTTP.Headers > import Happstack.Server > import Happstack.Server.FastCGI (runFastCGIConcurrent, serverPartToCGI) > import Control.Monad.Trans > import Control.Monad.State (StateT) > import Data.MIME.Types > import qualified Data.ByteString.Lazy as L > import qualified Data.ByteString.UTF8 as U > import Frame.Validation > import Frame.GUI > import Frame.Data > import Frame.Types > import Frame.Config > import Frame.Router > import Frame.Session > simpleCGI :: (ToMessage a) => ServerPartT IO a -> IO () > simpleCGI = runFastCGIConcurrent 10 . serverPartToCGI > runCGI :: ServerPart Response -> IO () > runCGI s = do > simpleCGI s > run :: ServerPart Response -> IO () > run s = do > simpleHTTP nullConf{ port = 3000 } s > serverPart :: ([(String, String)] -> String -> String -> Bool -> IO Data) > -> ServerPart Response > serverPart f = do > r <- askRq > mid <- getDataFn $ lookCookieValue "framesid" > case mid of > Nothing -> do > sid <- liftIO genSessionId > addCookie (3600) (mkCookie "framesid" sid) > routerToResponse f r sid > (Just sid) -> do > addCookie (3600) (mkCookie "framesid" sid) > routerToResponse f r sid > routerToResponse :: ([(String, String)] -> String -> String -> Bool -> IO Data) > -> Request > -> String > -> ServerPart Response > routerToResponse f r sid = withDataFn lookPairs $ > \vs -> do d <- liftIO $ f vs (rqURL r) sid $ isAjax r > dataToResponse d r > dataToResponse :: Data > -> Request > -> ServerPart Response > dataToResponse (File bs) r = return $ detectMime r $ fileResponse bs r > dataToResponse Error404 r = notFound $ htmlContent $ toResponse $ "Could not find " ++ rqURL r > dataToResponse (Redirect u) r = seeOther u $ toResponse $ "See " ++ u > dataToResponse (ViewPart ps) r = return $ htmlContent $ toResponse $ concatMap show ps > dataToResponse (View g) r = return $ htmlContent $ toResponse $ show g > htmlContent :: Response -> Response > htmlContent = setHeader "Content-Type" "text/html" > fileResponse :: L.ByteString > -> Request > -> Response > fileResponse bs r = lazyByteStringResponse (mimeType $ rqURL r) bs Nothing 0 $ fromIntegral $ L.length bs > detectMime :: Request -> Response -> Response > detectMime r = setHeader "Content-Type" (mimeType $ rqURL r) > mimeType :: String -> String > mimeType u = case guessType defaultmtd False u of > (Just t, _) -> t > (Nothing, _) -> "image/jpeg" > isAjax :: Request -> Bool > isAjax r = case getHeader "X-Requested-With" r of > (Just bs) -> U.toString bs == "XMLHttpRequest" > Nothing -> False > -- | Start a test server > testServer :: Router -- ^ The router to run > -> Config -- ^ The configuration > -> Validators -- ^ The validators to check fields against > -> IO () -- ^ The server action > testServer r c v = do > putStr "\nA server is running at http://127.0.0.1:3000/\n" > run $ serverPart $ startRouter r c v > return () > -- | Start Frame using FastCGI > server :: Router -- ^ The router to run > -> Config -- ^ The configuration > -> Validators -- ^ The validators to check fields against > -> IO () -- ^ The server action > server r c v = do > runCGI $ serverPart $ startRouter r c v