scotty 0.11.0 → 0.11.1
raw patch · 9 files changed
+68/−25 lines, 9 filesdep +exceptionsdep +hpc-coverallsdep ~aesondep ~basedep ~bytestring
Dependencies added: exceptions, hpc-coveralls
Dependency ranges changed: aeson, base, bytestring, network, warp
Files
- LICENSE +1/−1
- README.md +3/−3
- Web/Scotty.hs +1/−1
- Web/Scotty/Internal/Types.hs +9/−2
- Web/Scotty/Route.hs +13/−4
- changelog.md +5/−0
- examples/exceptions.hs +3/−0
- scotty.cabal +24/−9
- test/Web/ScottySpec.hs +9/−5
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2012 Andrew Farmer+Copyright (c) 2012-2017 Andrew Farmer All rights reserved. Redistribution and use in source and binary forms, with or without
README.md view
@@ -1,4 +1,4 @@-# Scotty [](https://travis-ci.org/scotty-web/scotty)[](https://coveralls.io/r/scotty-web/scotty?branch=master)+# Scotty [](https://travis-ci.org/scotty-web/scotty)[](https://coveralls.io/r/scotty-web/scotty?branch=master) A Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp. @@ -8,7 +8,7 @@ import Data.Monoid (mconcat) -main = scotty 3000 $ do+main = scotty 3000 $ get "/:word" $ do beam <- param "word" html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]@@ -41,4 +41,4 @@ Open an issue on GitHub or join `#scotty` on Freenode. -Copyright (c) 2012-2014 Andrew Farmer+Copyright (c) 2012-2017 Andrew Farmer
Web/Scotty.hs view
@@ -114,7 +114,7 @@ -- | Abort execution of this action. Like an exception, any code after 'finish' -- is not executed. ----- As an example only requests to /foo/special will include in the response+-- As an example only requests to @/foo/special@ will include in the response -- content the text message. -- -- > get "/foo/:bar" $ do
Web/Scotty/Internal/Types.hs view
@@ -12,6 +12,7 @@ import Control.Applicative import qualified Control.Exception as E import Control.Monad.Base (MonadBase, liftBase, liftBaseDefault)+import Control.Monad.Catch (MonadCatch, catch, MonadThrow, throwM) import Control.Monad.Error.Class import qualified Control.Monad.Fail as Fail import Control.Monad.Reader@@ -33,7 +34,7 @@ import Network.Wai hiding (Middleware, Application) import qualified Network.Wai as Wai-import Network.Wai.Handler.Warp (Settings, defaultSettings, setFdCacheDuration)+import Network.Wai.Handler.Warp (Settings, defaultSettings) import Network.Wai.Parse (FileInfo) --------------------- Options -----------------------@@ -48,7 +49,7 @@ } instance Default Options where- def = Options 1 (setFdCacheDuration 0 defaultSettings)+ def = Options 1 defaultSettings ----- Transformer Aware Applications/Middleware ----- type Middleware m = Application m -> Application m@@ -173,6 +174,12 @@ instance (MonadBase b m, ScottyError e) => MonadBase b (ActionT e m) where liftBase = liftBaseDefault ++instance (MonadThrow m, ScottyError e) => MonadThrow (ActionT e m) where+ throwM = ActionT . throwM++instance (MonadCatch m, ScottyError e) => MonadCatch (ActionT e m) where+ catch (ActionT m) f = ActionT (m `catch` (runAM . f)) instance MonadTransControl (ActionT e) where type StT (ActionT e) a = StT (StateT ScottyResponse) (StT (ReaderT ActionEnv) (StT (ExceptT (ActionError e)) a))
Web/Scotty/Route.hs view
@@ -57,7 +57,7 @@ -- | Add a route that matches regardless of the HTTP verb. matchAny :: (ScottyError e, MonadIO m) => RoutePattern -> ActionT e m () -> ScottyT e m ()-matchAny pattern action = mapM_ (\v -> addroute v pattern action) [minBound..maxBound]+matchAny pattern action = ScottyT $ MS.modify $ \s -> addRoute (route (handler s) Nothing pattern action) s -- | Specify an action to take if nothing else is found. Note: this _always_ matches, -- so should generally be the last route specified.@@ -79,12 +79,21 @@ -- >>> curl http://localhost:3000/foo/something -- something addroute :: (ScottyError e, MonadIO m) => StdMethod -> RoutePattern -> ActionT e m () -> ScottyT e m ()-addroute method pat action = ScottyT $ MS.modify $ \s -> addRoute (route (handler s) method pat action) s+addroute method pat action = ScottyT $ MS.modify $ \s -> addRoute (route (handler s) (Just method) pat action) s -route :: (ScottyError e, MonadIO m) => ErrorHandler e m -> StdMethod -> RoutePattern -> ActionT e m () -> Middleware m+route :: (ScottyError e, MonadIO m) => ErrorHandler e m -> Maybe StdMethod -> RoutePattern -> ActionT e m () -> Middleware m route h method pat action app req = let tryNext = app req- in if Right method == parseMethod (requestMethod req)+ {- |+ We match all methods in the case where 'method' is 'Nothing'.+ See https://github.com/scotty-web/scotty/issues/196+ -}+ methodMatches :: Bool+ methodMatches =+ case method of+ Nothing -> True+ Just m -> Right m == parseMethod (requestMethod req)+ in if methodMatches then case matchRoute pat req of Just captures -> do env <- mkEnv req captures
changelog.md view
@@ -1,3 +1,8 @@+## 0.11.1 [2018.04.07]+* Add `MonadThrow` and `MonadCatch` instances for `ActionT` [abhinav]+* Fix `matchAny` so that all methods are matched, not just standard ones+ [taphu]+ ## 0.11.0 * IO exceptions are no longer automatically turned into ScottyErrors by `liftIO`. Use `liftAndCatchIO` to get that behavior.
examples/exceptions.hs view
@@ -33,6 +33,9 @@ handleEx (NotFound i) = do status status404 html $ fromString $ "<h1>Can't find " ++ show i ++ ".</h1>"+handleEx (StringEx s) = do+ status status500+ html $ fromString $ "<h1>" ++ s ++ "</h1>" main :: IO () main = scottyT 3000 id $ do -- note, we aren't using any additional transformer layers
scotty.cabal view
@@ -1,5 +1,5 @@ Name: scotty-Version: 0.11.0+Version: 0.11.1 Synopsis: Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp Homepage: https://github.com/scotty-web/scotty Bug-reports: https://github.com/scotty-web/scotty/issues@@ -22,7 +22,7 @@ . import Data.Monoid (mconcat) .- main = scotty 3000 $ do+ main = scotty 3000 $   get "/:word" $ do     beam <- param "word"     html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]@@ -44,7 +44,11 @@ [WAI] <http://hackage.haskell.org/package/wai> . [Warp] <http://hackage.haskell.org/package/warp>-+tested-with: GHC == 7.6.3+ , GHC == 7.8.4+ , GHC == 7.10.3+ , GHC == 8.0.2+ , GHC == 8.2.2 Extra-source-files: README.md changelog.md@@ -60,6 +64,11 @@ examples/static/jquery.js examples/static/jquery-json.js +flag hpc-coveralls+ description: Build hpc-coveralls in the test suite.+ default: True+ manual: True+ Library Exposed-modules: Web.Scotty Web.Scotty.Trans@@ -68,14 +77,15 @@ Web.Scotty.Route Web.Scotty.Util default-language: Haskell2010- build-depends: aeson >= 0.6.2.1 && < 0.11,- base >= 4.3.1 && < 5,+ build-depends: aeson >= 0.6.2.1 && < 1.4,+ base >= 4.6 && < 5, blaze-builder >= 0.3.3.0 && < 0.5, bytestring >= 0.10.0.2 && < 0.11, case-insensitive >= 1.0.0.1 && < 1.3,- data-default-class >= 0.0.1 && < 0.1,+ data-default-class >= 0.0.1 && < 0.2,+ exceptions >= 0.7 && < 0.11, fail,- http-types >= 0.8.2 && < 0.10,+ http-types >= 0.8.2 && < 0.13, monad-control >= 1.0.0.3 && < 1.1, mtl >= 2.1.2 && < 2.3, nats >= 0.1 && < 2,@@ -84,10 +94,10 @@ text >= 0.11.3.1 && < 1.3, transformers >= 0.3.0.0 && < 0.6, transformers-base >= 0.4.1 && < 0.5,- transformers-compat >= 0.4 && < 0.6,+ transformers-compat >= 0.4 && < 0.7, wai >= 3.0.0 && < 3.3, wai-extra >= 3.0.0 && < 3.1,- warp >= 3.0.0 && < 3.3+ warp >= 3.0.13 && < 3.3 GHC-options: -Wall -fno-warn-orphans @@ -99,6 +109,7 @@ hs-source-dirs: test build-depends: async, base,+ bytestring, data-default-class, directory, hspec == 2.*,@@ -109,6 +120,10 @@ scotty, text, wai+ build-tool-depends: hspec-discover:hspec-discover == 2.*+ if flag(hpc-coveralls)+ build-depends: hpc-coveralls+ build-tool-depends: hpc-coveralls:hpc-coveralls GHC-options: -Wall -threaded -fno-warn-orphans source-repository head
test/Web/ScottySpec.hs view
@@ -18,9 +18,12 @@ #if !defined(mingw32_HOST_OS) import Control.Concurrent.Async (withAsync)+import qualified Data.ByteString as BS+import Data.ByteString (ByteString) import Data.Default.Class (def) import Network (listenOn, PortID(..))-import Network.Socket+import Network.Socket (Family(..), SockAddr(..), SocketType(..), close, connect, socket)+import Network.Socket.ByteString (send, recv) import System.Directory (removeFile) #endif @@ -57,9 +60,9 @@ describe "matchAny" $ do withApp (matchAny "/scotty" $ html "") $ do- forM_ availableMethods $ \method -> do+ forM_ ("NONSTANDARD" : fmap renderStdMethod availableMethods) $ \method -> do it ("adds route that matches " ++ show method ++ " requests") $ do- request (renderStdMethod method) "/scotty" [] "" `shouldRespondWith` 200+ request method "/scotty" [] "" `shouldRespondWith` 200 describe "notFound" $ do withApp (notFound $ html "my custom not found page") $ do@@ -167,8 +170,9 @@ r1 <- recv sock 1024 _ <- send sock "GET /four-oh-four HTTP/1.1\r\n\n" r2 <- recv sock 1024- (take (length ok) r1, take (length no) r2) `shouldBe` (ok, no)- where ok = "HTTP/1.1 200 OK"+ (BS.take (BS.length ok) r1, BS.take (BS.length no) r2) `shouldBe` (ok, no)+ where ok, no :: ByteString+ ok = "HTTP/1.1 200 OK" no = "HTTP/1.1 404 Not Found" socketPath :: FilePath