Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased changes

- Change `waitStream` so that it automatically credits the connection. This
is a breaking change due to function signature change.

## v0.10.0.0

- Export frameHttp2RawConnection to convert an RawHttp2Connection into an Http2FrameConnection.
Expand Down
2 changes: 1 addition & 1 deletion examples/SimpleGet.lhs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ client-originated streams (however with its own flow-control context).
> resetPushPromises _ pps _ _ _ = _rst pps RefusedStream
>
> handler sfc _ = do
> waitStream stream sfc resetPushPromises >>= print . fromStreamResult
> waitStream conn stream sfc resetPushPromises >>= print . fromStreamResult

We've defined an initializer and a handler so far.

Expand Down
27 changes: 21 additions & 6 deletions src/Network/HTTP2/Client/Helpers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,16 @@ upload dat flagmod conn connectionFlowControl stream streamFlowControl = do
--
-- This function is fine if you don't want to consume results in chunks. See
-- 'fromStreamResult' to collect the complicated 'StreamResult' into a simpler
-- 'StramResponse'.
waitStream :: Http2Stream
-- 'StreamResponse'.
waitStream :: Http2Client
-- ^The connection.
-> Http2Stream
-- ^The stream to wait on. This stream must be part of the connection.
-> IncomingFlowControl
-- ^Incoming flow control for the __stream__.
-> PushPromiseHandler
-> ClientIO StreamResult
waitStream stream streamFlowControl ppHandler = do
waitStream conn stream streamFlowControl ppHandler = do
ev <- _waitEvent stream
case ev of
StreamHeadersEvent fH hdrs
Expand All @@ -131,20 +135,31 @@ waitStream stream streamFlowControl ppHandler = do
return (Right hdrs, reverse dfrms, trls)
StreamPushPromiseEvent _ ppSid ppHdrs -> do
_handlePushPromise stream ppSid ppHdrs ppHandler
waitStream stream streamFlowControl ppHandler
waitStream conn stream streamFlowControl ppHandler
_ ->
error $ "expecting StreamHeadersEvent but got " ++ show ev
where
connFlowControl = _incomingFlowControl conn
waitDataFrames xs = do
ev <- _waitEvent stream
case ev of
StreamDataEvent fh x
| HTTP2.testEndStream (HTTP2.flags fh) ->
return ((Right x):xs, Nothing)
| otherwise -> do
_ <- lift $ _consumeCredit streamFlowControl (HTTP2.payloadLength fh)
lift $ _addCredit streamFlowControl (HTTP2.payloadLength fh)
let size = HTTP2.payloadLength fh
_ <- lift $ _consumeCredit streamFlowControl size
lift $ _addCredit streamFlowControl size
_ <- _updateWindow $ streamFlowControl
-- We also send a WINDOW_UPDATE for the connection in order
-- to not rely on external updateWindow calls. This reduces
-- latency and makes the function less error-prone to use.
-- Note that the main loop (dispatchLoop) already credits
-- the connection for received data frames, but it does not
-- send the WINDOW_UPDATE frames.. That is why we only send
-- those frames here, and we do not credit the connection
-- as we do the stream in the preceding lines.
_ <- _updateWindow $ connFlowControl
waitDataFrames ((Right x):xs)
StreamPushPromiseEvent _ ppSid ppHdrs -> do
_handlePushPromise stream ppSid ppHdrs ppHandler
Expand Down