on master help sign in
Merge pull request #702 from yesodweb/pb/timeout-middleware

Add Middleware.Timeout

commit03555027a5f3342a9208f927c8c3a27258805219 authorMichael Snoyman <michael@snoyman.com> dateThu 2 Aug 2018, 08:33 (8 years ago) parent89f81cebb2ba5d
4 files changed+97−1
wai-extra/ChangeLog.md+4 wai-extra/Network/Wai/Middleware/Timeout.hs+33 wai-extra/test/Network/Wai/Middleware/TimeoutSpec.hs+57 wai-extra/wai-extra.cabal+3−1
wai-extra/ChangeLog.md+4
@@ -1,3 +1,7 @@
1+## 3.0.24.0
2+
3+* Add timeout middleware [#702](https://github.com/yesodweb/wai/pull/702).
4+
15## 3.0.23.0
26
37* Add rewriteRoot middleware [#697](https://github.com/yesodweb/wai/pull/697).
wai-extra/Network/Wai/Middleware/Timeout.hsnew file+33
@@ -0,0 +1,33 @@
1+-- | Timeout requests
2+module Network.Wai.Middleware.Timeout
3+ ( timeout
4+ , timeoutStatus
5+ , timeoutAs
6+ ) where
7+
8+import Network.HTTP.Types (Status, status503)
9+import Network.Wai
10+import qualified System.Timeout as Timeout
11+
12+-- | Time out the request after the given number of seconds
13+--
14+-- Timeouts respond with @'status503'@. See @'timeoutStatus'@ or @'timeoutAs'@
15+-- to customize the behavior of the timed-out case.
16+--
17+-- @since 3.0.24.0@
18+timeout :: Int -> Middleware
19+timeout = timeoutStatus status503
20+
21+-- | Time out with the given @'Status'@
22+--
23+-- @since 3.0.24.0@
24+timeoutStatus :: Status -> Int -> Middleware
25+timeoutStatus status = timeoutAs $ responseLBS status [] ""
26+
27+-- | Time out with the given @'Response'@
28+--
29+-- @since 3.0.24.0@
30+timeoutAs :: Response -> Int -> Middleware
31+timeoutAs timeoutReponse seconds app req respond =
32+ maybe (respond timeoutReponse) pure
33+ =<< Timeout.timeout (seconds * 1000000) (app req respond)
wai-extra/test/Network/Wai/Middleware/TimeoutSpec.hsnew file+57
@@ -0,0 +1,57 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Network.Wai.Middleware.TimeoutSpec
4+ ( spec
5+ ) where
6+
7+import Test.Hspec
8+
9+import Control.Concurrent (threadDelay)
10+import Network.HTTP.Types (status200, status503, status504)
11+import Network.Wai
12+import Network.Wai.Middleware.Timeout
13+import Network.Wai.Test
14+
15+spec :: Spec
16+spec = do
17+ describe "timeout" $ do
18+ it "times out slow requests with 503" $ do
19+ let app _req respond = do
20+ threadDelay $ 2 * 1000000
21+ respond $ responseLBS status200 [] ""
22+
23+ resp <- runApp $ timeout 1 app
24+
25+ simpleStatus resp `shouldBe` status503
26+
27+ it "does not time out fast requests" $ do
28+ let app _req respond = respond $ responseLBS status200 [] ""
29+
30+ resp <- runApp $ timeout 3 app
31+
32+ simpleStatus resp `shouldBe` status200
33+
34+ describe "timeoutStatus" $ do
35+ it "allows customizing the timeout response status" $ do
36+ let app _req respond = do
37+ threadDelay $ 2 * 1000000
38+ respond $ responseLBS status200 [] ""
39+
40+ resp <- runApp $ timeoutStatus status504 1 app
41+
42+ simpleStatus resp `shouldBe` status504
43+
44+ describe "timeoutAs" $ do
45+ it "allows customizing the timeout response" $ do
46+ let app _req respond = do
47+ threadDelay $ 2 * 1000000
48+ respond $ responseLBS status200 [] ""
49+ timeoutResponse = responseLBS status503 [("X-Timeout", "1")] ""
50+
51+ resp <- runApp $ timeoutAs timeoutResponse 1 app
52+
53+ simpleStatus resp `shouldBe` status503
54+ simpleHeaders resp `shouldBe` [("X-Timeout", "1")]
55+
56+runApp :: Application -> IO SResponse
57+runApp = runSession $ request defaultRequest
wai-extra/wai-extra.cabal+3−1
@@ -1,5 +1,5 @@
11Name: wai-extra
2−Version: 3.0.23.0
2+Version: 3.0.24.0
33Synopsis: Provides some basic WAI handlers and middleware.
44description:
55 Provides basic WAI handler and middleware functionality:
@@ -148,6 +148,7 @@ Library
148148 Network.Wai.Middleware.ForceDomain
149149 Network.Wai.Middleware.ForceSSL
150150 Network.Wai.Middleware.Routed
151+ Network.Wai.Middleware.Timeout
151152 Network.Wai.Parse
152153 Network.Wai.Request
153154 Network.Wai.UrlMap
@@ -186,6 +187,7 @@ test-suite spec
186187 Network.Wai.Middleware.ForceSSLSpec
187188 Network.Wai.Middleware.RoutedSpec
188189 Network.Wai.Middleware.StripHeadersSpec
190+ Network.Wai.Middleware.TimeoutSpec
189191 WaiExtraSpec
190192 build-depends: base >= 4 && < 5
191193 , wai-extra