diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -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)
diff --git a/Network/Wai/Handler/Warp/HTTP2/HPACK.hs b/Network/Wai/Handler/Warp/HTTP2/HPACK.hs
--- a/Network/Wai/Handler/Warp/HTTP2/HPACK.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/HPACK.hs
@@ -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
diff --git a/Network/Wai/Handler/Warp/HTTP2/Receiver.hs b/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
@@ -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
diff --git a/Network/Wai/Handler/Warp/HTTP2/Types.hs b/Network/Wai/Handler/Warp/HTTP2/Types.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Types.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Types.hs
@@ -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 ()
diff --git a/warp.cabal b/warp.cabal
--- a/warp.cabal
+++ b/warp.cabal
@@ -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
