module Network.Salvia.Impl.Server (start) where import Control.Concurrent.ThreadManager import Control.Monad.State import Network.Protocol.Http hiding (accept, hostname) import Network.Salvia.Impl.Config import Network.Salvia.Impl.Context import Network.Salvia.Impl.Handler import Network.Socket import System.IO {- | todo: Start a webserver with a specific server configuration and default handler. The server will go into an infinite loop and will repeatedly accept client connections on the address and port specified in the configuration. For every connection the specified handler will be executed with the client address and socket stored in the handler context. -} {- todo: Start a listening TCP server on the specified address/port combination and handle every connection with a custom handler. Accept connections on the listening socket and pass execution to the application specific connection handler. -} start :: Config -> Handler p () -> p -> IO () start conf handler payload = do tm <- make forM_ (listenOn conf) $ \(SockAddrInet port addr) -> fork tm $ do inet_ntoa addr >>= \a -> putStrLn ("starting listening server on: " ++ a ++ ":" ++ show port) s <- socket AF_INET Stream 0 setSocketOption s ReuseAddr 1 let sAddr = SockAddrInet port addr bindSocket s sAddr listen s (backlog conf) forever $ do (sck, cAddr) <- accept s fork tm $ do hndl <- socketToHandle sck ReadWriteMode _ <- runHandler handler Context { _cServerHost = hostname conf , _cAdminMail = adminMail conf , _cListenOn = listenOn conf , _cPayload = payload , _cRequest = emptyRequest , _cResponse = emptyResponse , _cRawRequest = emptyRequest , _cRawResponse = emptyResponse , _cSocket = sck , _cHandle = hndl , _cClientAddr = cAddr , _cServerAddr = sAddr , _cQueue = [] } return () waitForAll tm