warp 3.2.11 → 3.2.11.1
raw patch · 3 files changed
+44/−37 lines, 3 files
Files
- ChangeLog.md +5/−0
- Network/Wai/Handler/Warp/Run.hs +38/−36
- warp.cabal +1/−1
ChangeLog.md view
@@ -1,3 +1,8 @@+## 3.2.11.1++* Move exception handling to top of thread (fixes+ [#613](https://github.com/yesodweb/wai/issues/613))+ ## 3.2.11 * Fixing 10 HTTP2 bugs pointed out by h2spec v2.
Network/Wai/Handler/Warp/Run.hs view
@@ -263,51 +263,53 @@ -> Counter -> InternalInfo0 -> IO ()-fork set mkConn addr app counter ii0 = settingsFork set $ \ unmask ->+fork set mkConn addr app counter ii0 = settingsFork set $ \unmask ->+ -- Call the user-supplied on exception code if any+ -- exceptions are thrown.+ handle (settingsOnException set Nothing) . -- Allocate a new IORef indicating whether the connection has been -- closed, to avoid double-freeing a connection withClosedRef $ \ref ->-- -- Run the connection maker to get a new connection, and ensure- -- that the connection is closed. If the mkConn call throws an- -- exception, we will leak the connection. If the mkConn call is- -- vulnerable to attacks (e.g., Slowloris), we do nothing to- -- protect the server. It is therefore vital that mkConn is well- -- vetted.- --- -- We grab the connection before registering timeouts since the- -- timeouts will be useless during connection creation, due to the- -- fact that async exceptions are still masked.- bracket mkConn (\(conn, _) -> closeConn ref conn `finally` connFree conn)- $ \(conn, transport) ->-- -- We need to register a timeout handler for this thread, and- -- cancel that handler as soon as we exit. We additionally close- -- the connection immediately in case the child thread catches the- -- async exception or performs some long-running cleanup action.- bracket (T.registerKillThread (timeoutManager0 ii0) (closeConn ref conn)) T.cancel $ \th ->-- let ii1 = toInternalInfo1 ii0 th- -- We now have fully registered a connection close handler- -- in the case of all exceptions, so it is safe to one- -- again allow async exceptions.- in unmask .- -- Call the user-supplied on exception code if any- -- exceptions are thrown.- handle (settingsOnException set Nothing) .-- -- Call the user-supplied code for connection open and close events- bracket (onOpen addr) (onClose addr) $ \goingon ->-- -- Actually serve this connection.- -- bracket with closeConn above ensures the connection is closed.- when goingon $ serveConnection conn ii1 addr transport set app+ -- Run the connection maker to get a new connection, and ensure+ -- that the connection is closed. If the mkConn call throws an+ -- exception, we will leak the connection. If the mkConn call is+ -- vulnerable to attacks (e.g., Slowloris), we do nothing to+ -- protect the server. It is therefore vital that mkConn is well+ -- vetted.+ --+ -- We grab the connection before registering timeouts since the+ -- timeouts will be useless during connection creation, due to the+ -- fact that async exceptions are still masked.+ bracket mkConn (cleanUp ref) (serve unmask ref) where withClosedRef inner = newIORef False >>= inner closeConn ref conn = do isClosed <- atomicModifyIORef' ref $ \x -> (True, x) unless isClosed $ connClose conn++ cleanUp ref (conn, _) = closeConn ref conn `finally` connFree conn++ -- We need to register a timeout handler for this thread, and+ -- cancel that handler as soon as we exit. We additionally close+ -- the connection immediately in case the child thread catches the+ -- async exception or performs some long-running cleanup action.+ serve unmask ref (conn, transport) = bracket register cancel $ \th -> do+ let ii1 = toInternalInfo1 ii0 th+ -- We now have fully registered a connection close handler in+ -- the case of all exceptions, so it is safe to one again+ -- allow async exceptions.+ unmask .+ -- Call the user-supplied code for connection open and+ -- close events+ bracket (onOpen addr) (onClose addr) $ \goingon ->+ -- Actually serve this connection. bracket with closeConn+ -- above ensures the connection is closed.+ when goingon $ serveConnection conn ii1 addr transport set app+ where+ register = T.registerKillThread (timeoutManager0 ii0)+ (closeConn ref conn)+ cancel = T.cancel onOpen adr = increase counter >> settingsOnOpen set adr onClose adr _ = decrease counter >> settingsOnClose set adr
warp.cabal view
@@ -1,5 +1,5 @@ Name: warp-Version: 3.2.11+Version: 3.2.11.1 Synopsis: A fast, light-weight web server for WAI applications. License: MIT License-file: LICENSE