quic-0.2.3: util/ServerX.hs
{-# LANGUAGE OverloadedStrings #-}
module ServerX where
import Control.Concurrent
import qualified Control.Exception as E
import Control.Monad
import qualified Data.ByteString as BS
import Data.ByteString.Builder
import Network.ByteOrder
import H3
import Network.QUIC
import Network.QUIC.Internal
serverHQ :: Connection -> IO ()
serverHQ conn = connDebugLog conn "Connection terminated" `onE` body
where
body = forever $ do
s <- acceptStream conn
consume conn s
let sid = streamId s
when (isClientInitiatedBidirectional sid) $ do
sendStream s html
closeStream s
serverH3 :: Connection -> IO ()
serverH3 conn =
connDebugLog conn "Connection terminated" `onE` do
s3 <- unidirectionalStream conn
s7 <- unidirectionalStream conn
s11 <- unidirectionalStream conn
-- 0: control, 4 settings
sendStream s3 (BS.pack [0, 4, 8, 1, 80, 0, 6, 128, 0, 128, 0])
-- 2: from encoder to decoder
sendStream s7 (BS.pack [2])
-- 3: from decoder to encoder
sendStream s11 (BS.pack [3])
hdrblock <- taglen 1 <$> qpackServer
let bdyblock = taglen 0 html
hdrbdy = [hdrblock, bdyblock]
loop hdrbdy
where
loop hdrbdy = do
s <- acceptStream conn
void . forkIO $ do
consume conn s
let sid = streamId s
when (isClientInitiatedBidirectional sid) $ do
sendStreamMany s hdrbdy
closeStream s
loop hdrbdy
serverPF :: Connection -> IO ()
serverPF conn =
connDebugLog conn "Connection terminated" `onE` do
s <- acceptStream conn
let sid = streamId s
when (isClientInitiatedBidirectional sid) $ do
bs <- recvStream s 8
n <- withReadBuffer bs read64
loop s n
closeStream s
where
bs1024 = BS.replicate 1024 65
loop _ 0 = return ()
loop s n
| n < 1024 = sendStream s $ BS.replicate (fromIntegral n) 65
| otherwise = do
sendStream s bs1024
loop s (n - 1024)
consume :: Connection -> Stream -> IO ()
consume conn s = loop
where
loop = do
bs <- recvStream s 1024
if bs == ""
then connDebugLog conn "FIN received"
else do
connDebugLog conn $ byteString bs
loop
onE :: IO b -> IO a -> IO a
h `onE` b = b `E.onException` h