@@ -1,16 +1,13 @@
11{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE NamedFieldPuns #-}
2+{-# LANGUAGE NamedFieldPuns, RecordWildCards #-}
33
44module Network.Wai.Handler.Warp.HTTP2.HPACK where
55
66import Control.Arrow (first)
77import qualified Control.Exception as E
8−import qualified Data.ByteString as B
9−import Data.ByteString.Builder (Builder)
108import qualified Data.ByteString.Char8 as B8
119import Data.CaseInsensitive (foldedCase)
12−import Data.IORef (readIORef, writeIORef)
13−import Network.HPACK
10+import Network.HPACK hiding (Buffer)
1411import qualified Network.HTTP.Types as H
1512import Network.HTTP2
1613import Network.Wai.Handler.Warp.HTTP2.Types
@@ -24,37 +21,30 @@ import Network.Wai.Handler.Warp.Types
2421
2522-- Set-Cookie: contains only one cookie value.
2623-- So, we don't need to split it.
27−hpackEncodeHeader :: Context -> InternalInfo -> S.Settings
24+hpackEncodeHeader :: Context -> Buffer -> BufSize
25+ -> InternalInfo -> S.Settings
2826 -> H.Status -> H.ResponseHeaders
29− -> IO Builder
30−hpackEncodeHeader ctx ii settings s h = do
31− hdr1 <- addServerAndDate h
32− let hdr2 = (":status", status) : map (first foldedCase) hdr1
33− hpackEncodeRawHeaders ctx hdr2
27+ -> IO (HeaderList, Int)
28+hpackEncodeHeader Context{..} buf siz ii settings s hdr0 = do
29+ hdr1 <- addServerAndDate hdr0
30+ let hs = (":status", status) : map (first foldedCase) hdr1
31+ encodeHeaderBuffer buf siz defaultEncodeStrategy True encodeDynamicTable hs
3432 where
3533 status = B8.pack $ show $ H.statusCode s
3634 dc = dateCacher ii
37− rspidxhdr = indexResponseHeader h
35+ rspidxhdr = indexResponseHeader hdr0
3836 defServer = S.settingsServerName settings
3937 addServerAndDate = addDate dc rspidxhdr . addServer defServer rspidxhdr
4038
41−hpackEncodeCIHeaders :: Context -> [H.Header] -> IO Builder
42−hpackEncodeCIHeaders ctx = hpackEncodeRawHeaders ctx . map (first foldedCase)
43−
44−hpackEncodeRawHeaders :: Context -> [(B.ByteString, B.ByteString)] -> IO Builder
45−hpackEncodeRawHeaders Context{encodeDynamicTable} hdr = do
46− ehdrtbl <- readIORef encodeDynamicTable
47− (ehdrtbl', builder) <- encodeHeaderBuilder defaultEncodeStrategy ehdrtbl hdr
48− writeIORef encodeDynamicTable ehdrtbl'
49− return builder
39+hpackEncodeHeaderLoop :: Context -> Buffer -> BufSize -> HeaderList
40+ -> IO (HeaderList, Int)
41+hpackEncodeHeaderLoop Context{..} buf siz hs =
42+ encodeHeaderBuffer buf siz defaultEncodeStrategy False encodeDynamicTable hs
5043
5144----------------------------------------------------------------
5245
5346hpackDecodeHeader :: HeaderBlockFragment -> Context -> IO HeaderList
54−hpackDecodeHeader hdrblk Context{decodeDynamicTable} = do
55− hdrtbl <- readIORef decodeDynamicTable
56− (hdrtbl', hdr) <- decodeHeader hdrtbl hdrblk `E.onException` cleanup
57− writeIORef decodeDynamicTable hdrtbl'
58− return hdr
47+hpackDecodeHeader hdrblk Context{..} =
48+ decodeHeader decodeDynamicTable hdrblk `E.onException` cleanup
5949 where
6050 cleanup = E.throwIO $ ConnectionError CompressionError "cannot decompress the header"