scotty 0.4.2 → 0.4.3
raw patch · 8 files changed
+77/−26 lines, 8 files
Files
- README +1/−1
- Web/Scotty.hs +12/−6
- Web/Scotty/Action.hs +13/−6
- Web/Scotty/Types.hs +10/−2
- Web/Scotty/Util.hs +16/−7
- examples/basic.hs +2/−2
- examples/options.hs +20/−0
- scotty.cabal +3/−2
README view
@@ -20,7 +20,7 @@ * Conforms to WAI Application interface. * Uses very fast Warp webserver by default. -See examples/basic.hs to see Scotty in action.+See examples/basic.hs to see Scotty in action. (basic.hs needs the wai-extra package) > runghc examples/basic.hs Setting phasers to stun... (ctrl-c to quit)
Web/Scotty.hs view
@@ -3,7 +3,7 @@ -- OverloadedStrings language pragma. module Web.Scotty ( -- * scotty-to-WAI- scotty, scottyApp+ scotty, scottyApp, scottyOpts, Options(..) -- * Defining Middleware and Routes -- -- | 'Middleware' and routes are run in the order in which they@@ -22,7 +22,7 @@ -- -- | Note: only one of these should be present in any given route -- definition, as they completely replace the current 'Response' body.- , text, html, file, json+ , text, html, file, json, source -- ** Exceptions , raise, rescue, next -- * Types@@ -31,13 +31,14 @@ import Blaze.ByteString.Builder (fromByteString) +import Control.Monad (when) import Control.Monad.State (execStateT, modify) import Data.Default (def) import Network.HTTP.Types (status404) import Network.Wai-import Network.Wai.Handler.Warp (Port, run)+import Network.Wai.Handler.Warp (Port, runSettings, settingsPort) import Web.Scotty.Action import Web.Scotty.Route@@ -45,9 +46,14 @@ -- | Run a scotty application using the warp server. scotty :: Port -> ScottyM () -> IO ()-scotty p s = do- putStrLn $ "Setting phasers to stun... (ctrl-c to quit) (port " ++ show p ++ ")"- run p =<< scottyApp s+scotty p = scottyOpts $ def { settings = (settings def) { settingsPort = p } }++-- | Run a scotty application using the warp server, passing extra options.+scottyOpts :: Options -> ScottyM() -> IO ()+scottyOpts opts s = do+ when (verbose opts > 0) $+ putStrLn $ "Setting phasers to stun... (port " ++ show (settingsPort (settings opts)) ++ ") (ctrl-c to quit)"+ runSettings (settings opts) =<< scottyApp s -- | Turn a scotty application into a WAI 'Application', which can be -- run with any WAI handler.
Web/Scotty/Action.hs view
@@ -2,12 +2,12 @@ module Web.Scotty.Action ( request, body, param, jsonData , status, header, redirect- , text, html, file, json+ , text, html, file, json, source , raise, rescue, next , ActionM, Parsable, Param, runAction ) where -import Blaze.ByteString.Builder (fromLazyByteString)+import Blaze.ByteString.Builder (Builder, fromLazyByteString) import Control.Applicative import Control.Monad.Error@@ -18,6 +18,7 @@ import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.CaseInsensitive as CI+import Data.Conduit (Flush, ResourceT, Source) import Data.Default (Default, def) import Data.Monoid (mconcat) import qualified Data.Text.Lazy as T@@ -164,23 +165,29 @@ text :: T.Text -> ActionM () text t = do header "Content-Type" "text/plain"- MS.modify $ setContent $ Left $ fromLazyByteString $ encodeUtf8 t+ MS.modify $ setContent $ ContentBuilder $ fromLazyByteString $ encodeUtf8 t -- | Set the body of the response to the given 'T.Text' value. Also sets \"Content-Type\" -- header to \"text/html\". html :: T.Text -> ActionM () html t = do header "Content-Type" "text/html"- MS.modify $ setContent $ Left $ fromLazyByteString $ encodeUtf8 t+ MS.modify $ setContent $ ContentBuilder $ fromLazyByteString $ encodeUtf8 t -- | Send a file as the response. Doesn't set the \"Content-Type\" header, so you probably -- want to do that on your own with 'header'. file :: FilePath -> ActionM ()-file = MS.modify . setContent . Right+file = MS.modify . setContent . ContentFile -- | Set the body of the response to the JSON encoding of the given value. Also sets \"Content-Type\" -- header to \"application/json\". json :: (A.ToJSON a) => a -> ActionM () json v = do header "Content-Type" "application/json"- MS.modify $ setContent $ Left $ fromLazyByteString $ A.encode v+ MS.modify $ setContent $ ContentBuilder $ fromLazyByteString $ A.encode v++-- | Set the body of the response to a Source. Doesn't set the+-- \"Content-Type\" header, so you probably want to do that on your+-- own with 'header'.+source :: Source (ResourceT IO) (Flush Builder) -> ActionM ()+source = MS.modify . setContent . ContentSource
Web/Scotty/Types.hs view
@@ -11,16 +11,24 @@ import Data.Text.Lazy (Text, pack) import Network.Wai+import Network.Wai.Handler.Warp (Settings, defaultSettings) +data Options = Options { verbose :: Int -- ^ 0 = silent, 1(def) = startup banner+ , settings :: Settings -- ^ Warp 'Settings'+ }++instance Default Options where+ def = Options 1 defaultSettings+ data ScottyState = ScottyState { middlewares :: [Middleware] , routes :: [Middleware] } addMiddleware :: Middleware -> ScottyState -> ScottyState-addMiddleware m (ScottyState ms rs) = ScottyState (m:ms) rs+addMiddleware m s@(ScottyState {middlewares = ms}) = s { middlewares = m:ms } addRoute :: Middleware -> ScottyState -> ScottyState-addRoute r (ScottyState ms rs) = ScottyState ms (r:rs)+addRoute r s@(ScottyState {routes = rs}) = s { routes = r:rs } instance Default ScottyState where def = ScottyState [] []
Web/Scotty/Util.hs view
@@ -2,6 +2,7 @@ ( lazyTextToStrictByteString , strictByteStringToLazyText , setContent, setHeader, setStatus+ , Content(..) ) where import Network.Wai@@ -10,6 +11,7 @@ import Blaze.ByteString.Builder (Builder) import Data.CaseInsensitive (CI)+import Data.Conduit (Flush, Source, ResourceT) import Data.Default import Data.Monoid @@ -26,13 +28,20 @@ strictByteStringToLazyText :: B.ByteString -> T.Text strictByteStringToLazyText = T.fromStrict . ES.decodeUtf8 -setContent :: Either Builder FilePath -> Response -> Response-setContent (Left b) (ResponseBuilder s h _) = ResponseBuilder s h b-setContent (Left b) (ResponseFile s h _ _) = ResponseBuilder s h b-setContent (Left b) (ResponseSource s h _) = ResponseBuilder s h b-setContent (Right f) (ResponseBuilder s h _) = ResponseFile s h f Nothing-setContent (Right f) (ResponseFile s h _ _) = ResponseFile s h f Nothing-setContent (Right f) (ResponseSource s h _) = ResponseFile s h f Nothing+data Content = ContentBuilder Builder+ | ContentFile FilePath+ | ContentSource (Source (ResourceT IO) (Flush Builder))++setContent :: Content -> Response -> Response+setContent (ContentBuilder b) (ResponseBuilder s h _) = ResponseBuilder s h b+setContent (ContentBuilder b) (ResponseFile s h _ _) = ResponseBuilder s h b+setContent (ContentBuilder b) (ResponseSource s h _) = ResponseBuilder s h b+setContent (ContentFile f) (ResponseBuilder s h _) = ResponseFile s h f Nothing+setContent (ContentFile f) (ResponseFile s h _ _) = ResponseFile s h f Nothing+setContent (ContentFile f) (ResponseSource s h _) = ResponseFile s h f Nothing+setContent (ContentSource src) (ResponseBuilder s h _) = ResponseSource s h src+setContent (ContentSource src) (ResponseFile s h _ _) = ResponseSource s h src+setContent (ContentSource src) (ResponseSource s h _) = ResponseSource s h src setHeader :: (CI Ascii, Ascii) -> Response -> Response setHeader (k,v) (ResponseBuilder s h b) = ResponseBuilder s (update h k v) b
examples/basic.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} import Web.Scotty -import Network.Wai.Middleware.RequestLogger+import Network.Wai.Middleware.RequestLogger -- install wai-extra if you don't have this import Control.Monad.Trans import Data.Monoid@@ -85,7 +85,7 @@ b <- body text $ decodeUtf8 b - get "/lambda/:foo/:bar" $ \ foo bar baz -> do+ get "/lambda/:foo/:bar/:baz" $ \ foo bar baz -> do text $ mconcat [foo, bar, baz] {- If you don't want to use Warp as your webserver,
+ examples/options.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE OverloadedStrings #-}+import Web.Scotty++import Network.Wai.Middleware.RequestLogger -- install wai-extra if you don't have this++import Data.Default (def)+import Network.Wai.Handler.Warp (settingsPort)++-- Set some Scotty settings+opts :: Options+opts = def { verbose = 0+ , settings = (settings def) { settingsPort = 4000 }+ }++-- This won't display anything at startup, and will listen on localhost:4000+main :: IO ()+main = scottyOpts opts $ do+ middleware logStdoutDev++ get "/" $ text "hello world"
scotty.cabal view
@@ -1,5 +1,5 @@ Name: scotty-Version: 0.4.2+Version: 0.4.3 Synopsis: Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp Homepage: https://github.com/xich/scotty Bug-reports: https://github.com/xich/scotty/issues@@ -55,8 +55,9 @@ Extra-source-files: README examples/basic.hs- examples/urlshortener.hs examples/json.hs+ examples/options.hs+ examples/urlshortener.hs examples/static/jquery.js examples/static/jquery-json.js examples/static/json.js