@@ -154,8 +154,17 @@ frameReceiver ctx mkreq recvN = loop `E.catch` sendGoaway
154154 else
155155 writeIORef currentStreamId streamId
156156 cnt <- readIORef concurrency
157− when (cnt >= recommendedConcurrency) $
158− E.throwIO $ ConnectionError RefusedStream "over max concurrency"
157+ when (cnt >= recommendedConcurrency) $ do
158+ -- Record that the stream is closed, rather than
159+ -- idle, so that receiving frames on it is only a
160+ -- stream error.
161+ consume payloadLength
162+ strm <- newStream streamId 0
163+ writeIORef (streamState strm) $ Closed $
164+ ResetByMe $ E.toException $
165+ StreamError RefusedStream streamId
166+ insert streamTable streamId strm
167+ E.throwIO $ StreamError RefusedStream streamId
159168 ws <- initialWindowSize <$> readIORef http2settings
160169 newstrm <- newStream streamId (fromIntegral ws)
161170 when (ftyp == FrameHeaders) $ opened ctx newstrm
@@ -315,5 +324,7 @@ stream FramePriority header bs Context{outputQ} s Stream{streamNumber} = do
315324
316325-- this ordering is important
317326stream _ _ _ _ (Open Continued{}) _ = E.throwIO $ ConnectionError ProtocolError "an illegal frame follows header/continuation frames"
327+-- Ignore frames to streams we have just reset, per section 5.1.
328+stream _ _ _ _ st@(Closed (ResetByMe _)) _ = return st
318329stream FrameData FrameHeader{streamId} _ _ _ _ = E.throwIO $ StreamError StreamClosed streamId
319330stream _ FrameHeader{streamId} _ _ _ _ = E.throwIO $ StreamError ProtocolError streamId