on master help sign in
Cleanup: send trailers directly rather than re-enqueuing them.
commitec035d43ab64217b068242a84080084d5d033c52 authorAndrew Pritchard <awpr@google.com> dateSat 29 Aug 2015, 15:21 (11 years ago) parentdb9ae02
2 files changed+24−30
warp/Network/Wai/Handler/Warp/HTTP2/Sender.hs+24−27 warp/Network/Wai/Handler/Warp/HTTP2/Types.hs−3
warp/Network/Wai/Handler/Warp/HTTP2/Sender.hs+24−27
@@ -134,27 +134,6 @@ frameSender ctx@Context{outputQ,connectionWindow}
134134 sendResponse strm s h aux lim
135135 putMVar mvar pushed
136136 loop
137− switch (OTrailers strm trailers) = do
138− _ <- unlessClosed conn strm $ do
139− -- Trailers always indicate the end of a stream; send them in
140− -- consecutive header+continuation frames and end the stream. Some
141− -- clients dislike empty headers frames, so end the stream with an
142− -- empty data frame instead, as recommended by the spec.
143− toFlush <- case trailers of
144− [] -> frameHeaderLength <$ fillFrameHeader FrameData 0
145− (streamNumber strm)
146− (setEndStream defaultFlags)
147− connWriteBuffer
148− _ -> do
149− builder <- hpackEncodeCIHeaders ctx trailers
150− off <- headerContinue (streamNumber strm) builder True
151− return (off + frameHeaderLength)
152− -- 'closed' must be before 'flushN'. If not, the context would be
153− -- switched to the receiver, resulting in the inconsistency of
154− -- concurrency.
155− closed strm Finished
156− flushN toFlush
157− loop
158137
159138 -- Send the response headers and as much of the response as is immediately
160139 -- available; shared by normal responses and pushed streams.
@@ -177,6 +156,27 @@ frameSender ctx@Context{outputQ,connectionWindow}
177156 when needSend $ flushN off
178157 dispatchNext strm mnext
179158
159+ -- Send the stream's trailers and close the stream.
160+ sendTrailers :: Stream -> Trailers -> IO ()
161+ sendTrailers strm trailers = do
162+ -- Trailers always indicate the end of a stream; send them in
163+ -- consecutive header+continuation frames and end the stream. Some
164+ -- clients dislike empty headers frames, so end the stream with an
165+ -- empty data frame instead, as recommended by the spec.
166+ toFlush <- case trailers of
167+ [] -> frameHeaderLength <$ fillFrameHeader FrameData 0
168+ (streamNumber strm)
169+ (setEndStream defaultFlags)
170+ connWriteBuffer
171+ _ -> do
172+ builder <- hpackEncodeCIHeaders ctx trailers
173+ off <- headerContinue (streamNumber strm) builder True
174+ return (off + frameHeaderLength)
175+ -- 'closed' must be before 'flushN'. If not, the context would be
176+ -- switched to the receiver, resulting in the inconsistency of
177+ -- concurrency.
178+ closed strm Finished
179+ flushN toFlush
180180
181181 -- Flush the connection buffer to the socket, where the first 'n' bytes of
182182 -- the buffer are filled.
@@ -237,14 +237,11 @@ frameSender ctx@Context{outputQ,connectionWindow}
237237 -- This is done after sending any part of the stream body, so it's shared
238238 -- by 'sendResponse' and @switch (ONext ...)@.
239239 dispatchNext :: Stream -> Control DynaNext -> IO ()
240− dispatchNext strm (CNext next) = do
240+ dispatchNext _ CNone = return ()
241+ dispatchNext strm (CFinish trailers) = sendTrailers strm trailers
242+ dispatchNext strm (CNext next) = do
241243 let out = ONext strm next
242244 enqueueOrSpawnTemporaryWaiter strm outputQ out
243− dispatchNext strm (CFinish trailers) = do
244− let out = OTrailers strm trailers
245− pri <- readIORef $ streamPriority strm
246− enqueue outputQ out pri
247− dispatchNext _ _ = return ()
248245
249246
250247 -- Send headers if there is not room for a 1-byte data frame, and return
warp/Network/Wai/Handler/Warp/HTTP2/Types.hs−3
@@ -82,14 +82,11 @@ data Output = OFinish
8282 -- MVar whether the promise has been sent.
8383 | ONext Stream DynaNext
8484 -- ^ Send a chunk of the response.
85− | OTrailers Stream Trailers
86− -- ^ Send a series of trailers in header and continuation frames.
8785
8886outputStream :: Output -> Stream
8987outputStream (OResponse strm _ _ _) = strm
9088outputStream (ONext strm _) = strm
9189outputStream (OPush strm _ _ _ _ _ _) = strm
92−outputStream (OTrailers strm _) = strm
9390outputStream _ = error "outputStream"
9491
9592----------------------------------------------------------------