forked from scotty-web/scotty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
basic.hs
113 lines (87 loc) · 3.36 KB
/
basic.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
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)
import Network.HTTP.Types (status302)
import Network.Wai
import qualified Data.Text.Lazy as T
import Data.Text.Lazy.Encoding (decodeUtf8)
import Data.String (fromString)
main :: IO ()
main = scotty 3000 $ do
-- Add any WAI middleware, they are run top-down.
middleware logStdoutDev
-- get (function $ \req -> Just [("version", T.pack $ show $ httpVersion req)]) $ do
-- v <- param "version"
-- text v
-- To demonstrate that routes are matched top-down.
get "/" $ text "foobar"
get "/" $ text "barfoo"
-- Using a parameter in the query string. If it has
-- not been given, a 500 page is generated.
get "/foo" $ do
v <- param "fooparam"
html $ mconcat ["<h1>", v, "</h1>"]
-- An uncaught error becomes a 500 page.
get "/raise" $ raise "some error here"
-- You can set status and headers directly.
get "/redirect-custom" $ do
status status302
setHeader "Location" "http://www.google.com"
-- note first arg to header is NOT case-sensitive
-- redirects preempt execution
get "/redirect" $ do
redirect "http://www.google.com"
raise "this error is never reached"
-- Of course you can catch your own errors.
get "/rescue" $ do
(do raise "a rescued error"; redirect "http://www.we-never-go-here.com")
`rescue` (\m -> text $ "we recovered from " `mappend` m)
-- Parts of the URL that start with a colon match
-- any string, and capture that value as a parameter.
-- URL captures take precedence over query string parameters.
get "/foo/:bar/required" $ do
v <- param "bar"
html $ mconcat ["<h1>", v, "</h1>"]
-- Files are streamed directly to the client.
get "/404" $ file "404.html"
-- You can stop execution of this action and keep pattern matching routes.
get "/random" $ do
next
redirect "http://www.we-never-go-here.com"
-- You can do IO with liftIO, and you can return JSON content.
get "/random" $ do
g <- liftIO newStdGen
json $ take 20 $ randomRs (1::Int,100) g
get "/ints/:is" $ do
is <- param "is"
json $ [(1::Int)..10] ++ is
get "/setbody" $ do
html $ mconcat ["<form method=POST action=\"readbody\">"
,"<input type=text name=something>"
,"<input type=submit>"
,"</form>"
]
post "/readbody" $ do
b <- body
text $ decodeUtf8 b
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.
import Network.Wai.Handler.FastCGI (run)
main = do
myApp <- scottyApp $ do
get "/" $ text "hello world"
run myApp
-}