packages feed

warp 3.2.10 → 3.2.11

raw patch · 5 files changed

+41/−19 lines, 5 files

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+## 3.2.11++* Fixing 10 HTTP2 bugs pointed out by h2spec v2.+ ## 3.2.10  * Add `connFree` to `Connection`. Close socket connections on timeout triggered. Timeout exceptions extend from `SomeAsyncException`. [#602](https://github.com/yesodweb/wai/pull/602) [#605](https://github.com/yesodweb/wai/pull/605)
Network/Wai/Handler/Warp/HTTP2/HPACK.hs view
@@ -83,13 +83,16 @@ {-# INLINE checkRequestHeader #-} checkRequestHeader :: ValueTable -> Bool checkRequestHeader reqvt+  | just mMethod (== "CONNECT") = mPath == Nothing && mScheme == Nothing   | mStatus     /= Nothing      = False   | mMethod     == Nothing      = False+  | mScheme     == Nothing      = False+  | mPath       == Nothing      = False+  | mPath       == Just ""      = False   | mAuthority  == Nothing      = False   | mConnection /= Nothing      = False   | just mTE (/= "trailers")    = False-  | just mMethod (== "CONNECT") = mPath == Nothing && mScheme == Nothing-  | otherwise                   = mPath /= Nothing+  | otherwise                   = True   where     mStatus     = getHeaderValue tokenStatus reqvt     mScheme     = getHeaderValue tokenScheme reqvt
Network/Wai/Handler/Warp/HTTP2/Receiver.hs view
@@ -159,6 +159,8 @@                      when (ftyp == FrameHeaders) $ do                          st <- readIORef $ streamState strm0                          when (isHalfClosed st) $ E.throwIO $ ConnectionError StreamClosed "header must not be sent to half closed"+                         -- Priority made an idele stream+                         when (isIdle st) $ opened ctx strm0                      return js                  Nothing                    | isResponse streamId -> return Nothing@@ -166,19 +168,23 @@                          when (ftyp `notElem` [FrameHeaders,FramePriority]) $                              E.throwIO $ ConnectionError ProtocolError "this frame is not allowed in an idel stream"                          csid <- readIORef clientStreamId-                         when (streamId <= csid) $-                             E.throwIO $ ConnectionError ProtocolError "stream identifier must not decrease"-                         when (ftyp == FrameHeaders) $ do-                             writeIORef clientStreamId streamId-                             cnt <- readIORef concurrency-                             -- Checking the limitation of concurrency-                             when (cnt >= maxConcurrency) $-                                 E.throwIO $ StreamError RefusedStream streamId-                         ws <- initialWindowSize <$> readIORef http2settings-                         newstrm <- newStream streamId (fromIntegral ws)-                         when (ftyp == FrameHeaders) $ opened ctx newstrm-                         insert streamTable streamId newstrm-                         return $ Just newstrm+                         if streamId <= csid then do+                             if ftyp == FramePriority then+                                 return Nothing -- will be ignored+                               else+                                 E.throwIO $ ConnectionError ProtocolError "stream identifier must not decrease"+                           else do+                             when (ftyp == FrameHeaders) $ do+                                 writeIORef clientStreamId streamId+                                 cnt <- readIORef concurrency+                                 -- Checking the limitation of concurrency+                                 when (cnt >= maxConcurrency) $+                                     E.throwIO $ StreamError RefusedStream streamId+                             ws <- initialWindowSize <$> readIORef http2settings+                             newstrm <- newStream streamId (fromIntegral ws)+                             when (ftyp == FrameHeaders) $ opened ctx newstrm+                             insert streamTable streamId newstrm+                             return $ Just newstrm      consume = void . recvN @@ -191,14 +197,18 @@ ----------------------------------------------------------------  control :: FrameTypeId -> FrameHeader -> ByteString -> Context -> IO Bool-control FrameSettings header@FrameHeader{flags} bs Context{http2settings, controlQ,firstSettings} = do+control FrameSettings header@FrameHeader{flags} bs Context{http2settings, controlQ, firstSettings, streamTable} = do     SettingsFrame alist <- guardIt $ decodeSettingsFrame header bs     case checkSettingsList alist of         Just x  -> E.throwIO x         Nothing -> return ()     -- HTTP/2 Setting from a browser     unless (testAck flags) $ do+        oldws <- initialWindowSize <$> readIORef http2settings         modifyIORef' http2settings $ \old -> updateSettings old alist+        newws <- initialWindowSize <$> readIORef http2settings+        let diff = newws - oldws+        when (diff /= 0) $ updateAllStreamWindow (+ diff) streamTable         let !frame = settingsFrame setAck []         sent <- readIORef firstSettings         let !setframe@@ -210,7 +220,7 @@  control FramePing FrameHeader{flags} bs Context{controlQ} =     if testAck flags then-        E.throwIO $ ConnectionError ProtocolError "the ack flag of this ping frame must not be set"+        return True -- just ignore       else do         let !frame = pingFrame bs         enqueueControl controlQ $ CFrame frame
Network/Wai/Handler/Warp/HTTP2/Types.hs view
@@ -11,7 +11,7 @@ import Control.Concurrent (forkIO) import Control.Concurrent.STM import Control.Exception (SomeException, bracket)-import Control.Monad (void)+import Control.Monad (void, forM_) import Data.ByteString (ByteString) import qualified Data.ByteString as BS import Data.IntMap.Strict (IntMap, IntMap)@@ -255,6 +255,11 @@  search :: StreamTable -> M.Key -> IO (Maybe Stream) search (StreamTable ref) k = M.lookup k <$> readIORef ref++updateAllStreamWindow :: (WindowSize -> WindowSize) -> StreamTable -> IO ()+updateAllStreamWindow adst (StreamTable ref) = do+    strms <- M.elems <$> readIORef ref+    forM_ strms $ \strm -> atomically $ modifyTVar (streamWindow strm) adst  {-# INLINE forkAndEnqueueWhenReady #-} forkAndEnqueueWhenReady :: IO () -> PriorityTree Output -> Output -> Manager -> IO ()
warp.cabal view
@@ -1,5 +1,5 @@ Name:                warp-Version:             3.2.10+Version:             3.2.11 Synopsis:            A fast, light-weight web server for WAI applications. License:             MIT License-file:        LICENSE