on master help sign in
Merge PR #782
8773fb4Kazu Yamamoto
warp/Network/Wai/Handler/Warp.hs+34
@@ -72,6 +72,8 @@ module Network.Wai.Handler.Warp (
72 , setLogger
72 , setLogger
73 , setServerPushLogger
73 , setServerPushLogger
74 , setGracefulShutdownTimeout
74 , setGracefulShutdownTimeout
75+ , setGracefulCloseTimeout1
76+ , setGracefulCloseTimeout2
75 -- ** Getters
77 -- ** Getters
76 , getPort
78 , getPort
77 , getHost
79 , getHost
@@ -79,6 +81,8 @@ module Network.Wai.Handler.Warp (
79 , getOnClose
81 , getOnClose
80 , getOnException
82 , getOnException
81 , getGracefulShutdownTimeout
83 , getGracefulShutdownTimeout
84+ , getGracefulCloseTimeout1
85+ , getGracefulCloseTimeout2
82 -- ** Exception handler
86 -- ** Exception handler
83 , defaultOnException
87 , defaultOnException
84 , defaultShouldDisplayException
88 , defaultShouldDisplayException
@@ -457,3 +461,33 @@ pauseTimeout = fromMaybe (return ()) . Vault.lookup pauseTimeoutKey . vault
457-- Since 3.1.10
461-- Since 3.1.10
458getFileInfo :: Request -> FilePath -> IO FileInfo
462getFileInfo :: Request -> FilePath -> IO FileInfo
459getFileInfo = fromMaybe (\_ -> throwIO (userError "getFileInfo")) . Vault.lookup getFileInfoKey . vault
463getFileInfo = 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+setGracefulCloseTimeout1 :: Int -> Settings -> Settings
471+setGracefulCloseTimeout1 x y = y { settingsGracefulCloseTimeout1 = 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+getGracefulCloseTimeout1 :: Settings -> Int
478+getGracefulCloseTimeout1 = settingsGracefulCloseTimeout1
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+setGracefulCloseTimeout2 :: Int -> Settings -> Settings
486+setGracefulCloseTimeout2 x y = y { settingsGracefulCloseTimeout2 = 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+getGracefulCloseTimeout2 :: Settings -> Int
493+getGracefulCloseTimeout2 = settingsGracefulCloseTimeout2
warp/Network/Wai/Handler/Warp/Run.hs+14−4
@@ -58,17 +58,25 @@ import Network.Socket (fdSocket)
58#endif
58#endif
59
59
60-- | Creating 'Connection' for plain HTTP based on a given socket.
60-- | Creating 'Connection' for plain HTTP based on a given socket.
61−socketConnection :: Socket -> IO Connection
61+socketConnection :: Settings -> Socket -> IO Connection
62−socketConnection s = do
62+socketConnection set s = do
63 bufferPool <- newBufferPool
63 bufferPool <- newBufferPool
64 writeBuf <- allocateBuffer bufferSize
64 writeBuf <- allocateBuffer bufferSize
65 let sendall = Sock.sendAll s
65 let sendall = Sock.sendAll s
66+ isH2 <- newIORef False -- HTTP/1.x
66 return Connection {
67 return Connection {
67 connSendMany = Sock.sendMany s
68 connSendMany = Sock.sendMany s
68 , connSendAll = sendall
69 , connSendAll = sendall
69 , connSendFile = sendFile s writeBuf bufferSize sendall
70 , connSendFile = sendFile s writeBuf bufferSize sendall
70#if MIN_VERSION_network(3,1,1)
71#if MIN_VERSION_network(3,1,1)
72+ , connClose = do
73+ h2 <- readIORef isH2
74+ let tm = if h2 then settingsGracefulCloseTimeout2 set
75+ else settingsGracefulCloseTimeout1 set
76+ if tm == 0 then
77+ close s
78+ else
71− , connClose = gracefulClose s 5000
79+ gracefulClose s tm
72#else
80#else
73 , connClose = close s
81 , connClose = close s
74#endif
82#endif
@@ -77,6 +85,7 @@ socketConnection s = do
77 , connRecvBuf = receiveBuf s
85 , connRecvBuf = receiveBuf s
78 , connWriteBuffer = writeBuf
86 , connWriteBuffer = writeBuf
79 , connBufferSize = bufferSize
87 , connBufferSize = bufferSize
88+ , connHTTP2 = isH2
80 }
89 }
81
90
82-- | Run an 'Application' on the given port.
91-- | Run an 'Application' on the given port.
@@ -138,7 +147,7 @@ runSettingsSocket set socket app = do
138 setSocketCloseOnExec s
147 setSocketCloseOnExec s
139 -- NoDelay causes an error for AF_UNIX.
148 -- NoDelay causes an error for AF_UNIX.
140 setSocketOption s NoDelay 1 `E.catch` \(E.SomeException _) -> return ()
149 setSocketOption s NoDelay 1 `E.catch` \(E.SomeException _) -> return ()
141− conn <- socketConnection s
150+ conn <- socketConnection set s
142 return (conn, sa)
151 return (conn, sa)
143
152
144 closeListenSocket = close socket
153 closeListenSocket = close socket
@@ -344,6 +353,7 @@ serveConnection conn ii th origAddr transport settings app = do
344 let recvN = wrappedRecvN th istatus (settingsSlowlorisSize settings) rawRecvN
353 let recvN = wrappedRecvN th istatus (settingsSlowlorisSize settings) rawRecvN
345 -- fixme: origAddr
354 -- fixme: origAddr
346 checkTLS
355 checkTLS
356+ setConnHTTP2 conn True
347 http2 conn transport ii origAddr settings recvN app
357 http2 conn transport ii origAddr settings recvN app
348 else do
358 else do
349 src <- mkSource (wrappedRecv conn th istatus (settingsSlowlorisSize settings))
359 src <- mkSource (wrappedRecv conn th istatus (settingsSlowlorisSize settings))
warp/Network/Wai/Handler/Warp/Settings.hs+14
@@ -109,6 +109,18 @@ data Settings = Settings
109 -- a graceful shutdown of the web server.
109 -- a graceful shutdown of the web server.
110 --
110 --
111 -- Since 3.2.8
111 -- Since 3.2.8
112+ , settingsGracefulCloseTimeout1 :: 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+ , settingsGracefulCloseTimeout2 :: 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
112 }
124 }
113
125
114-- | Specify usage of the PROXY protocol.
126-- | Specify usage of the PROXY protocol.
@@ -145,6 +157,8 @@ defaultSettings = Settings
145 , settingsLogger = \_ _ _ -> return ()
157 , settingsLogger = \_ _ _ -> return ()
146 , settingsServerPushLogger = \_ _ _ -> return ()
158 , settingsServerPushLogger = \_ _ _ -> return ()
147 , settingsGracefulShutdownTimeout = Nothing
159 , settingsGracefulShutdownTimeout = Nothing
160+ , settingsGracefulCloseTimeout1 = 0
161+ , settingsGracefulCloseTimeout2 = 2000
148 }
162 }
149
163
150-- | Apply the logic provided by 'defaultOnException' to determine if an
164-- | 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 {
122 , connWriteBuffer :: Buffer
122 , connWriteBuffer :: Buffer
123 -- | The size of the write buffer.
123 -- | The size of the write buffer.
124 , connBufferSize :: BufSize
124 , connBufferSize :: BufSize
125+ -- | Is this connection HTTP/2?
126+ , connHTTP2 :: IORef Bool
125 }
127 }
126
128
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+
127----------------------------------------------------------------
135----------------------------------------------------------------
128
136
129data InternalInfo = InternalInfo {
137data InternalInfo = InternalInfo {