http3 0.0.23 → 0.0.24
raw patch · 20 files changed
+155/−98 lines, 20 filesdep ~tlsPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: tls
API changes (from Hackage documentation)
- Network.QPACK.Internal: InsertWithoutNameReference :: Token -> FieldValue -> EncoderInstruction
+ Network.QPACK.Internal: InsertWithLiteralName :: Token -> FieldValue -> EncoderInstruction
+ Network.QPACK.Internal: getSendDI :: DynamicTable -> ByteString -> IO ()
- Network.QPACK: newQDecoder :: QDecoderConfig -> IO (QDecoder, EncoderInstructionHandler)
+ Network.QPACK: newQDecoder :: QDecoderConfig -> (EncodedDecoderInstruction -> IO ()) -> IO (QDecoder, EncoderInstructionHandler)
- Network.QPACK: newQDecoderS :: QDecoderConfig -> Bool -> IO (QDecoderS, EncoderInstructionHandlerS)
+ Network.QPACK: newQDecoderS :: QDecoderConfig -> (EncodedDecoderInstruction -> IO ()) -> Bool -> IO (QDecoderS, EncoderInstructionHandlerS)
- Network.QPACK: type QDecoder = EncodedFieldSection -> IO TokenHeaderTable
+ Network.QPACK: type QDecoder = StreamId -> EncodedFieldSection -> IO TokenHeaderTable
- Network.QPACK: type QDecoderS = EncodedFieldSection -> IO [Header]
+ Network.QPACK: type QDecoderS = StreamId -> EncodedFieldSection -> IO [Header]
- Network.QPACK.Internal: SectionAcknowledgement :: Int -> DecoderInstruction
+ Network.QPACK.Internal: SectionAcknowledgement :: StreamId -> DecoderInstruction
- Network.QPACK.Internal: StreamCancellation :: Int -> DecoderInstruction
+ Network.QPACK.Internal: StreamCancellation :: StreamId -> DecoderInstruction
- Network.QPACK.Internal: decodePrefix :: ReadBuffer -> DynamicTable -> IO (InsertionPoint, BasePoint)
+ Network.QPACK.Internal: decodePrefix :: ReadBuffer -> DynamicTable -> IO (InsertionPoint, BasePoint, Bool)
- Network.QPACK.Internal: decodeTokenHeader :: DynamicTable -> ReadBuffer -> IO TokenHeaderTable
+ Network.QPACK.Internal: decodeTokenHeader :: DynamicTable -> ReadBuffer -> IO (TokenHeaderTable, Bool)
- Network.QPACK.Internal: decodeTokenHeaderS :: DynamicTable -> ReadBuffer -> IO [Header]
+ Network.QPACK.Internal: decodeTokenHeaderS :: DynamicTable -> ReadBuffer -> IO ([Header], Bool)
- Network.QPACK.Internal: newDynamicTableForDecoding :: Size -> Size -> IO DynamicTable
+ Network.QPACK.Internal: newDynamicTableForDecoding :: Size -> Size -> (ByteString -> IO ()) -> IO DynamicTable
Files
- ChangeLog.md +5/−0
- Network/HTTP3/Client.hs +3/−5
- Network/HTTP3/Context.hs +2/−1
- Network/HTTP3/Control.hs +3/−1
- Network/HTTP3/Recv.hs +6/−5
- Network/HTTP3/Send.hs +1/−1
- Network/HTTP3/Server.hs +6/−8
- Network/HTTP3/Settings.hs +9/−1
- Network/QPACK.hs +60/−38
- Network/QPACK/HeaderBlock/Decode.hs +8/−6
- Network/QPACK/HeaderBlock/Encode.hs +1/−1
- Network/QPACK/HeaderBlock/Prefix.hs +4/−2
- Network/QPACK/Instruction.hs +11/−10
- Network/QPACK/Table.hs +1/−0
- Network/QPACK/Table/Dynamic.hs +12/−4
- http3.cabal +3/−3
- test/QPACK/InstructionSpec.hs +1/−1
- test/QPACK/QIFSpec.hs +5/−4
- util/Common.hs +1/−1
- util/qif.hs +13/−6
ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for http3 +## 0.0.24++* Supporting SSLKEYLOGFILE in h3-server and h3-client.+* Sending SectionAcknowledgement only when reqInsCnt /= 0.+ ## 0.0.23 * Enclosing IPv6 address in :authority
Network/HTTP3/Client.hs view
@@ -32,7 +32,6 @@ import Imports import Network.HTTP3.Config import Network.HTTP3.Context-import Network.HTTP3.Control import Network.HTTP3.Error import Network.HTTP3.Frame import Network.HTTP3.Recv@@ -48,8 +47,6 @@ -- | Running an HTTP\/3 client. run :: Connection -> ClientConfig -> Config -> Client a -> IO a run conn ClientConfig{..} conf client = withContext conn conf $ \ctx -> do- forkManaged ctx "H3 client: unidirectional setter" $- setupUnidirectional conn conf forkManaged ctx "H3 client: readerClient" $ readerClient ctx client (sendRequest ctx scheme authority) aux where@@ -83,7 +80,8 @@ sendBody ctx strm th outobj QUIC.shutdownStream strm src <- newSource strm- mvt <- recvHeader ctx src+ let sid = QUIC.streamId strm+ mvt <- recvHeader ctx sid src case mvt of Nothing -> do QUIC.resetStream strm H3MessageError@@ -93,7 +91,7 @@ Just vt -> do refI <- newIORef IInit refH <- newIORef Nothing- let readB = recvBody ctx src refI refH+ let readB = recvBody ctx sid src refI refH rsp = Response $ InpObj vt Nothing readB refH processResponse rsp where
Network/HTTP3/Context.hs view
@@ -60,9 +60,10 @@ newContext :: Connection -> Config -> IO Context newContext conn conf = do+ sendDI <- setupUnidirectional conn conf ctl <- controlStream conn <$> newIORef IInit (enc, handleDI) <- newQEncoder defaultQEncoderConfig- (dec, handleEI) <- newQDecoder defaultQDecoderConfig+ (dec, handleEI) <- newQDecoder defaultQDecoderConfig sendDI info <- getConnectionInfo conn let handleDI' recv = handleDI recv `E.catch` abortWith QpackDecoderStreamError handleEI' recv = handleEI recv `E.catch` abortWith QpackEncoderStreamError
Network/HTTP3/Control.hs view
@@ -20,7 +20,8 @@ mkType :: H3StreamType -> ByteString mkType = BS.singleton . fromIntegral . fromH3StreamType -setupUnidirectional :: Connection -> H3.Config -> IO ()+setupUnidirectional+ :: Connection -> H3.Config -> IO (EncodedDecoderInstruction -> IO ()) setupUnidirectional conn conf = do settings <- encodeH3Settings@@ -40,6 +41,7 @@ H3.onControlStreamCreated hooks sC H3.onEncoderStreamCreated hooks sE H3.onDecoderStreamCreated hooks sD+ return $ sendStream sD where stC = mkType H3ControlStreams stE = mkType QPACKEncoderStream
Network/HTTP3/Recv.hs view
@@ -45,8 +45,8 @@ pushbackSource _ "" = return () pushbackSource Source{..} bs = writeIORef sourcePending $ Just bs -recvHeader :: Context -> Source -> IO (Maybe TokenHeaderTable)-recvHeader ctx src = loop IInit+recvHeader :: Context -> StreamId -> Source -> IO (Maybe TokenHeaderTable)+recvHeader ctx sid src = loop IInit where loop st = do bs <- readSource src@@ -56,7 +56,7 @@ IDone typ payload leftover | typ == H3FrameHeaders -> do pushbackSource src leftover- Just <$> qpackDecode ctx payload+ Just <$> qpackDecode ctx sid payload | typ == H3FrameData -> do abort ctx H3FrameUnexpected loop IInit -- dummy@@ -70,11 +70,12 @@ recvBody :: Context+ -> StreamId -> Source -> IORef IFrame -> IORef (Maybe TokenHeaderTable) -> IO (ByteString, Bool)-recvBody ctx src refI refH = do+recvBody ctx sid src refI refH = do st <- readIORef refI loop st where@@ -95,7 +96,7 @@ | typ == H3FrameHeaders -> do writeIORef refI IInit -- pushbackSource src leftover -- fixme- hdr <- qpackDecode ctx payload+ hdr <- qpackDecode ctx sid payload writeIORef refH $ Just hdr return ("", True) | typ == H3FrameData -> do
Network/HTTP3/Send.hs view
@@ -26,7 +26,7 @@ sendHeader ctx strm th hdrs = do -- fixme: fixHeaders (ths, _) <- toTokenHeaderTable hdrs- (hdr, "") <- qpackEncode ctx ths+ (hdr, "") <- qpackEncode ctx ths -- FIXME: send 2nd ret value as EI let frames = [H3Frame H3FrameHeaders hdr] frames' = onHeadersFrameCreated (getHooks ctx) frames bss = encodeH3Frames frames'
Network/HTTP3/Server.hs view
@@ -36,7 +36,6 @@ import Imports import Network.HTTP3.Config import Network.HTTP3.Context-import Network.HTTP3.Control import Network.HTTP3.Error import Network.HTTP3.Frame import Network.HTTP3.Recv@@ -47,8 +46,6 @@ run :: Connection -> Config -> Server -> IO () run conn conf server = withContext conn conf $ \ctx -> do myThreadId >>= \t -> labelThread t "H3 server: run"- forkManaged ctx "H3 server: unidirectional setter" $- setupUnidirectional conn conf readerServer ctx $ \strm -> forkManagedTimeoutFinally ctx@@ -58,8 +55,6 @@ runIO :: Connection -> Config -> (ServerIO Stream -> IO (IO ())) -> IO () runIO conn conf action = withContext conn conf $ \ctx -> do- forkManaged ctx "H3 server: unidirectional setter" $- setupUnidirectional conn conf info <- getConnectionInfo conn reqq <- newTQueueIO let sio =@@ -97,7 +92,7 @@ -> IO () processRequest ctx server strm th = E.handle reset $ do src <- newSource strm- mvt <- recvHeader ctx src+ mvt <- recvHeader ctx sid src case mvt of Nothing -> QUIC.resetStream strm H3MessageError Just ht -> do@@ -105,6 +100,7 @@ let aux = Aux th (getMySockAddr ctx) (getPeerSockAddr ctx) server req aux $ sendResponse ctx strm th where+ sid = QUIC.streamId strm reset se | isAsyncException se = E.throwIO se | Just (_ :: DecodeError) <- E.fromException se =@@ -114,13 +110,14 @@ processRequestIO :: Context -> ((Stream, Request) -> IO ()) -> Stream -> IO () processRequestIO ctx put strm = E.handle reset $ do src <- newSource strm- mvt <- recvHeader ctx src+ mvt <- recvHeader ctx sid src case mvt of Nothing -> QUIC.resetStream strm H3MessageError Just ht -> do req <- mkRequest ctx strm src ht put (strm, req) where+ sid = QUIC.streamId strm reset se | isAsyncException se = E.throwIO se | Just (_ :: DecodeError) <- E.fromException se =@@ -145,7 +142,8 @@ -- fixme: Content-Length refI <- newIORef IInit refH <- newIORef Nothing- let readB = recvBody ctx src refI refH+ let sid = QUIC.streamId strm+ let readB = recvBody ctx sid src refI refH req = Request $ InpObj ht Nothing readB refH return req
Network/HTTP3/Settings.hs view
@@ -7,7 +7,7 @@ type H3Settings = [(H3SettingsKey, Int)] -newtype H3SettingsKey = H3SettingsKey Int deriving (Eq, Show)+newtype H3SettingsKey = H3SettingsKey Int deriving (Eq) {- FOURMOLU_DISABLE -} pattern SettingsQpackMaxTableCapacity :: H3SettingsKey@@ -18,6 +18,14 @@ pattern SettingsQpackBlockedStreams :: H3SettingsKey pattern SettingsQpackBlockedStreams = H3SettingsKey 0x7+{- FOURMOLU_ENABLE -}++{- FOURMOLU_DISABLE -}+instance Show H3SettingsKey where+ show SettingsQpackMaxTableCapacity = "SettingsQpackMaxTableCapacity"+ show SettingsMaxFieldSectionSize = "SettingsMaxFieldSectionSize"+ show SettingsQpackBlockedStreams = "SettingsQpackBlockedStreams"+ show (H3SettingsKey n) = "H3SettingsKey " ++ show n {- FOURMOLU_ENABLE -} encodeH3Settings :: H3Settings -> IO ByteString
Network/QPACK.hs view
@@ -58,7 +58,7 @@ toTokenHeaderTable, ) import Network.HTTP.Types-import Network.QUIC.Internal (stdoutLogger)+import Network.QUIC.Internal (StreamId, stdoutLogger) import Imports import Network.QPACK.Error@@ -74,10 +74,10 @@ TokenHeaderList -> IO (EncodedFieldSection, EncodedEncoderInstruction) -- | QPACK decoder.-type QDecoder = EncodedFieldSection -> IO TokenHeaderTable+type QDecoder = StreamId -> EncodedFieldSection -> IO TokenHeaderTable -- | QPACK simple decoder.-type QDecoderS = EncodedFieldSection -> IO [Header]+type QDecoderS = StreamId -> EncodedFieldSection -> IO [Header] -- | Encoder instruction handler. type EncoderInstructionHandler = (Int -> IO EncodedEncoderInstruction) -> IO ()@@ -174,8 +174,7 @@ let hb = prefix `B.append` hb0 return (hb, ins) -decoderInstructionHandler- :: DynamicTable -> (Int -> IO EncodedDecoderInstruction) -> IO ()+decoderInstructionHandler :: DynamicTable -> DecoderInstructionHandler decoderInstructionHandler dyntbl recv = loop where loop = do@@ -191,7 +190,7 @@ handle (StreamCancellation _n) = return () handle (InsertCountIncrement n) | n == 0 = E.throwIO DecoderInstructionError- | otherwise = return ()+ | otherwise = return () -- FIXME: Known Received Count ---------------------------------------------------------------- @@ -214,31 +213,47 @@ } -- | Creating a new QPACK decoder.-newQDecoder :: QDecoderConfig -> IO (QDecoder, EncoderInstructionHandler)-newQDecoder QDecoderConfig{..} = do- dyntbl <- newDynamicTableForDecoding dcDynamicTableSize dcHuffmanBufferSize+newQDecoder+ :: QDecoderConfig+ -> (EncodedDecoderInstruction -> IO ())+ -> IO (QDecoder, EncoderInstructionHandler)+newQDecoder QDecoderConfig{..} sendDI = do+ dyntbl <-+ newDynamicTableForDecoding dcDynamicTableSize dcHuffmanBufferSize sendDI let dec = qpackDecoder dyntbl handler = encoderInstructionHandler dyntbl return (dec, handler) -- | Creating a new simple QPACK decoder. newQDecoderS- :: QDecoderConfig -> Bool -> IO (QDecoderS, EncoderInstructionHandlerS)-newQDecoderS QDecoderConfig{..} debug = do- dyntbl <- newDynamicTableForDecoding dcDynamicTableSize dcHuffmanBufferSize+ :: QDecoderConfig+ -> (EncodedDecoderInstruction -> IO ())+ -> Bool+ -> IO (QDecoderS, EncoderInstructionHandlerS)+newQDecoderS QDecoderConfig{..} sendDI debug = do+ dyntbl <-+ newDynamicTableForDecoding dcDynamicTableSize dcHuffmanBufferSize sendDI when debug $ setDebugQPACK dyntbl let dec = qpackDecoderS dyntbl handler = encoderInstructionHandlerS dyntbl return (dec, handler) -qpackDecoder :: DynamicTable -> EncodedFieldSection -> IO TokenHeaderTable-qpackDecoder dyntbl bs = withReadBuffer bs $ \rbuf -> decodeTokenHeader dyntbl rbuf+qpackDecoder+ :: DynamicTable -> StreamId -> EncodedFieldSection -> IO TokenHeaderTable+qpackDecoder dyntbl sid bs = do+ (tbl, needAck) <- withReadBuffer bs $ \rbuf -> decodeTokenHeader dyntbl rbuf+ when needAck $+ encodeDecoderInstructions [SectionAcknowledgement sid] >>= getSendDI dyntbl+ return tbl -qpackDecoderS :: DynamicTable -> EncodedFieldSection -> IO [Header]-qpackDecoderS dyntbl bs = withReadBuffer bs $ \rbuf -> decodeTokenHeaderS dyntbl rbuf+qpackDecoderS :: DynamicTable -> StreamId -> EncodedFieldSection -> IO [Header]+qpackDecoderS dyntbl sid bs = do+ (hs, needAck) <- withReadBuffer bs $ \rbuf -> decodeTokenHeaderS dyntbl rbuf+ when needAck $+ encodeDecoderInstructions [SectionAcknowledgement sid] >>= getSendDI dyntbl+ return hs -encoderInstructionHandler- :: DynamicTable -> (Int -> IO EncodedEncoderInstruction) -> IO ()+encoderInstructionHandler :: DynamicTable -> EncoderInstructionHandler encoderInstructionHandler dyntbl recv = loop where loop = do@@ -247,8 +262,9 @@ encoderInstructionHandlerS dyntbl bs loop -encoderInstructionHandlerS :: DynamicTable -> EncodedEncoderInstruction -> IO ()-encoderInstructionHandlerS dyntbl bs = when (bs /= "") $ do+encoderInstructionHandlerS :: DynamicTable -> EncoderInstructionHandlerS+encoderInstructionHandlerS _dyntbl "" = return ()+encoderInstructionHandlerS dyntbl bs = do (ins, leftover) <- decodeEncoderInstructions hufdec bs -- fixme: saving leftover when (leftover /= "") $ stdoutLogger "encoderInstructionHandler: leftover" @@ -258,21 +274,27 @@ hufdec = getHuffmanDecoder dyntbl handle (SetDynamicTableCapacity n) | n > 4096 = E.throwIO EncoderInstructionError- | otherwise = return ()- handle (InsertWithNameReference ii val) = atomically $ do- idx <- case ii of- Left ai -> return $ SIndex ai- Right ri -> do- ip <- getInsertionPointSTM dyntbl- return $ DIndex $ fromInsRelativeIndex ri ip- ent0 <- toIndexedEntry dyntbl idx- let ent = toEntryToken (entryToken ent0) val- insertEntryToDecoder ent dyntbl- handle (InsertWithoutNameReference t val) = atomically $ do- let ent = toEntryToken t val- insertEntryToDecoder ent dyntbl- handle (Duplicate ri) = atomically $ do- ip <- getInsertionPointSTM dyntbl- let idx = DIndex $ fromInsRelativeIndex ri ip- ent <- toIndexedEntry dyntbl idx- insertEntryToDecoder ent dyntbl+ | otherwise = return () -- FIXME: set cap+ handle (InsertWithNameReference ii val) = do+ atomically $ do+ idx <- case ii of+ Left ai -> return $ SIndex ai+ Right ri -> do+ ip <- getInsertionPointSTM dyntbl+ return $ DIndex $ fromInsRelativeIndex ri ip+ ent0 <- toIndexedEntry dyntbl idx+ let ent = toEntryToken (entryToken ent0) val+ insertEntryToDecoder ent dyntbl+ encodeDecoderInstructions [InsertCountIncrement 1] >>= getSendDI dyntbl+ handle (InsertWithLiteralName t val) = do+ atomically $ do+ let ent = toEntryToken t val+ insertEntryToDecoder ent dyntbl+ encodeDecoderInstructions [InsertCountIncrement 1] >>= getSendDI dyntbl+ handle (Duplicate ri) = do+ atomically $ do+ ip <- getInsertionPointSTM dyntbl+ let idx = DIndex $ fromInsRelativeIndex ri ip+ ent <- toIndexedEntry dyntbl idx+ insertEntryToDecoder ent dyntbl+ encodeDecoderInstructions [InsertCountIncrement 1] >>= getSendDI dyntbl
Network/QPACK/HeaderBlock/Decode.hs view
@@ -24,21 +24,23 @@ decodeTokenHeader :: DynamicTable -> ReadBuffer- -> IO TokenHeaderTable+ -> IO (TokenHeaderTable, Bool) decodeTokenHeader dyntbl rbuf = do- (reqip, bp) <- decodePrefix rbuf dyntbl+ (reqip, bp, needAck) <- decodePrefix rbuf dyntbl checkInsertionPoint dyntbl reqip- decodeSophisticated (toTokenHeader dyntbl bp) rbuf+ tbl <- decodeSophisticated (toTokenHeader dyntbl bp) rbuf+ return (tbl, needAck) decodeTokenHeaderS :: DynamicTable -> ReadBuffer- -> IO [Header]+ -> IO ([Header], Bool) decodeTokenHeaderS dyntbl rbuf = do- (reqip, bp) <- decodePrefix rbuf dyntbl+ (reqip, bp, needAck) <- decodePrefix rbuf dyntbl debug <- getDebugQPACK dyntbl unless debug $ checkInsertionPoint dyntbl reqip- decodeSimple (toTokenHeader dyntbl bp) rbuf+ hs <- decodeSimple (toTokenHeader dyntbl bp) rbuf+ return (hs, needAck) toTokenHeader :: DynamicTable -> BasePoint -> Word8 -> ReadBuffer -> IO TokenHeader
Network/QPACK/HeaderBlock/Encode.hs view
@@ -147,7 +147,7 @@ encodeLiteralFieldLineWithNameReference wbuf1 dyntbl hi val huff N | shouldBeIndexed t -> do- let ins = InsertWithoutNameReference t val+ let ins = InsertWithLiteralName t val encodeEI wbuf2 True ins dai <- insertEntryToEncoder (toEntryToken t val) dyntbl encodeIndexedFieldLineWithPostBaseIndex wbuf1 dyntbl dai
Network/QPACK/HeaderBlock/Prefix.hs view
@@ -95,7 +95,8 @@ encodeI wbuf set 7 base -- | Decoding the prefix part of header block.-decodePrefix :: ReadBuffer -> DynamicTable -> IO (InsertionPoint, BasePoint)+decodePrefix+ :: ReadBuffer -> DynamicTable -> IO (InsertionPoint, BasePoint, Bool) decodePrefix rbuf dyntbl = do maxEntries <- getMaxNumOfEntries dyntbl totalNumberOfInserts <- getInsertionPoint dyntbl@@ -110,4 +111,5 @@ qpackDebug dyntbl $ putStrLn $ "Required" ++ show reqInsCnt ++ ", " ++ show baseIndex- return (reqInsCnt, baseIndex)+ let needAck = reqInsCnt /= 0+ return (reqInsCnt, baseIndex, needAck)
Network/QPACK/Instruction.hs view
@@ -33,6 +33,7 @@ encodeS, entryHeaderName, )+import Network.QUIC (StreamId) import Imports import Network.QPACK.Table.Static@@ -45,7 +46,7 @@ data EncoderInstruction = SetDynamicTableCapacity Int | InsertWithNameReference InsIndex FieldValue- | InsertWithoutNameReference Token FieldValue+ | InsertWithLiteralName Token FieldValue | Duplicate InsRelativeIndex deriving (Eq) @@ -59,8 +60,8 @@ ++ "\"" show (InsertWithNameReference (Right (InsRelativeIndex idx)) v) = "InsertWithNameReference (DynRel " ++ show idx ++ ") \"" ++ BS8.unpack v ++ "\""- show (InsertWithoutNameReference t v) =- "InsertWithoutNameReference \""+ show (InsertWithLiteralName t v) =+ "InsertWithLiteralName \"" ++ BS8.unpack (foldedCase (tokenKey t)) ++ "\" \"" ++ BS8.unpack v@@ -81,7 +82,7 @@ Right (InsRelativeIndex i) -> (set1, i) encodeI wbuf set 6 idx encodeS wbuf huff id set1 7 v-encodeEI wbuf huff (InsertWithoutNameReference k v) = do+encodeEI wbuf huff (InsertWithLiteralName k v) = do encodeS wbuf huff set01 set001 5 $ foldedCase $ tokenKey k encodeS wbuf huff id set1 7 v encodeEI wbuf _ (Duplicate (InsRelativeIndex idx)) = encodeI wbuf set000 5 idx@@ -124,7 +125,7 @@ then decodeInsertWithNameReference rbuf w8 hufdec else if w8 `testBit` 6- then decodeInsertWithoutNameReference rbuf hufdec+ then decodeInsertWithLiteralName rbuf hufdec else if w8 `testBit` 5 then decodeSetDynamicTableCapacity rbuf w8@@ -140,13 +141,13 @@ v <- decodeS (.&. 0b01111111) (`testBit` 7) 7 hufdec rbuf return $ InsertWithNameReference hidx v -decodeInsertWithoutNameReference+decodeInsertWithLiteralName :: ReadBuffer -> HuffmanDecoder -> IO EncoderInstruction-decodeInsertWithoutNameReference rbuf hufdec = do+decodeInsertWithLiteralName rbuf hufdec = do ff rbuf (-1) k <- decodeS (.&. 0b00011111) (`testBit` 5) 5 hufdec rbuf v <- decodeS (.&. 0b01111111) (`testBit` 7) 7 hufdec rbuf- return $ InsertWithoutNameReference (toToken k) v+ return $ InsertWithLiteralName (toToken k) v decodeSetDynamicTableCapacity :: ReadBuffer -> Word8 -> IO EncoderInstruction decodeSetDynamicTableCapacity rbuf w8 =@@ -159,8 +160,8 @@ ---------------------------------------------------------------- data DecoderInstruction- = SectionAcknowledgement Int- | StreamCancellation Int+ = SectionAcknowledgement StreamId+ | StreamCancellation StreamId | InsertCountIncrement Int deriving (Eq, Show)
Network/QPACK/Table.hs view
@@ -27,6 +27,7 @@ -- * Misc getHuffmanDecoder,+ getSendDI, setDebugQPACK, getDebugQPACK, qpackDebug,
Network/QPACK/Table/Dynamic.hs view
@@ -28,7 +28,7 @@ = EncodeInfo RevIndex -- Reverse index (IORef InsertionPoint)- | DecodeInfo HuffmanDecoder+ | DecodeInfo HuffmanDecoder (ByteString -> IO ()) -- | Dynamic table for QPACK. data DynamicTable = DynamicTable@@ -42,6 +42,8 @@ , debugQPACK :: IORef Bool } +-- knownReceivedCount :: TVar Int+ type Table = TArray Index Entry ----------------------------------------------------------------@@ -84,12 +86,13 @@ -- ^ The dynamic table size -> Size -- ^ The size of temporary buffer for Huffman decoding+ -> (ByteString -> IO ()) -> IO DynamicTable-newDynamicTableForDecoding maxsiz huftmpsiz = do+newDynamicTableForDecoding maxsiz huftmpsiz sendDI = do gcbuf <- mallocPlainForeignPtrBytes huftmpsiz tvar <- newTVarIO $ Just (gcbuf, huftmpsiz) let decoder = decodeHLock tvar- info = DecodeInfo decoder+ info = DecodeInfo decoder sendDI newDynamicTable maxsiz info decodeHLock@@ -153,7 +156,12 @@ getHuffmanDecoder :: DynamicTable -> HuffmanDecoder getHuffmanDecoder DynamicTable{..} = huf where- DecodeInfo huf = codeInfo+ DecodeInfo huf _ = codeInfo++getSendDI :: DynamicTable -> (ByteString -> IO ())+getSendDI DynamicTable{..} = sendDI+ where+ DecodeInfo _ sendDI = codeInfo ----------------------------------------------------------------
http3.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: http3-version: 0.0.23+version: 0.0.24 license: BSD-3-Clause license-file: LICENSE maintainer: Kazu Yamamoto <kazu@iij.ad.jp>@@ -114,7 +114,7 @@ http2, http3, quic,- tls < 2.2,+ tls >=2.1.10 && <2.2, tls-session-manager if flag(devel)@@ -141,7 +141,7 @@ http-types, http3, quic,- tls,+ tls >=2.1.10 && <2.2, unix-time if flag(devel)
test/QPACK/InstructionSpec.hs view
@@ -14,7 +14,7 @@ let eis0 = [ SetDynamicTableCapacity 4096 , InsertWithNameReference (Left 92) "Warp/4.3.2.1"- , InsertWithoutNameReference tokenContentType "text/plain"+ , InsertWithLiteralName tokenContentType "text/plain" , Duplicate 40 ] bs1 <- encodeEncoderInstructions eis0 True
test/QPACK/QIFSpec.hs view
@@ -14,6 +14,7 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 import Data.Conduit.Attoparsec+import Network.QUIC (StreamId) import System.IO import Test.Hspec @@ -36,7 +37,7 @@ test :: FilePath -> FilePath -> IO () test efile qfile = do- (dec, insthdr) <- newQDecoderS defaultQDecoderConfig False+ (dec, insthdr) <- newQDecoderS defaultQDecoderConfig (\_ -> return ()) False q <- newTQueueIO let recv = atomically $ readTQueue q send x = atomically $ writeTQueue q x@@ -60,7 +61,7 @@ | otherwise = send blk decode- :: (ByteString -> IO [Header])+ :: (StreamId -> ByteString -> IO [Header]) -> Handle -> IO Block -> MVar ()@@ -73,8 +74,8 @@ then putMVar mvar () else do- Block _ bs <- recv- hdr <- dec bs+ Block n bs <- recv+ hdr <- dec n bs hdr `shouldBe` hdr' loop
util/Common.hs view
@@ -41,7 +41,7 @@ (s', r) -> s' : split c (drop 1 r) getLogger :: Maybe FilePath -> (String -> IO ())-getLogger Nothing = \_ -> return ()+getLogger Nothing = defaultKeyLogger getLogger (Just file) = \msg -> appendFile file (msg ++ "\n") makeProtos :: Version -> (ByteString, ByteString)
util/qif.hs view
@@ -14,6 +14,7 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 import Data.Conduit.Attoparsec+import Network.QUIC (StreamId) import System.Environment import System.IO @@ -36,7 +37,10 @@ dump :: Int -> FilePath -> IO () dump size efile = do (dec, insthdr) <-- newQDecoderS defaultQDecoderConfig{dcDynamicTableSize = size} True+ newQDecoderS+ defaultQDecoderConfig{dcDynamicTableSize = size}+ (\_ -> return ())+ True runConduitRes ( sourceFile efile .| conduitParser block@@ -44,17 +48,17 @@ ) dumpSwitch- :: (ByteString -> IO [Header])+ :: (StreamId -> ByteString -> IO [Header]) -> EncoderInstructionHandlerS -> (a, Block) -> IO () dumpSwitch dec insthdr (_, Block n bs) | n == 0 = do- putStrLn "---- Stream 0"+ putStrLn "---- Encoder Stream" insthdr bs | otherwise = do putStrLn $ "---- Stream " ++ show n- _ <- dec bs+ _ <- dec n bs return () ----------------------------------------------------------------@@ -62,7 +66,10 @@ test :: Int -> FilePath -> FilePath -> IO () test size efile qfile = do (dec, insthdr') <-- newQDecoderS defaultQDecoderConfig{dcDynamicTableSize = size} False+ newQDecoderS+ defaultQDecoderConfig{dcDynamicTableSize = size}+ (\_ -> return ())+ False q <- newTQueueIO let recv = atomically $ readTQueue q send x = atomically $ writeTQueue q x@@ -100,7 +107,7 @@ then putMVar mvar () else do Block n bs <- recv- hdr <- dec bs+ hdr <- dec n bs if hdr == hdr' then loop else do