packages feed

http2-client 0.2.0.2 → 0.3.0.0

raw patch · 3 files changed

+46/−28 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Network.HTTP2.Client: type PushPromiseHandler = StreamId -> Http2Stream -> IncomingFlowControl -> OutgoingFlowControl -> IO ()
+ Network.HTTP2.Client: type PushPromiseHandler = StreamId -> Http2Stream -> HeaderList -> IncomingFlowControl -> OutgoingFlowControl -> IO ()

Files

app/Main.hs view
@@ -136,8 +136,8 @@                           , (":authority", ByteString.pack _host)                           ] <> _extraHeaders -    let ppHandler _ stream streamFlowControl _ = void $ forkIO $ do-            timePrint ("push stream started" :: String)+    let ppHandler _ stream ppHdrs streamFlowControl _ = void $ forkIO $ do+            timePrint ("push stream started" :: String, ppHdrs)             waitStream stream streamFlowControl >>= timePrint . fromStreamResult             timePrint ("push stream ended" :: String) 
http2-client.cabal view
@@ -1,5 +1,5 @@ name:                http2-client-version:             0.2.0.2+version:             0.3.0.0 synopsis:            A native HTTP2 client library. description:         Please read the README.md at the homepage. homepage:            https://github.com/lucasdicioccio/http2-client
src/Network/HTTP2/Client.hs view
@@ -227,7 +227,7 @@ -- client-initiated stream. Longer term we may move passing this handler to the -- '_startStream' instead of 'newHttp2Client' (as it is for now). type PushPromiseHandler =-    StreamId -> Http2Stream -> IncomingFlowControl -> OutgoingFlowControl -> IO ()+    StreamId -> Http2Stream -> HeaderList -> IncomingFlowControl -> OutgoingFlowControl -> IO ()  -- | Helper to carry around the HPACK encoder for outgoing header blocks.. data HpackEncoderContext = HpackEncoderContext {@@ -411,9 +411,9 @@   :: Exception e   => Http2FrameConnection   -> IORef ConnectionSettings-  -> Chan (FrameHeader, Either e FramePayload)-  -> Chan (FrameHeader, StreamId, Either ErrorCode HeaderList)-  -> Chan (StreamId, Chan (FrameHeader, Either e FramePayload), StreamId)+  -> FramesChan e+  -> HeadersChan+  -> PushPromisesChan e   -> HpackEncoderContext   -> StreamId   -> (Http2Stream -> StreamDefinition a)@@ -450,12 +450,12 @@     let _rst            = sendResetFrame frameStream     let _prio           = sendPriorityFrame frameStream     let _waitPushPromise ppHandler = do-            (_,ppFrames,ppSid) <- waitPushPromiseWithParentStreamId sid pushPromises-            let mkStreamActions stream = StreamDefinition (return CST) (ppHandler sid stream)+            (_,ppFrames,ppHeaders,ppSid,ppReadHeaders) <- waitPushPromiseWithParentStreamId sid pushPromises+            let mkStreamActions stream = StreamDefinition (return CST) (ppHandler sid stream ppReadHeaders)             ppCont <- initializeStream conn                                        settings                                        ppFrames-                                       serverHeaders+                                       ppHeaders                                        serverPushPromises                                        hpackEncoder                                        ppSid@@ -534,11 +534,20 @@     _ <- _consumeCredit flowControl (HTTP2.payloadLength fh)     _addCredit flowControl (HTTP2.payloadLength fh) +data HPACKLoopDecision =+    ForwardHeader !StreamId+  | OpenPushPromise !StreamId !StreamId++type FramesChan e = Chan (FrameHeader, Either e FramePayload)+type HeadersChan = Chan (FrameHeader, StreamId, Either ErrorCode HeaderList)+type PushPromisesChanContent e = (StreamId, FramesChan e, HeadersChan, StreamId, HeaderList)+type PushPromisesChan e = Chan (PushPromisesChanContent e)+ incomingHPACKFramesLoop   :: Exception e-  => Chan (FrameHeader, Either e FramePayload)-  -> Chan (FrameHeader, StreamId, Either ErrorCode HeaderList)-  -> Chan (StreamId, Chan (FrameHeader, Either e FramePayload), StreamId)+  => FramesChan e+  -> HeadersChan+  -> PushPromisesChan e   -> DynamicTable   -> IO () incomingHPACKFramesLoop frames hdrs pushPromises hpackDecoder = forever $ do@@ -547,18 +556,14 @@                                     , FrameHeaders                                     ]                                     frames-    (sId, pattern) <- case fp of-            PushPromiseFrame sid hbf -> do-                -- Important: We duplicate the channel here or we risk losing-                -- DATA frames sent over the stream.-                ppChan <- dupChan frames-                let parentSid = HTTP2.streamId fh-                writeChan pushPromises (parentSid, ppChan, sid)-                return (sid, Right hbf)+    let sid = HTTP2.streamId fh+    (decision, pattern) <- case fp of+            PushPromiseFrame ppSid hbf -> do+                return (OpenPushPromise sid ppSid, Right hbf)             HeadersFrame _ hbf       -> -- TODO: handle priority-                return (HTTP2.streamId fh, Right hbf)+                return (ForwardHeader sid, Right hbf)             RSTStreamFrame err       ->-                return (HTTP2.streamId fh, Left err)+                return (ForwardHeader sid, Left err)             _                        -> error "wrong TypeId"      let go curFh (Right buffer) =@@ -576,10 +581,23 @@                     _                     -> error "waitFrameWithTypeIdForStreamId returned an unknown frame"             else do                 newHdrs <- decodeHeader hpackDecoder buffer-                writeChan hdrs (curFh, sId, Right newHdrs)+                case decision of+                    ForwardHeader sId ->+                        writeChan hdrs (curFh, sId, Right newHdrs)+                    OpenPushPromise parentSid newSid -> do+                        -- Important: We duplicate the channel here or we risk+                        -- losing DATA or HEADERS+CONTINUATION frames sent over+                        -- the main stream because even though+                        -- 'initializeStream' dupes frame channels, this+                        -- function will has no guarantee that the parent+                        -- stream and the push-promise handler that will+                        -- initiate the new stream are synchronous.+                        ppChan <- dupChan frames+                        ppHeaders <- dupChan hdrs+                        writeChan pushPromises (parentSid, ppChan, ppHeaders, newSid, newHdrs)          go curFh (Left err) =-                writeChan hdrs (curFh, sId, (Left $ HTTP2.fromErrorCodeId err))+                writeChan hdrs (curFh, sid, (Left $ HTTP2.fromErrorCodeId err))      go fh pattern @@ -835,13 +853,13 @@  waitPushPromiseWithParentStreamId   :: StreamId-  -> Chan (StreamId, Chan (FrameHeader, Either e0 FramePayload), StreamId)-  -> IO (StreamId, Chan (FrameHeader, Either e0 FramePayload), StreamId)+  -> PushPromisesChan e+  -> IO (PushPromisesChanContent e) waitPushPromiseWithParentStreamId sid chan =     loop   where     loop = do-        tuple@(parentSid,_,_) <- readChan chan+        tuple@(parentSid,_,_,_,_) <- readChan chan         if parentSid == sid         then return tuple         else loop