on master help sign in
moving length stuff from Stream to OpenState.
7559404Kazu Yamamoto
warp/Network/Wai/Handler/Warp/HTTP2/Receiver.hs+9−10
@@ -100,7 +100,7 @@ frameReceiver ctx mkreq recvN = loop 0 `E.catch` sendGoaway
100 control ftyp header pl ctx
100 control ftyp header pl ctx
101 | otherwise = do
101 | otherwise = do
102 checkContinued
102 checkContinued
103− !strm@Stream{streamState,streamContentLength,streamPrecedence} <- getStream
103+ !strm@Stream{streamState,streamPrecedence} <- getStream
104 pl <- recvN payloadLength
104 pl <- recvN payloadLength
105 state <- readIORef streamState
105 state <- readIORef streamState
106 state' <- stream ftyp header pl ctx state strm
106 state' <- stream ftyp header pl ctx state strm
@@ -117,10 +117,10 @@ frameReceiver ctx mkreq recvN = loop 0 `E.catch` sendGoaway
117 Open (HasBody tbl@(_,reqvt) pri) -> do
117 Open (HasBody tbl@(_,reqvt) pri) -> do
118 resetContinued
118 resetContinued
119 q <- newTQueueIO
119 q <- newTQueueIO
120+ let !mcl = readInt <$> getHeaderValue tokenContentLength reqvt
120 writeIORef streamPrecedence $ toPrecedence pri
121 writeIORef streamPrecedence $ toPrecedence pri
122+ bodyLength <- newIORef 0
121− writeIORef streamState (Open (Body q))
123+ writeIORef streamState $ Open (Body q mcl bodyLength)
122− let mcl = readInt <$> getHeaderValue tokenContentLength reqvt
123− writeIORef streamContentLength mcl
124 readQ <- newReadBody q
124 readQ <- newReadBody q
125 bodySource <- mkSource readQ
125 bodySource <- mkSource readQ
126 let (!req, !ii) = mkreq tbl (readSource bodySource)
126 let (!req, !ii) = mkreq tbl (readSource bodySource)
@@ -257,7 +257,7 @@ stream FrameHeaders header@FrameHeader{flags} bs ctx (Open JustOpened) Stream{st
257 let !siz = BS.length frag
257 let !siz = BS.length frag
258 return $ Open $ Continued [frag] siz 1 endOfStream pri
258 return $ Open $ Continued [frag] siz 1 endOfStream pri
259
259
260−stream FrameHeaders header@FrameHeader{flags} bs _ (Open (Body q)) _ = do
260+stream FrameHeaders header@FrameHeader{flags} bs _ (Open (Body q _ _)) _ = do
261 -- trailer is not supported.
261 -- trailer is not supported.
262 -- let's read and ignore it.
262 -- let's read and ignore it.
263 HeadersFrame _ _ <- guardIt $ decodeHeadersFrame header bs
263 HeadersFrame _ _ <- guardIt $ decodeHeadersFrame header bs
@@ -272,13 +272,13 @@ stream FrameHeaders header@FrameHeader{flags} bs _ (Open (Body q)) _ = do
272stream FrameData
272stream FrameData
273 header@FrameHeader{flags,payloadLength,streamId}
273 header@FrameHeader{flags,payloadLength,streamId}
274 bs
274 bs
275− Context{controlQ} s@(Open (Body q))
275+ Context{controlQ} s@(Open (Body q mcl bodyLength))
276− Stream{streamNumber,streamBodyLength,streamContentLength} = do
276+ Stream{streamNumber} = do
277 DataFrame body <- guardIt $ decodeDataFrame header bs
277 DataFrame body <- guardIt $ decodeDataFrame header bs
278 let !endOfStream = testEndStream flags
278 let !endOfStream = testEndStream flags
279− len0 <- readIORef streamBodyLength
279+ len0 <- readIORef bodyLength
280 let !len = len0 + payloadLength
280 let !len = len0 + payloadLength
281− writeIORef streamBodyLength len
281+ writeIORef bodyLength len
282 when (payloadLength /= 0) $ do
282 when (payloadLength /= 0) $ do
283 let !frame1 = windowUpdateFrame 0 payloadLength
283 let !frame1 = windowUpdateFrame 0 payloadLength
284 !frame2 = windowUpdateFrame streamNumber payloadLength
284 !frame2 = windowUpdateFrame streamNumber payloadLength
@@ -286,7 +286,6 @@ stream FrameData
286 enqueueControl controlQ $ CFrame frame
286 enqueueControl controlQ $ CFrame frame
287 atomically $ writeTQueue q body
287 atomically $ writeTQueue q body
288 if endOfStream then do
288 if endOfStream then do
289− mcl <- readIORef streamContentLength
290 case mcl of
289 case mcl of
291 Nothing -> return ()
290 Nothing -> return ()
292 Just cl -> when (cl /= len) $ E.throwIO $ StreamError ProtocolError streamId
291 Just cl -> when (cl /= len) $ E.throwIO $ StreamError ProtocolError streamId
warp/Network/Wai/Handler/Warp/HTTP2/Types.hs+7−9
@@ -149,6 +149,9 @@ data OpenState =
149 | NoBody (TokenHeaderList,ValueTable) !Priority
149 | NoBody (TokenHeaderList,ValueTable) !Priority
150 | HasBody (TokenHeaderList,ValueTable) !Priority
150 | HasBody (TokenHeaderList,ValueTable) !Priority
151 | Body !(TQueue ByteString)
151 | Body !(TQueue ByteString)
152+ !(Maybe Int) -- received Content-Length
153+ -- compared the body length for error checking
154+ !(IORef Int) -- actual body length
152
155
153data ClosedCode = Finished
156data ClosedCode = Finished
154 | Killed
157 | Killed
@@ -187,13 +190,10 @@ instance Show StreamState where
187----------------------------------------------------------------
190----------------------------------------------------------------
188
191
189data Stream = Stream {
192data Stream = Stream {
190− streamNumber :: !StreamId
193+ streamNumber :: !StreamId
191− , streamState :: !(IORef StreamState)
194+ , streamState :: !(IORef StreamState)
192− -- Next two fields are for error checking.
193− , streamContentLength :: !(IORef (Maybe Int))
194− , streamBodyLength :: !(IORef Int)
195− , streamWindow :: !(TVar WindowSize)
195+ , streamWindow :: !(TVar WindowSize)
196− , streamPrecedence :: !(IORef Precedence)
196+ , streamPrecedence :: !(IORef Precedence)
197 }
197 }
198
198
199instance Show Stream where
199instance Show Stream where
@@ -201,8 +201,6 @@ instance Show Stream where
201
201
202newStream :: StreamId -> WindowSize -> IO Stream
202newStream :: StreamId -> WindowSize -> IO Stream
203newStream sid win = Stream sid <$> newIORef Idle
203newStream sid win = Stream sid <$> newIORef Idle
204− <*> newIORef Nothing
205− <*> newIORef 0
206 <*> newTVarIO win
204 <*> newTVarIO win
207 <*> newIORef defaultPrecedence
205 <*> newIORef defaultPrecedence
208
206