scotty 0.6.2 → 0.7.0
raw patch · 8 files changed
+130/−62 lines, 8 filesdep ~aesondep ~textdep ~wai
Dependency ranges changed: aeson, text, wai, wai-extra, warp
Files
- ReleaseNotes.md +0/−42
- Web/Scotty.hs +11/−2
- Web/Scotty/Action.hs +26/−4
- Web/Scotty/Trans.hs +4/−4
- Web/Scotty/Types.hs +7/−1
- changelog.md +64/−0
- examples/basic.hs +11/−2
- scotty.cabal +7/−7
− ReleaseNotes.md
@@ -1,42 +0,0 @@-## 0.6.0--* The Scotty transformers (`ScottyT` and `ActionT`) are now parameterized- over a custom exception type, allowing one to extend Scotty's `ErrorT`- layer with something richer than `Text` errors. See the `exceptions`- example for use. `ScottyM` and `ActionM` remain specialized to `Text`- exceptions for simplicity.--* Both monads are now instances of `Functor` and `Applicative`.--* There is a new `cookies` example.--* Internals brought up-to-date with WAI 2.0 and related packages.--## 0.5.0--* The Scotty monads (`ScottyM` and `ActionM`) are now monad transformers,- allowing Scotty applications to be embedded in arbitrary `MonadIO`s.- The old API continues to be exported from `Web.Scotty` where:-- type ScottyM = ScottyT IO- type ActionM = ActionT IO-- The new transformers are found in `Web.Scotty.Trans`. See the- `globalstate` example for use. Special thanks to Dan Frumin (co-dan)- for much of the legwork here.--* Added support for HTTP PATCH method.--* Removed lambda action syntax. This will return when we have a better- story for typesafe routes.--* `reqHeader :: Text -> ActionM Text` ==> - `reqHeader :: Text -> ActionM (Maybe Text)`--* New `raw` method to set body to a raw `ByteString`--* Parse error thrown by `jsonData` now includes the body it couldn't parse.--* `header` split into `setHeader` and `addHeader`. The former replaces- a response header (original behavior). The latter adds a header (useful- for multiple `Set-Cookie`s, for instance).
Web/Scotty.hs view
@@ -13,7 +13,7 @@ -- ** Route Patterns , capture, regex, function, literal -- ** Accessing the Request, Captures, and Query Parameters- , request, reqHeader, body, param, params, jsonData, files+ , request, header, reqHeader, headers, body, param, params, jsonData, files -- ** Modifying the Response and Redirecting , status, addHeader, setHeader, redirect -- ** Setting Response Body@@ -122,8 +122,17 @@ files = Trans.files -- | Get a request header. Header name is case-insensitive.+header :: Text -> ActionM (Maybe Text)+header = Trans.header++-- | Get a request header. Header name is case-insensitive. (Deprecated in favor of `header`.) reqHeader :: Text -> ActionM (Maybe Text)-reqHeader = Trans.reqHeader+reqHeader = Trans.header+{-# DEPRECATED reqHeader "Use header instead. reqHeader will be removed in the next release." #-}++-- | Get all the request headers. Header names are case-insensitive.+headers :: ActionM [(Text, Text)]+headers = Trans.headers -- | Get the request body. body :: ActionM ByteString
Web/Scotty/Action.hs view
@@ -4,6 +4,8 @@ , body , file , files+ , header+ , headers , html , json , jsonData@@ -14,7 +16,7 @@ , raw , readEither , redirect- , reqHeader+ , reqHeader -- Deprecated , request , rescue , setHeader@@ -121,12 +123,25 @@ files :: (ScottyError e, Monad m) => ActionT e m [File] files = ActionT $ liftM getFiles ask --- | Get a request header. Header name is case-insensitive.+-- | Get a request header. Header name is case-insensitive. (Deprecated in favor of `header`.) reqHeader :: (ScottyError e, Monad m) => T.Text -> ActionT e m (Maybe T.Text)-reqHeader k = do+reqHeader = header+{-# DEPRECATED reqHeader "Use header instead. This will be removed in the next release." #-}++-- | Get a request header. Header name is case-insensitive.+header :: (ScottyError e, Monad m) => T.Text -> ActionT e m (Maybe T.Text)+header k = do hs <- liftM requestHeaders request return $ fmap strictByteStringToLazyText $ lookup (CI.mk (lazyTextToStrictByteString k)) hs +-- | Get all the request headers. Header names are case-insensitive.+headers :: (ScottyError e, Monad m) => ActionT e m [(T.Text, T.Text)]+headers = do+ hs <- liftM requestHeaders request+ return [ ( strictByteStringToLazyText (CI.original k)+ , strictByteStringToLazyText v) + | (k,v) <- hs ]+ -- | Get the request body. body :: (ScottyError e, Monad m) => ActionT e m BL.ByteString body = ActionT $ liftM getBody ask@@ -183,7 +198,14 @@ instance (Parsable a) => Parsable [a] where parseParam = parseParamList -instance Parsable Bool where parseParam = readEither+instance Parsable Bool where + parseParam t = if t' == T.toCaseFold "true"+ then Right True+ else if t' == T.toCaseFold "false"+ then Right False+ else Left "parseParam Bool: no parse"+ where t' = T.toCaseFold t+ instance Parsable Double where parseParam = readEither instance Parsable Float where parseParam = readEither instance Parsable Int where parseParam = readEither
Web/Scotty/Trans.hs view
@@ -17,7 +17,7 @@ -- ** Route Patterns , capture, regex, function, literal -- ** Accessing the Request, Captures, and Query Parameters- , request, reqHeader, body, param, params, jsonData, files+ , request, header, reqHeader, headers, body, param, params, jsonData, files -- ** Modifying the Response and Redirecting , status, addHeader, setHeader, redirect -- ** Setting Response Body@@ -45,7 +45,7 @@ import Network.HTTP.Types (status404) import Network.Wai-import Network.Wai.Handler.Warp (Port, runSettings, settingsPort)+import Network.Wai.Handler.Warp (Port, runSettings, setPort, getPort) import Web.Scotty.Action import Web.Scotty.Route@@ -60,7 +60,7 @@ -> (m Response -> IO Response) -- ^ Run monad 'm' into 'IO', called at each action. -> ScottyT e m () -> n ()-scottyT p = scottyOptsT $ def { settings = (settings def) { settingsPort = p } }+scottyT p = scottyOptsT $ def { settings = setPort p (settings def) } -- | Run a scotty application using the warp server, passing extra options. -- NB: 'scottyOpts opts' === 'scottyOptsT opts id id'@@ -72,7 +72,7 @@ -> n () scottyOptsT opts runM runActionToIO s = do when (verbose opts > 0) $- liftIO $ putStrLn $ "Setting phasers to stun... (port " ++ show (settingsPort (settings opts)) ++ ") (ctrl-c to quit)"+ liftIO $ putStrLn $ "Setting phasers to stun... (port " ++ show (getPort (settings opts)) ++ ") (ctrl-c to quit)" liftIO . runSettings (settings opts) =<< scottyAppT runM runActionToIO s -- | Turn a scotty application into a WAI 'Application', which can be
Web/Scotty/Types.hs view
@@ -4,6 +4,7 @@ import Blaze.ByteString.Builder (Builder) import Control.Applicative+import qualified Control.Exception as E import Control.Monad.Error import Control.Monad.Reader import Control.Monad.State@@ -109,7 +110,12 @@ def = SR status200 [] (ContentBuilder mempty) newtype ActionT e m a = ActionT { runAM :: ErrorT (ActionError e) (ReaderT ActionEnv (StateT ScottyResponse m)) a }- deriving ( Functor, Applicative, Monad, MonadIO )+ deriving ( Functor, Applicative, Monad )++instance (MonadIO m, ScottyError e) => MonadIO (ActionT e m) where+ liftIO io = ActionT $ do+ r <- liftIO $ liftM Right io `E.catch` (\ e -> return $ Left $ stringError $ show (e :: E.SomeException))+ either throwError return r instance ScottyError e => MonadTrans (ActionT e) where lift = ActionT . lift . lift . lift
+ changelog.md view
@@ -0,0 +1,64 @@+## 0.7.0++* Renamed `reqHeader` to `header`. Added `headers` function to get all headers.++* Changed `MonadIO` instance for `ActionT` such that IO exceptions are lifted+ into `ScottyError`s via `stringError`.++* Make `Bool` parsing case-insensitive. Goal: support both Haskell's True/False+ and Javascript's true/false. Thanks to Ben Gamari for suggesting this.++* Bump `aeson`/`text` upper bounds.++* Bump `wai`/`wai-extra`/`warp` bounds, including new lower bound for `warp`, which fixes a security issue related to Slowloris protection.++## 0.6.2++* Bump upper bound for `text`.++## 0.6.1++* Match changes in `wai-extra`.++## 0.6.0++* The Scotty transformers (`ScottyT` and `ActionT`) are now parameterized+ over a custom exception type, allowing one to extend Scotty's `ErrorT`+ layer with something richer than `Text` errors. See the `exceptions`+ example for use. `ScottyM` and `ActionM` remain specialized to `Text`+ exceptions for simplicity.++* Both monads are now instances of `Functor` and `Applicative`.++* There is a new `cookies` example.++* Internals brought up-to-date with WAI 2.0 and related packages.++## 0.5.0++* The Scotty monads (`ScottyM` and `ActionM`) are now monad transformers,+ allowing Scotty applications to be embedded in arbitrary `MonadIO`s.+ The old API continues to be exported from `Web.Scotty` where:++ type ScottyM = ScottyT IO+ type ActionM = ActionT IO++ The new transformers are found in `Web.Scotty.Trans`. See the+ `globalstate` example for use. Special thanks to Dan Frumin (co-dan)+ for much of the legwork here.++* Added support for HTTP PATCH method.++* Removed lambda action syntax. This will return when we have a better+ story for typesafe routes.++* `reqHeader :: Text -> ActionM Text` ==> + `reqHeader :: Text -> ActionM (Maybe Text)`++* New `raw` method to set body to a raw `ByteString`++* Parse error thrown by `jsonData` now includes the body it couldn't parse.++* `header` split into `setHeader` and `addHeader`. The former replaces+ a response header (original behavior). The latter adds a header (useful+ for multiple `Set-Cookie`s, for instance).
examples/basic.hs view
@@ -3,6 +3,7 @@ import Network.Wai.Middleware.RequestLogger -- install wai-extra if you don't have this +import Control.Monad import Control.Monad.Trans import Data.Monoid import System.Random (newStdGen, randomRs)@@ -12,6 +13,7 @@ import qualified Data.Text.Lazy as T import Data.Text.Lazy.Encoding (decodeUtf8)+import Data.String (fromString) main :: IO () main = scotty 3000 $ do@@ -85,9 +87,16 @@ b <- body text $ decodeUtf8 b - get "/reqHeader" $ do- agent <- reqHeader "User-Agent"+ get "/header" $ do+ agent <- header "User-Agent" maybe (raise "User-Agent header not found!") text agent++ -- Make a request to this URI, then type a line in the terminal, which+ -- will be the response. Using ctrl-c will cause getLine to fail.+ -- This demonstrates that IO exceptions are lifted into ActionM exceptions.+ get "/iofail" $ do+ msg <- liftIO $ liftM fromString getLine+ text msg {- If you don't want to use Warp as your webserver, you can use any WAI handler.
scotty.cabal view
@@ -1,5 +1,5 @@ Name: scotty-Version: 0.6.2+Version: 0.7.0 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@@ -47,7 +47,7 @@ Extra-source-files: README.md- ReleaseNotes.md+ changelog.md examples/404.html examples/basic.hs examples/cookies.hs@@ -68,7 +68,7 @@ Web.Scotty.Types Web.Scotty.Util default-language: Haskell2010- build-depends: aeson >= 0.6.2.1 && < 0.7,+ build-depends: aeson >= 0.6.2.1 && < 0.8, base >= 4.3.1 && < 5, blaze-builder >= 0.3.3.0 && < 0.4, bytestring >= 0.10.0.2 && < 0.11,@@ -78,11 +78,11 @@ http-types >= 0.8.2 && < 0.9, mtl >= 2.1.2 && < 2.2, regex-compat >= 0.95.1 && < 0.96,- text >= 0.11.3.1 && < 1.1,+ text >= 0.11.3.1 && < 1.2, transformers >= 0.3.0.0 && < 0.4,- wai >= 2.0.0 && < 2.1,- wai-extra >= 2.0.1 && < 2.1,- warp >= 2.0.0.1 && < 2.1+ wai >= 2.0.0 && < 2.2,+ wai-extra >= 2.0.1 && < 2.2,+ warp >= 2.1.1 && < 2.2 GHC-options: -Wall -fno-warn-orphans