{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Network.HTTP2.Server.Run where
import UnliftIO.Async (race_)
import qualified UnliftIO.Exception as E
import Imports
import Network.HTTP2.Arch
import Network.HTTP2.Frame
import Network.HTTP2.Server.Types
import Network.HTTP2.Server.Worker
run :: Config -> Server -> IO ()
run :: Config -> Server -> IO ()
run conf :: Config
conf@Config{BufferSize
Buffer
Manager
BufferSize -> IO ByteString
PositionReadMaker
ByteString -> IO ()
confTimeoutManager :: Config -> Manager
confPositionReadMaker :: Config -> PositionReadMaker
confReadN :: Config -> BufferSize -> IO ByteString
confSendAll :: Config -> ByteString -> IO ()
confBufferSize :: Config -> BufferSize
confWriteBuffer :: Config -> Buffer
confTimeoutManager :: Manager
confPositionReadMaker :: PositionReadMaker
confReadN :: BufferSize -> IO ByteString
confSendAll :: ByteString -> IO ()
confBufferSize :: BufferSize
confWriteBuffer :: Buffer
..} Server
server = do
Bool
ok <- IO Bool
checkPreface
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
ok forall a b. (a -> b) -> a -> b
$ do
RoleInfo
serverInfo <- IO RoleInfo
newServerInfo
Context
ctx <- RoleInfo -> IO Context
newContext RoleInfo
serverInfo
Manager
mgr <- Manager -> IO Manager
start Manager
confTimeoutManager
let wc :: WorkerConf Stream
wc = Context -> WorkerConf Stream
fromContext Context
ctx
Manager -> IO () -> IO ()
setAction Manager
mgr forall a b. (a -> b) -> a -> b
$ forall a. WorkerConf a -> Manager -> Server -> IO ()
worker WorkerConf Stream
wc Manager
mgr Server
server
forall (m :: * -> *) a. Applicative m => BufferSize -> m a -> m ()
replicateM_ BufferSize
3 forall a b. (a -> b) -> a -> b
$ Manager -> IO ()
spawnAction Manager
mgr
let runReceiver :: IO ()
runReceiver = Context -> (BufferSize -> IO ByteString) -> IO ()
frameReceiver Context
ctx BufferSize -> IO ByteString
confReadN
runSender :: IO ()
runSender = Context -> Config -> Manager -> IO ()
frameSender Context
ctx Config
conf Manager
mgr
forall (m :: * -> *) a b. MonadUnliftIO m => m a -> m b -> m ()
race_ IO ()
runReceiver IO ()
runSender forall (m :: * -> *) a b. MonadUnliftIO m => m a -> m b -> m a
`E.finally` Manager -> IO ()
stop Manager
mgr
where
checkPreface :: IO Bool
checkPreface = do
ByteString
preface <- BufferSize -> IO ByteString
confReadN BufferSize
connectionPrefaceLength
if ByteString
connectionPreface forall a. Eq a => a -> a -> Bool
/= ByteString
preface then do
Config -> ErrorCode -> ByteString -> IO ()
goaway Config
conf ErrorCode
ProtocolError ByteString
"Preface mismatch"
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
goaway :: Config -> ErrorCode -> ByteString -> IO ()
goaway :: Config -> ErrorCode -> ByteString -> IO ()
goaway Config{BufferSize
Buffer
Manager
BufferSize -> IO ByteString
PositionReadMaker
ByteString -> IO ()
confTimeoutManager :: Manager
confPositionReadMaker :: PositionReadMaker
confReadN :: BufferSize -> IO ByteString
confSendAll :: ByteString -> IO ()
confBufferSize :: BufferSize
confWriteBuffer :: Buffer
confTimeoutManager :: Config -> Manager
confPositionReadMaker :: Config -> PositionReadMaker
confReadN :: Config -> BufferSize -> IO ByteString
confSendAll :: Config -> ByteString -> IO ()
confBufferSize :: Config -> BufferSize
confWriteBuffer :: Config -> Buffer
..} ErrorCode
etype ByteString
debugmsg = ByteString -> IO ()
confSendAll ByteString
bytestream
where
bytestream :: ByteString
bytestream = BufferSize -> ErrorCode -> ByteString -> ByteString
goawayFrame BufferSize
0 ErrorCode
etype ByteString
debugmsg