-
Notifications
You must be signed in to change notification settings - Fork 67
/
routing.jl
72 lines (57 loc) · 1.91 KB
/
routing.jl
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
import HTTP
export method, GET, route, page, probability, query
# Request type
method(m::AbstractString, app...) = branch(req -> req[:method] == m, app...)
method(ms, app...) = branch(req -> req[:method] in ms, app...)
GET(app...) = method("GET", app...)
# Path routing
splitpath(p::AbstractString) = split(p, "/", keepempty=false)
splitpath(p) = p
function matchpath(target, path)
length(target) > length(path) && return
params = d()
for i = 1:length(target)
if startswith(target[i], ":")
params[Symbol(target[i][2:end])] = path[i]
else
target[i] == path[i] || return
end
end
return params
end
function matchpath!(target, req)
ps = matchpath(target, req[:path])
ps === nothing && return false
merge!(params!(req), ps)
splice!(req[:path], 1:length(target))
return true
end
route(p::Vector, app...) = branch(req -> matchpath!(p, req), app...)
route(p::AbstractString, app...) = route(splitpath(p), app...)
route(app...) = route([], app...)
route(app::Base.Callable, p) = route(p, app)
route(app1::Base.Callable, app2::Base.Callable) = route([], app1, app2)
page(p::Vector, app...) = branch(req -> length(p) == length(req[:path]) && matchpath!(p, req), app...)
page(p::AbstractString, app...) = page(splitpath(p), app...)
page(app...) = page([], app...)
page(app::Base.Callable, p) = page(p, app)
page(app1::Base.Callable, app2::Base.Callable) = page([], app1, app2)
# Query routing
function matchquery(q, req)
qdict = HTTP.URIs.queryparams(req[:query])
length(q) != length(qdict) && return false
for (key, value) in q
if haskey(qdict, key) && (value == "" || value == qdict[key])
continue
else
return false
end
end
return true
end
query(q::Dict{<:AbstractString, <:AbstractString}, app...) =
branch(req -> matchquery(q, req), app...)
# Misc
probability(x, app...) = branch(_->rand()<x, app...)
# Old typo
@deprecate probabilty(x, app...) probability(x, app...)