summaryrefslogtreecommitdiff
path: root/mini-http/Network/HTTP/Server/Mini.hs
diff options
context:
space:
mode:
Diffstat (limited to 'mini-http/Network/HTTP/Server/Mini.hs')
-rw-r--r--mini-http/Network/HTTP/Server/Mini.hs40
1 files changed, 27 insertions, 13 deletions
diff --git a/mini-http/Network/HTTP/Server/Mini.hs b/mini-http/Network/HTTP/Server/Mini.hs
index 5af52da..3c5c3f6 100644
--- a/mini-http/Network/HTTP/Server/Mini.hs
+++ b/mini-http/Network/HTTP/Server/Mini.hs
@@ -1,5 +1,6 @@
+{-# LANGUAGE TypeApplications #-}
module Network.HTTP.Server.Mini (
- module Network.HTTP.Server.Mini,
+ run,
module Network.HTTP.Server.Mini.Types,
) where
@@ -12,6 +13,7 @@ import Network.Socket
import Network.Socket.ByteString
import Network.HTTP.Server.Mini.Parser
+import Network.HTTP.Server.Mini.Printer
import Network.HTTP.Server.Mini.Types
@@ -20,14 +22,24 @@ run :: Settings -> (Request -> IO Response) -> IO ()
run settings handler = do
let hints = defaultHints { addrFlags = [AI_NUMERICHOST, AI_NUMERICSERV, AI_PASSIVE]
, addrSocketType = Stream }
- addr <- NE.head <$> getAddrInfo (Just hints) Nothing (Just (show (setPort settings)))
+ addrs <- getAddrInfo @NE.NonEmpty (Just hints) Nothing (Just (show (setPort settings)))
- bracket (openSocket addr) close $ \sock -> do
- setSocketOption sock ReusePort 1
- bind sock (addrAddress addr)
- listen sock 64
- semaphore <- newTVarIO (setMaxParallelRequests settings)
- acceptLoop sock semaphore
+ semaphore <- newTVarIO (setMaxParallelRequests settings)
+ finishVar <- newEmptyMVar
+
+ threads <- forM addrs $ \addr ->
+ forkIO $
+ bracket
+ (openSocket addr)
+ (\sock -> close sock `finally` putMVar finishVar ())
+ (\sock -> do
+ setSocketOption sock ReusePort 1
+ bind sock (addrAddress addr)
+ listen sock (setListenQueue settings)
+ acceptLoop sock semaphore)
+
+ takeMVar finishVar
+ forM_ threads killThread
where
-- Put the forever _outside_ the mask_ to unmask briefly between iterations
-- (when it's safe because we have nothing ongoing).
@@ -41,12 +53,11 @@ run settings handler = do
writeTVar semaphore $! n - 1
let increment = atomically (modifyTVar' semaphore (+1))
- (conn, peer) <- accept sock `onException` increment
+ (conn, _peer) <- accept sock `onException` increment
let cleanup = close conn `finally` increment
onException
(do allowInterrupt -- we're masked but we just blocked (in `accept` in FFI), so let exceptions through
- print peer
-- Now either the forkIO succeeds (and the responsibility for
-- closing and incrementing is passed to the thread) or it fails
-- (and we retain both responsibilities).
@@ -57,6 +68,9 @@ run settings handler = do
-- | Will not close the connection, instead will just return, expecting the
-- caller to close the connection then.
handleConnection :: Settings -> Socket -> (Request -> IO Response) -> IO ()
-handleConnection settings conn handler = do
- req <- readRequest (setMaxRequestSize settings) (recv conn)
- print req
+handleConnection settings conn handler =
+ readRequest (setMaxRequestSize settings) (recv conn) >>= \case
+ Nothing -> return ()
+ Just req -> do
+ resp <- handler req
+ sendResponse conn resp