on master help sign in
configuring timeout for graceful close.
commit1d40f63196e687ce9e58ce337f65b0186060806d authorKazu Yamamoto <kazu@iij.ad.jp> dateFri 13 Dec 2019, 15:07 (7 years ago) parent08265cc
4 files changed+70−4
warp/Network/Wai/Handler/Warp.hs+34 warp/Network/Wai/Handler/Warp/Run.hs+14−4 warp/Network/Wai/Handler/Warp/Settings.hs+14 warp/Network/Wai/Handler/Warp/Types.hs+8
warp/Network/Wai/Handler/Warp.hs+34
@@ -72,6 +72,8 @@ module Network.Wai.Handler.Warp (
7272 , setLogger
7373 , setServerPushLogger
7474 , setGracefulShutdownTimeout
75+ , setGracefulCloseTiemout1
76+ , setGracefulCloseTiemout2
7577 -- ** Getters
7678 , getPort
7779 , getHost
@@ -79,6 +81,8 @@ module Network.Wai.Handler.Warp (
7981 , getOnClose
8082 , getOnException
8183 , getGracefulShutdownTimeout
84+ , getGracefulCloseTiemout1
85+ , getGracefulCloseTiemout2
8286 -- ** Exception handler
8387 , defaultOnException
8488 , defaultShouldDisplayException
@@ -457,3 +461,33 @@ pauseTimeout = fromMaybe (return ()) . Vault.lookup pauseTimeoutKey . vault
457461-- Since 3.1.10
458462getFileInfo :: Request -> FilePath -> IO FileInfo
459463getFileInfo = fromMaybe (\_ -> throwIO (userError "getFileInfo")) . Vault.lookup getFileInfoKey . vault
464+
465+-- | A timeout to limit the time (in milliseconds) waiting for
466+-- FIN for HTTP/1.x. 0 means uses immediate close.
467+-- Default: 0.
468+--
469+-- Since 3.3.5
470+setGracefulCloseTiemout1 :: Int -> Settings -> Settings
471+setGracefulCloseTiemout1 x y = y { settingsGracefulCloseTiemout1 = x }
472+
473+-- | A timeout to limit the time (in milliseconds) waiting for
474+-- FIN for HTTP/1.x. 0 means uses immediate close.
475+--
476+-- Since 3.3.5
477+getGracefulCloseTiemout1 :: Settings -> Int
478+getGracefulCloseTiemout1 = settingsGracefulCloseTiemout1
479+
480+-- | A timeout to limit the time (in milliseconds) waiting for
481+-- FIN for HTTP/2. 0 means uses immediate close.
482+-- Default: 2000.
483+--
484+-- Since 3.3.5
485+setGracefulCloseTiemout2 :: Int -> Settings -> Settings
486+setGracefulCloseTiemout2 x y = y { settingsGracefulCloseTiemout2 = x }
487+
488+-- | A timeout to limit the time (in milliseconds) waiting for
489+-- FIN for HTTP/2. 0 means uses immediate close.
490+--
491+-- Since 3.3.5
492+getGracefulCloseTiemout2 :: Settings -> Int
493+getGracefulCloseTiemout2 = settingsGracefulCloseTiemout2
warp/Network/Wai/Handler/Warp/Run.hs+14−4
@@ -58,17 +58,25 @@ import Network.Socket (fdSocket)
5858#endif
5959
6060-- | Creating 'Connection' for plain HTTP based on a given socket.
61−socketConnection :: Socket -> IO Connection
62−socketConnection s = do
61+socketConnection :: Settings -> Socket -> IO Connection
62+socketConnection set s = do
6363 bufferPool <- newBufferPool
6464 writeBuf <- allocateBuffer bufferSize
6565 let sendall = Sock.sendAll s
66+ isH2 <- newIORef False -- HTTP/1.x
6667 return Connection {
6768 connSendMany = Sock.sendMany s
6869 , connSendAll = sendall
6970 , connSendFile = sendFile s writeBuf bufferSize sendall
7071#if MIN_VERSION_network(3,1,1)
71− , connClose = gracefulClose s 5000
72+ , connClose = do
73+ h2 <- readIORef isH2
74+ let tm = if h2 then settingsGracefulCloseTiemout2 set
75+ else settingsGracefulCloseTiemout1 set
76+ if tm == 0 then
77+ close s
78+ else
79+ gracefulClose s tm
7280#else
7381 , connClose = close s
7482#endif
@@ -77,6 +85,7 @@ socketConnection s = do
7785 , connRecvBuf = receiveBuf s
7886 , connWriteBuffer = writeBuf
7987 , connBufferSize = bufferSize
88+ , connHTTP2 = isH2
8089 }
8190
8291-- | Run an 'Application' on the given port.
@@ -138,7 +147,7 @@ runSettingsSocket set socket app = do
138147 setSocketCloseOnExec s
139148 -- NoDelay causes an error for AF_UNIX.
140149 setSocketOption s NoDelay 1 `E.catch` \(E.SomeException _) -> return ()
141− conn <- socketConnection s
150+ conn <- socketConnection set s
142151 return (conn, sa)
143152
144153 closeListenSocket = close socket
@@ -344,6 +353,7 @@ serveConnection conn ii th origAddr transport settings app = do
344353 let recvN = wrappedRecvN th istatus (settingsSlowlorisSize settings) rawRecvN
345354 -- fixme: origAddr
346355 checkTLS
356+ setConnHTTP2 conn True
347357 http2 conn transport ii origAddr settings recvN app
348358 else do
349359 src <- mkSource (wrappedRecv conn th istatus (settingsSlowlorisSize settings))
warp/Network/Wai/Handler/Warp/Settings.hs+14
@@ -109,6 +109,18 @@ data Settings = Settings
109109 -- a graceful shutdown of the web server.
110110 --
111111 -- Since 3.2.8
112+ , settingsGracefulCloseTiemout1 :: Int
113+ -- ^ A timeout to limit the time (in milliseconds) waiting for
114+ -- FIN for HTTP/1.x. 0 means uses immediate close.
115+ -- Default: 0.
116+ --
117+ -- Since 3.3.5
118+ , settingsGracefulCloseTiemout2 :: Int
119+ -- ^ A timeout to limit the time (in milliseconds) waiting for
120+ -- FIN for HTTP/2. 0 means uses immediate close.
121+ -- Default: 2000.
122+ --
123+ -- Since 3.3.5
112124 }
113125
114126-- | Specify usage of the PROXY protocol.
@@ -145,6 +157,8 @@ defaultSettings = Settings
145157 , settingsLogger = \_ _ _ -> return ()
146158 , settingsServerPushLogger = \_ _ _ -> return ()
147159 , settingsGracefulShutdownTimeout = Nothing
160+ , settingsGracefulCloseTiemout1 = 0
161+ , settingsGracefulCloseTiemout2 = 2000
148162 }
149163
150164-- | Apply the logic provided by 'defaultOnException' to determine if an
warp/Network/Wai/Handler/Warp/Types.hs+8
@@ -122,8 +122,16 @@ data Connection = Connection {
122122 , connWriteBuffer :: Buffer
123123 -- | The size of the write buffer.
124124 , connBufferSize :: BufSize
125+ -- | Is this connection HTTP/2?
126+ , connHTTP2 :: IORef Bool
125127 }
126128
129+getConnHTTP2 :: Connection -> IO Bool
130+getConnHTTP2 conn = readIORef (connHTTP2 conn)
131+
132+setConnHTTP2 :: Connection -> Bool -> IO ()
133+setConnHTTP2 conn b = writeIORef (connHTTP2 conn) b
134+
127135----------------------------------------------------------------
128136
129137data InternalInfo = InternalInfo {