@@ -93,49 +93,51 @@ frameSender ctx@Context{outputQ,connectionWindow}
9393 switch (OFrame frame) = do
9494 connSendAll frame
9595 loop
96− switch (OResponse strm rsp aux) = unlessClosed ctx conn strm $ do
97− lim <- getWindowSize connectionWindow (streamWindow strm)
98− -- Header frame and Continuation frame
99− let sid = streamNumber strm
100− endOfStream = case aux of
101− Persist{} -> False
102− Oneshot hb -> not hb
103− len <- headerContinue sid rsp endOfStream
104− let total = len + frameHeaderLength
105− case aux of
106− Oneshot True -> do -- hasBody
107− -- Data frame payload
108− (off, _) <- sendHeadersIfNecessary total
109− let payloadOff = off + frameHeaderLength
110− Next datPayloadLen mnext <-
111− fillResponseBodyGetNext conn ii payloadOff lim rsp
112− fillDataHeaderSend strm total datPayloadLen mnext
113− maybeEnqueueNext strm mnext
114− Oneshot False -> do
115− -- "closed" must be before "connSendAll". If not,
116− -- the context would be switched to the receiver,
117− -- resulting the inconsistency of concurrency.
118− closed ctx strm Finished
119− flushN total
120− Persist sq tvar -> do
121− (off, needSend) <- sendHeadersIfNecessary total
122− let payloadOff = off + frameHeaderLength
123− Next datPayloadLen mnext <-
124− fillStreamBodyGetNext conn payloadOff lim sq tvar strm
125− -- If no data was immediately available, avoid sending an
126− -- empty data frame.
127− if datPayloadLen > 0 then
96+ switch (OResponse strm rsp aux) = do
97+ unlessClosed ctx conn strm $ do
98+ lim <- getWindowSize connectionWindow (streamWindow strm)
99+ -- Header frame and Continuation frame
100+ let sid = streamNumber strm
101+ endOfStream = case aux of
102+ Persist{} -> False
103+ Oneshot hb -> not hb
104+ len <- headerContinue sid rsp endOfStream
105+ let total = len + frameHeaderLength
106+ case aux of
107+ Oneshot True -> do -- hasBody
108+ -- Data frame payload
109+ (off, _) <- sendHeadersIfNecessary total
110+ let payloadOff = off + frameHeaderLength
111+ Next datPayloadLen mnext <-
112+ fillResponseBodyGetNext conn ii payloadOff lim rsp
128113 fillDataHeaderSend strm total datPayloadLen mnext
129− else
130− when needSend $ flushN off
131− maybeEnqueueNext strm mnext
114+ maybeEnqueueNext strm mnext
115+ Oneshot False -> do
116+ -- "closed" must be before "connSendAll". If not,
117+ -- the context would be switched to the receiver,
118+ -- resulting the inconsistency of concurrency.
119+ closed ctx strm Finished
120+ flushN total
121+ Persist sq tvar -> do
122+ (off, needSend) <- sendHeadersIfNecessary total
123+ let payloadOff = off + frameHeaderLength
124+ Next datPayloadLen mnext <-
125+ fillStreamBodyGetNext conn payloadOff lim sq tvar strm
126+ -- If no data was immediately available, avoid sending an
127+ -- empty data frame.
128+ if datPayloadLen > 0 then
129+ fillDataHeaderSend strm total datPayloadLen mnext
130+ else
131+ when needSend $ flushN off
132+ maybeEnqueueNext strm mnext
132133 loop
133− switch (ONext strm curr) = unlessClosed ctx conn strm $ do
134− lim <- getWindowSize connectionWindow (streamWindow strm)
135− -- Data frame payload
136− Next datPayloadLen mnext <- curr lim
137− fillDataHeaderSend strm 0 datPayloadLen mnext
138− maybeEnqueueNext strm mnext
134+ switch (ONext strm curr) = do
135+ unlessClosed ctx conn strm $ do
136+ lim <- getWindowSize connectionWindow (streamWindow strm)
137+ -- Data frame payload
138+ Next datPayloadLen mnext <- curr lim
139+ fillDataHeaderSend strm 0 datPayloadLen mnext
140+ maybeEnqueueNext strm mnext
139141 loop
140142
141143 -- Flush the connection buffer to the socket, where the first 'n' bytes of