From fd8098b5fdd4c93fa652b6960cd2d02c0ce8fa91 Mon Sep 17 00:00:00 2001 From: Finley McIlwaine Date: Tue, 6 Aug 2024 14:45:51 -0700 Subject: [PATCH] Avoid unnecessary empty data frames at end of stream Currently, if a stream terminates with an empty data frame, we will send that empty data frame even if it is succeeded by trailers that are marked end of stream. That empty data frame is unnecessary. We should only send it if the payload length is non-zero and we are not sending trailers. --- Network/HTTP2/H2/Sender.hs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Network/HTTP2/H2/Sender.hs b/Network/HTTP2/H2/Sender.hs index 55df6a70..ac01df5e 100644 --- a/Network/HTTP2/H2/Sender.hs +++ b/Network/HTTP2/H2/Sender.hs @@ -282,17 +282,23 @@ frameSender _ reqflush = do let buf = confWriteBuffer `plusPtr` off - off' = off + frameHeaderLength + datPayloadLen (mtrailers, flag) <- do Trailers trailers <- tlrmkr Nothing if null trailers then return (Nothing, setEndStream defaultFlags) else return (Just trailers, defaultFlags) - fillFrameHeader FrameData datPayloadLen streamNumber flag buf + -- Avoid sending an empty data frame before trailers at the end + -- of a stream + off' <- + if datPayloadLen /= 0 || isNothing mtrailers then do + decreaseWindowSize ctx strm datPayloadLen + fillFrameHeader FrameData datPayloadLen streamNumber flag buf + return $ off + frameHeaderLength + datPayloadLen + else + return off off'' <- handleTrailers mtrailers off' _ <- sync Nothing halfClosedLocal ctx strm Finished - decreaseWindowSize ctx strm datPayloadLen if reqflush then do flushN off''