diff options
| author | Andrew Guschin <guschin.drew@gmail.com> | 2023-03-05 13:45:37 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin.drew@gmail.com> | 2023-03-05 13:47:41 +0400 |
| commit | a0e8e5a91d15ed8c79f4a1b5914d3a6242c0cbd3 (patch) | |
| tree | 76f76788523a16c0db8cb8f3a90b23912acd37d4 /app/Main.hs | |
| parent | dd73de2e563c332c5a90bb21c5c7e6cbebc0ab86 (diff) | |
Migrated project to cabal
Diffstat (limited to 'app/Main.hs')
| -rw-r--r-- | app/Main.hs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/app/Main.hs b/app/Main.hs new file mode 100644 index 0000000..433ad8d --- /dev/null +++ b/app/Main.hs @@ -0,0 +1,58 @@ +module Main (main) where + +import Control.Concurrent (forkFinally) +import qualified Control.Exception as E +import Control.Monad (unless, forever, void) + +import qualified Data.ByteString as S +import qualified Data.Text as T +import Data.Text.Encoding (decodeUtf8, encodeUtf8) + +import Network.Socket +import Network.Socket.ByteString (recv, sendAll) + +import Web.Utils +import Web.Response +import Web.Router +import Routes + +import Settings (host, port) + +main :: IO () +main = do + let hostStr = case host of + Just smt -> smt + Nothing -> "0.0.0.0" + + putStrLn $ "Server launched on " ++ hostStr ++ ":" ++ port + runTCPServer host port talk + where + talk s = do + msg <- recv s 1024 + putStrLn "Got request" + unless (S.null msg) $ do + let (request, _, _) = parseHttp $ decodeUtf8 msg + response <- resolve routesTable $ request + sendAll s $ encodeUtf8 (formResponse response) + +runTCPServer :: Maybe HostName -> ServiceName -> (Socket -> IO a) -> IO a +runTCPServer mhost port server = withSocketsDo $ do + addr <- resolve + E.bracket (open addr) close loop + where + resolve = do + let hints = defaultHints { + addrFlags = [AI_PASSIVE] + , addrSocketType = Stream + } + head <$> getAddrInfo (Just hints) mhost (Just port) + open addr = do + sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) + setSocketOption sock ReuseAddr 1 + withFdSocket sock $ setCloseOnExecIfNeeded + bind sock $ addrAddress addr + listen sock 1024 + return sock + loop sock = forever $ do + (conn, _peer) <- accept sock + void $ forkFinally (server conn) (const $ gracefulClose conn 5000) |