/
Request.purs
85 lines (77 loc) · 2.13 KB
/
Request.purs
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
module Hyper.Request
( class Request
, RequestData
, ParsedUrl
, parseUrl
, getRequestData
, class BaseRequest
, class ReadableBody
, readBody
, class StreamableBody
, streamBody
) where
import Prelude
import Data.Array as Array
import Data.String as String
import Data.Bifunctor (lmap)
import Data.Either (Either)
import Data.HTTP.Method (CustomMethod, Method)
import Data.Lazy (Lazy)
import Data.Maybe (Maybe, fromMaybe)
import Foreign.Object (Object)
import Data.Tuple (Tuple)
import Hyper.Conn (Conn)
import Hyper.Form.Urlencoded (parseUrlencoded)
import Hyper.Middleware (Middleware)
type RequestData =
{ url :: String
, parsedUrl :: Lazy ParsedUrl
, contentLength :: Maybe Int
, headers :: Object String
, method :: Either Method CustomMethod
}
type ParsedUrl =
{ path :: Array String
, query :: Either String (Array (Tuple String (Maybe String)))
}
parseUrl :: String -> ParsedUrl
parseUrl url =
let
idx = fromMaybe (String.length url) $ String.indexOf (String.Pattern "?") url
rawPath = String.take idx url
rawQuery = String.drop (idx + 1) url
path = Array.filter (_ /= "") $ String.split (String.Pattern "/") rawPath
query = lmap (const rawQuery) $ parseUrlencoded rawQuery
in
{path, query}
class Request req m where
getRequestData
:: forall res c
. Middleware
m
(Conn req res c)
(Conn req res c)
RequestData
class Request req m <= BaseRequest req m
-- | A `ReadableBody` instance reads the complete request body as a
-- | value of type `b`. For streaming the request body, see the
-- | [StreamableBody](#streamablebody) class.
class ReadableBody req m b where
readBody
:: forall res c
. Middleware
m
(Conn req res c)
(Conn req res c)
b
-- | A `StreamableBody` instance returns a stream of the request body,
-- | of type `stream`. To read the whole body as a value, without
-- | streaming, see the [ReadableBody](#readablebody) class.
class StreamableBody req m stream | req -> stream where
streamBody
:: forall res c
. Middleware
m
(Conn req res c)
(Conn req res c)
stream