-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathpath_params.rb
61 lines (48 loc) · 1.5 KB
/
path_params.rb
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
require 'rack/utils'
module Goliath
module Contrib
# A middleware to parse Rails-style path parameters. This will parse
# parameters from the request path based on the supplied pattern and
# place them in the _params_ hash of the Goliath::Env for the request.
#
# @example
# use Goliath::Contrib::Rack::PathParams, '/records/:artist/:title'
#
class PathParams
module Parser
PARAM = %r{:([^/]+)(\/|$)}
CAPTURE_GROUP = '(?<\1>[^\/\?]+)\2'
def retrieve_params(env)
md = matched_params(env)
md.names.each_with_object({}) do |key, params|
params[key] = md[key]
end
end
def matched_params(env)
request_path(env).match(regexp).tap do |matched|
raise Goliath::Validation::BadRequestError, "Request path does not match expected pattern: #{request_path(env)}" if matched.nil?
end
end
def request_path(env)
env[Goliath::Request::REQUEST_PATH]
end
def regexp
@regexp ||= %r{^#{@url_pattern.gsub(PARAM, CAPTURE_GROUP)}\/?$}
end
end
include Goliath::Rack::Validator
include Parser
def initialize(app, url_pattern)
@app = app
@url_pattern = url_pattern
end
def call(env)
Goliath::Rack::Validator.safely(env) do
env['params'] ||= {}
env['params'].merge! retrieve_params(env)
@app.call(env)
end
end
end
end
end