renee-core 0.3.11 → 0.4.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/{renee_core.rb → renee/core.rb} +20 -13
- data/lib/{renee_core → renee/core}/chaining.rb +17 -15
- data/lib/{renee_core → renee/core}/env_accessors.rb +3 -3
- data/lib/{renee_core → renee/core}/exceptions.rb +0 -0
- data/lib/{renee_core → renee/core}/matcher.rb +0 -0
- data/lib/renee/core/plugins.rb +31 -0
- data/lib/{renee_core → renee/core}/rack_interaction.rb +0 -0
- data/lib/renee/core/request_context.rb +56 -0
- data/lib/{renee_core → renee/core}/responding.rb +3 -1
- data/lib/{renee_core → renee/core}/response.rb +0 -0
- data/lib/{renee_core → renee/core}/routing.rb +98 -101
- data/lib/{renee_core → renee/core}/transform.rb +0 -0
- data/test/{chaining_test.rb → renee-core/chaining_test.rb} +3 -3
- data/test/{env_accessors_test.rb → renee-core/env_accessors_test.rb} +1 -1
- data/test/{include_test.rb → renee-core/include_test.rb} +0 -0
- data/test/renee-core/request_context_test.rb +70 -0
- data/test/{responding_test.rb → renee-core/responding_test.rb} +0 -0
- data/test/{routing_test.rb → renee-core/routing_test.rb} +39 -82
- data/test/renee-core/test_helper.rb +4 -0
- data/test/{variable_type_test.rb → renee-core/variable_type_test.rb} +0 -0
- data/test/test_helper.rb +70 -4
- metadata +88 -129
- data/.yardopts +0 -6
- data/README.md +0 -242
- data/Rakefile +0 -13
- data/lib/renee_core/request_context.rb +0 -25
- data/lib/renee_core/url_generation.rb +0 -108
- data/lib/renee_core/version.rb +0 -6
- data/renee-core.gemspec +0 -26
- data/test/url_generation_test.rb +0 -66
@@ -1,15 +1,17 @@
|
|
1
1
|
require 'rack'
|
2
|
-
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require '
|
7
|
-
require '
|
8
|
-
require '
|
9
|
-
require '
|
10
|
-
require '
|
11
|
-
require '
|
12
|
-
require '
|
2
|
+
|
3
|
+
require 'renee/version'
|
4
|
+
require 'renee/core/matcher'
|
5
|
+
require 'renee/core/chaining'
|
6
|
+
require 'renee/core/response'
|
7
|
+
require 'renee/core/exceptions'
|
8
|
+
require 'renee/core/rack_interaction'
|
9
|
+
require 'renee/core/request_context'
|
10
|
+
require 'renee/core/transform'
|
11
|
+
require 'renee/core/routing'
|
12
|
+
require 'renee/core/responding'
|
13
|
+
require 'renee/core/env_accessors'
|
14
|
+
require 'renee/core/plugins'
|
13
15
|
|
14
16
|
# Top-level Renee constant
|
15
17
|
module Renee
|
@@ -25,9 +27,15 @@ module Renee
|
|
25
27
|
# For convience you can also used a method named #Renee
|
26
28
|
# for decalaring new instances.
|
27
29
|
class Core
|
30
|
+
# Current version of Renee::Core
|
31
|
+
VERSION = Renee::VERSION
|
32
|
+
|
33
|
+
# Error raised if routing fails. Use #continue_routing to continue routing.
|
34
|
+
NotMatchedError = Class.new(RuntimeError)
|
35
|
+
|
28
36
|
# Class methods that are included in new instances of {Core}
|
29
37
|
module ClassMethods
|
30
|
-
include
|
38
|
+
include Plugins
|
31
39
|
|
32
40
|
# The application block used to create your application.
|
33
41
|
attr_reader :application_block
|
@@ -46,7 +54,6 @@ module Renee
|
|
46
54
|
register_variable_type :integer, IntegerMatcher
|
47
55
|
register_variable_type :int, :integer
|
48
56
|
end
|
49
|
-
self
|
50
57
|
end
|
51
58
|
|
52
59
|
# Runs class methods on your application.
|
@@ -13,29 +13,28 @@ module Renee
|
|
13
13
|
module Chaining
|
14
14
|
# @private
|
15
15
|
class ChainingProxy
|
16
|
-
def initialize(target, m, args)
|
16
|
+
def initialize(target, m, args = nil)
|
17
17
|
@target, @calls = target, []
|
18
18
|
@calls << [m, args]
|
19
19
|
end
|
20
20
|
|
21
21
|
def method_missing(m, *args, &blk)
|
22
22
|
@calls << [m, args]
|
23
|
-
if blk.nil? && @target.class.
|
23
|
+
if blk.nil? && @target.class.respond_to?(:chainable?) && @target.class.chainable?(m)
|
24
24
|
self
|
25
25
|
else
|
26
26
|
inner_args = []
|
27
27
|
ret = nil
|
28
28
|
callback = proc do |*callback_args|
|
29
29
|
inner_args.concat(callback_args)
|
30
|
-
if @calls.size == 0
|
31
|
-
blk.call(*inner_args)
|
30
|
+
if @calls.size == 0
|
31
|
+
ret = blk.call(*inner_args) if blk
|
32
32
|
else
|
33
33
|
call = @calls.shift
|
34
|
-
ret = @target.send(call.at(0), *call.at(1), &callback)
|
34
|
+
ret = call.at(1) ? @target.send(call.at(0), *call.at(1), &callback) : @target.send(call.at(0), &callback)
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
38
|
-
ret = @target.send(call.at(0), *call.at(1), &callback)
|
37
|
+
ret = callback.call
|
39
38
|
ret
|
40
39
|
end
|
41
40
|
end
|
@@ -43,17 +42,20 @@ module Renee
|
|
43
42
|
|
44
43
|
# @private
|
45
44
|
module ClassMethods
|
46
|
-
def
|
45
|
+
def chainable?(m)
|
46
|
+
method_defined?(:"#{m}_chainable")
|
47
|
+
end
|
48
|
+
|
49
|
+
def chainable(*methods)
|
47
50
|
methods.each do |m|
|
48
|
-
|
49
|
-
alias_method :#{m}_without_chain, :#{m}
|
50
|
-
def #{m}(*args, &blk)
|
51
|
-
blk.nil? ? ChainingProxy.new(self, #{m.inspect}, args) : #{m}_without_chain(*args, &blk)
|
52
|
-
end
|
53
|
-
private :#{m}_without_chain
|
54
|
-
EOT
|
51
|
+
define_method(:"#{m}_chainable") { }
|
55
52
|
end
|
56
53
|
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_chain_proxy(method_name, *args)
|
58
|
+
ChainingProxy.new(self, method_name, args)
|
57
59
|
end
|
58
60
|
|
59
61
|
def self.included(o)
|
@@ -5,9 +5,9 @@ module Renee
|
|
5
5
|
|
6
6
|
# Exception for attempting to define an env accessor cannot be written as a method name.
|
7
7
|
# @example
|
8
|
-
# env_accessor "current.user" # raises
|
8
|
+
# env_accessor "current.user" # raises InvalidEnvNameError
|
9
9
|
# env_accessor "current.user" => :current_user # this works
|
10
|
-
|
10
|
+
InvalidEnvNameError = Class.new(RuntimeError)
|
11
11
|
|
12
12
|
# Class-methods included by this module.
|
13
13
|
module ClassMethods
|
@@ -55,7 +55,7 @@ module Renee
|
|
55
55
|
yield k, v
|
56
56
|
end
|
57
57
|
else
|
58
|
-
raise
|
58
|
+
raise InvalidEnvNameError, "Called env attr for #{a.inspect}, to use this, call your env method like this. env_reader #{a.inspect} => #{a.to_s.gsub(/-\./, '_').to_sym.inspect}" if a.to_s[/[-\.]/]
|
59
59
|
yield a, a.to_sym
|
60
60
|
end
|
61
61
|
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Renee
|
2
|
+
class Core
|
3
|
+
module Plugins
|
4
|
+
attr_reader :init_blocks, :before_blocks, :after_blocks
|
5
|
+
|
6
|
+
def on_init(&blk)
|
7
|
+
init_blocks << blk
|
8
|
+
end
|
9
|
+
|
10
|
+
def init_blocks
|
11
|
+
(@init_blocks ||= [])
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_before(&blk)
|
15
|
+
before_blocks << blk
|
16
|
+
end
|
17
|
+
|
18
|
+
def before_blocks
|
19
|
+
(@before_blocks ||= [])
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_after(&blk)
|
23
|
+
before_blocks << blk
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_blocks
|
27
|
+
(@after_blocks ||= [])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
File without changes
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Renee
|
2
|
+
class Core
|
3
|
+
module ClassMethods
|
4
|
+
def use(mw, *args, &blk)
|
5
|
+
middlewares << [mw, args, blk]
|
6
|
+
end
|
7
|
+
|
8
|
+
def middlewares
|
9
|
+
@middlewares ||= []
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# This module deals with the Rack#call compilance. It defines #call and also defines several critical methods
|
14
|
+
# used by interaction by other application modules.
|
15
|
+
module RequestContext
|
16
|
+
attr_reader :env, :request, :detected_extension
|
17
|
+
|
18
|
+
# Provides a rack interface compliant call method.
|
19
|
+
# @param[Hash] env The rack environment.
|
20
|
+
def call(e)
|
21
|
+
initialize_plugins
|
22
|
+
idx = 0
|
23
|
+
next_app = proc do |env|
|
24
|
+
if idx == self.class.middlewares.size
|
25
|
+
@env, @request = env, Rack::Request.new(env)
|
26
|
+
@detected_extension = env['PATH_INFO'][/\.([^\.\/]+)$/, 1]
|
27
|
+
# TODO clear template cache in development? `template_cache.clear`
|
28
|
+
out = catch(:halt) do
|
29
|
+
begin
|
30
|
+
self.class.before_blocks.each { |b| instance_eval(&b) }
|
31
|
+
instance_eval(&self.class.application_block)
|
32
|
+
rescue ClientError => e
|
33
|
+
e.response ? instance_eval(&e.response) : halt("There was an error with your request", 400)
|
34
|
+
rescue NotMatchedError => e
|
35
|
+
# unmatched, continue on
|
36
|
+
end
|
37
|
+
Renee::Core::Response.new("Not found", 404).finish
|
38
|
+
end
|
39
|
+
self.class.after_blocks.each { |a| out = instance_exec(out, &a) }
|
40
|
+
out
|
41
|
+
else
|
42
|
+
middleware = self.class.middlewares[idx]
|
43
|
+
idx += 1
|
44
|
+
middleware[0].new(next_app, *middleware[1], &middleware[2]).call(env)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
next_app[e]
|
48
|
+
end # call
|
49
|
+
|
50
|
+
def initialize_plugins
|
51
|
+
self.class.init_blocks.each { |init_block| self.class.class_eval(&init_block) }
|
52
|
+
self.class.send(:define_method, :initialize_plugins) { }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -42,7 +42,9 @@ module Renee
|
|
42
42
|
# respond("Hello", 200, "foo" => "bar")
|
43
43
|
#
|
44
44
|
def respond(body=[], status=200, header={}, &blk)
|
45
|
-
Renee::Core::Response.new(body, status, header)
|
45
|
+
response = Renee::Core::Response.new(body, status, header)
|
46
|
+
response.instance_eval(&blk) if block_given?
|
47
|
+
response.finish
|
46
48
|
end
|
47
49
|
|
48
50
|
##
|
File without changes
|
@@ -4,6 +4,26 @@ module Renee
|
|
4
4
|
module Routing
|
5
5
|
include Chaining
|
6
6
|
|
7
|
+
# Allow continued routing if a routing block fails to match
|
8
|
+
#
|
9
|
+
# @param [Boolean] val
|
10
|
+
# indicate if continued routing should be allowed.
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
def continue_routing
|
14
|
+
if block_given?
|
15
|
+
original_env = @env.dup
|
16
|
+
begin
|
17
|
+
yield
|
18
|
+
rescue NotMatchedError
|
19
|
+
@env = original_env
|
20
|
+
end
|
21
|
+
else
|
22
|
+
create_chain_proxy(:continue_routing)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
chainable :continue_routing
|
26
|
+
|
7
27
|
# Match a path to respond to.
|
8
28
|
#
|
9
29
|
# @param [String] p
|
@@ -21,27 +41,27 @@ module Renee
|
|
21
41
|
#
|
22
42
|
# @api public
|
23
43
|
def path(p, &blk)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# @see #path
|
32
|
-
def whole_path(p, &blk)
|
33
|
-
path(p) { complete(&blk) }
|
44
|
+
if blk
|
45
|
+
p = p[1, p.size] if p[0] == ?/
|
46
|
+
extension_part = detected_extension ? "|\\.#{Regexp.quote(detected_extension)}" : ""
|
47
|
+
part(/^\/#{Regexp.quote(p)}(?=\/|$#{extension_part})/, &blk)
|
48
|
+
else
|
49
|
+
create_chain_proxy(:path, p)
|
50
|
+
end
|
34
51
|
end
|
35
|
-
|
52
|
+
chainable :path
|
36
53
|
|
37
54
|
# Like #path, but doesn't look for leading slashes.
|
38
|
-
def part(p
|
39
|
-
|
40
|
-
|
41
|
-
|
55
|
+
def part(p)
|
56
|
+
if block_given?
|
57
|
+
p = /^\/?#{Regexp.quote(p)}/ if p.is_a?(String)
|
58
|
+
if match = env['PATH_INFO'][p]
|
59
|
+
with_path_part(match) { yield }
|
60
|
+
end
|
61
|
+
else
|
62
|
+
create_chain_proxy(:part, p)
|
42
63
|
end
|
43
64
|
end
|
44
|
-
chain_method :part
|
45
65
|
|
46
66
|
# Match parts off the path as variables. The parts matcher can conform to either a regular expression, or be an Integer, or
|
47
67
|
# simply a String.
|
@@ -68,54 +88,54 @@ module Renee
|
|
68
88
|
#
|
69
89
|
# @api public
|
70
90
|
def variable(type = nil, &blk)
|
71
|
-
complex_variable(type, '/', 1, &blk)
|
91
|
+
blk ? complex_variable(type, '/', 1, &blk) : create_chain_proxy(:variable, type)
|
72
92
|
end
|
73
93
|
alias_method :var, :variable
|
74
|
-
|
94
|
+
chainable :variable, :var
|
95
|
+
|
96
|
+
def optional_variable(type = nil, &blk)
|
97
|
+
blk ? complex_variable(type, '/', 0..1) { |vars| blk[vars.first] } : create_chain_proxy(:variable, type)
|
98
|
+
end
|
99
|
+
alias_method :optional, :optional_variable
|
100
|
+
chainable :optional, :optional_variable
|
75
101
|
|
76
102
|
# Same as variable except you can match multiple variables with the same type.
|
77
103
|
# @param [Range, Integer] count The number of parameters to capture.
|
78
104
|
# @param [Symbol] type The type to use for match.
|
79
105
|
def multi_variable(count, type = nil, &blk)
|
80
|
-
complex_variable(type, '/', count, &blk)
|
106
|
+
blk ? complex_variable(type, '/', count, &blk) : create_chain_proxy(:multi_variable, count, type)
|
81
107
|
end
|
82
108
|
alias_method :multi_var, :multi_variable
|
83
109
|
alias_method :mvar, :multi_variable
|
84
|
-
|
110
|
+
chainable :multi_variable, :multi_var, :mvar
|
85
111
|
|
86
112
|
# Same as variable except it matches indefinitely.
|
87
113
|
# @param [Symbol] type The type to use for match.
|
88
114
|
def repeating_variable(type = nil, &blk)
|
89
|
-
complex_variable(type, '/', nil, &blk)
|
115
|
+
blk ? complex_variable(type, '/', nil, &blk) : create_chain_proxy(:repeating_variable, type)
|
90
116
|
end
|
91
117
|
alias_method :glob, :repeating_variable
|
92
|
-
|
118
|
+
chainable :repeating_variable, :glob
|
93
119
|
|
94
120
|
# Match parts off the path as variables without a leading slash.
|
95
121
|
# @see #variable
|
96
122
|
# @api public
|
97
123
|
def partial_variable(type = nil, &blk)
|
98
|
-
complex_variable(type, nil, 1, &blk)
|
124
|
+
blk ? complex_variable(type, nil, 1, &blk) : create_chain_proxy(:partial_variable, type)
|
99
125
|
end
|
100
126
|
alias_method :part_var, :partial_variable
|
101
|
-
|
127
|
+
chainable :partial_variable, :part_var
|
102
128
|
|
103
|
-
#
|
129
|
+
# Returns the matched extension. If no extension is present, returns `nil`.
|
104
130
|
#
|
105
131
|
# @example
|
106
|
-
#
|
132
|
+
# halt [200, {}, path] if extension == 'html'
|
107
133
|
#
|
108
134
|
# @api public
|
109
|
-
def extension
|
110
|
-
|
111
|
-
if match == detected_extension
|
112
|
-
(ext_match = env['PATH_INFO'][/\/?\.#{match}/]) ?
|
113
|
-
with_path_part(ext_match, &blk) : blk.call
|
114
|
-
end
|
115
|
-
end
|
135
|
+
def extension
|
136
|
+
detected_extension
|
116
137
|
end
|
117
138
|
alias_method :ext, :extension
|
118
|
-
chain_method :extension, :ext
|
119
139
|
|
120
140
|
# Match no extension.
|
121
141
|
#
|
@@ -124,9 +144,8 @@ module Renee
|
|
124
144
|
#
|
125
145
|
# @api public
|
126
146
|
def no_extension(&blk)
|
127
|
-
blk.call
|
147
|
+
blk.call unless detected_extension
|
128
148
|
end
|
129
|
-
chain_method :no_extension
|
130
149
|
|
131
150
|
# Match any remaining path.
|
132
151
|
#
|
@@ -135,10 +154,10 @@ module Renee
|
|
135
154
|
#
|
136
155
|
# @api public
|
137
156
|
def remainder(&blk)
|
138
|
-
with_path_part(env['PATH_INFO']) { |var| blk.call(var) }
|
157
|
+
blk ? with_path_part(env['PATH_INFO']) { |var| blk.call(var) } : create_chain_proxy(:remainder)
|
139
158
|
end
|
140
159
|
alias_method :catchall, :remainder
|
141
|
-
|
160
|
+
chainable :remainder, :catchall
|
142
161
|
|
143
162
|
# Respond to a GET request and yield the block.
|
144
163
|
#
|
@@ -146,10 +165,10 @@ module Renee
|
|
146
165
|
# get { halt [200, {}, "hello world"] }
|
147
166
|
#
|
148
167
|
# @api public
|
149
|
-
def get(
|
150
|
-
request_method('GET',
|
168
|
+
def get(&blk)
|
169
|
+
blk ? request_method('GET', &blk) : create_chain_proxy(:get)
|
151
170
|
end
|
152
|
-
|
171
|
+
chainable :get
|
153
172
|
|
154
173
|
# Respond to a POST request and yield the block.
|
155
174
|
#
|
@@ -157,10 +176,10 @@ module Renee
|
|
157
176
|
# post { halt [200, {}, "hello world"] }
|
158
177
|
#
|
159
178
|
# @api public
|
160
|
-
def post(
|
161
|
-
request_method('POST',
|
179
|
+
def post(&blk)
|
180
|
+
blk ? request_method('POST', &blk) : create_chain_proxy(:post)
|
162
181
|
end
|
163
|
-
|
182
|
+
chainable :post
|
164
183
|
|
165
184
|
# Respond to a PUT request and yield the block.
|
166
185
|
#
|
@@ -168,10 +187,10 @@ module Renee
|
|
168
187
|
# put { halt [200, {}, "hello world"] }
|
169
188
|
#
|
170
189
|
# @api public
|
171
|
-
def put(
|
172
|
-
request_method('PUT',
|
190
|
+
def put(&blk)
|
191
|
+
blk ? request_method('PUT', &blk) : create_chain_proxy(:put)
|
173
192
|
end
|
174
|
-
|
193
|
+
chainable :put
|
175
194
|
|
176
195
|
# Respond to a DELETE request and yield the block.
|
177
196
|
#
|
@@ -179,10 +198,10 @@ module Renee
|
|
179
198
|
# delete { halt [200, {}, "hello world"] }
|
180
199
|
#
|
181
200
|
# @api public
|
182
|
-
def delete(
|
183
|
-
request_method('DELETE',
|
201
|
+
def delete(&blk)
|
202
|
+
blk ? request_method('DELETE', &blk) : create_chain_proxy(:delete)
|
184
203
|
end
|
185
|
-
|
204
|
+
chainable :delete
|
186
205
|
|
187
206
|
# Match only when the path is either '' or '/'.
|
188
207
|
#
|
@@ -191,66 +210,42 @@ module Renee
|
|
191
210
|
#
|
192
211
|
# @api public
|
193
212
|
def complete(&blk)
|
194
|
-
if
|
195
|
-
with_path_part(env['PATH_INFO']) { blk.call }
|
213
|
+
if blk
|
214
|
+
with_path_part(env['PATH_INFO']) { blk.call } if complete?
|
215
|
+
else
|
216
|
+
create_chain_proxy(:complete)
|
196
217
|
end
|
197
218
|
end
|
198
|
-
|
219
|
+
chainable :complete
|
199
220
|
|
200
|
-
#
|
221
|
+
# Test if the path has been consumed
|
201
222
|
#
|
202
223
|
# @example
|
203
|
-
#
|
224
|
+
# if complete?
|
225
|
+
# halt "Hey, the path is done"
|
226
|
+
# end
|
204
227
|
#
|
205
228
|
# @api public
|
206
|
-
def
|
207
|
-
|
208
|
-
with_path_part(env['PATH_INFO']) { blk.call }
|
209
|
-
end
|
229
|
+
def complete?
|
230
|
+
(detected_extension and env['PATH_INFO'] =~ /^\/?(\.#{Regexp.quote(detected_extension)}\/?)?$/) || (detected_extension.nil? and env['PATH_INFO'] =~ /^\/?$/)
|
210
231
|
end
|
211
|
-
chain_method :empty
|
212
232
|
|
213
|
-
# Match
|
214
|
-
#
|
215
|
-
# @param [Array, Hash] q
|
216
|
-
# Either an array or hash of things to match query string variables. If given
|
217
|
-
# an array, if you pass the values for each key as parameters to the block given.
|
218
|
-
# If given a hash, then every value must be able to be matched by a registered type.
|
219
|
-
#
|
220
|
-
# @example
|
221
|
-
# query(:key => :integer) { |h| halt [200, {}, "hello world #{h[:key]}"] }
|
233
|
+
# Match only when the path is ''.
|
222
234
|
#
|
223
235
|
# @example
|
224
|
-
#
|
236
|
+
# empty { halt [200, {}, "hello world"] }
|
225
237
|
#
|
226
238
|
# @api public
|
227
|
-
def
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
239
|
+
def empty(&blk)
|
240
|
+
if blk
|
241
|
+
if env['PATH_INFO'] == ''
|
242
|
+
with_path_part(env['PATH_INFO']) { blk.call }
|
243
|
+
end
|
244
|
+
else
|
245
|
+
create_chain_proxy(:empty)
|
232
246
|
end
|
233
247
|
end
|
234
|
-
|
235
|
-
|
236
|
-
# Yield block if the query string matches.
|
237
|
-
#
|
238
|
-
# @param [String] qs
|
239
|
-
# The query string to match.
|
240
|
-
#
|
241
|
-
# @example
|
242
|
-
# path 'test' do
|
243
|
-
# query_string 'foo=bar' do
|
244
|
-
# halt [200, {}, 'matched']
|
245
|
-
# end
|
246
|
-
# end
|
247
|
-
# GET /test?foo=bar #=> 'matched'
|
248
|
-
#
|
249
|
-
# @api public
|
250
|
-
def query_string(qs, &blk)
|
251
|
-
blk.call if qs === env['QUERY_STRING']
|
252
|
-
end
|
253
|
-
chain_method :query_string
|
248
|
+
chainable :empty
|
254
249
|
|
255
250
|
private
|
256
251
|
def complex_variable(type, prefix, count)
|
@@ -306,17 +301,19 @@ module Renee
|
|
306
301
|
end
|
307
302
|
|
308
303
|
def with_path_part(part)
|
309
|
-
|
310
|
-
|
304
|
+
script_part = env['PATH_INFO'][0, part.size]
|
305
|
+
env['PATH_INFO'] = env['PATH_INFO'].slice(part.size, env['PATH_INFO'].size)
|
311
306
|
env['SCRIPT_NAME'] += script_part
|
312
307
|
yield script_part
|
313
|
-
|
308
|
+
raise NotMatchedError
|
314
309
|
end
|
315
310
|
|
316
|
-
def request_method(method
|
317
|
-
|
311
|
+
def request_method(method)
|
312
|
+
if env['REQUEST_METHOD'] == method && complete?
|
313
|
+
yield
|
314
|
+
raise NotMatchedError
|
315
|
+
end
|
318
316
|
end
|
319
|
-
chain_method :request_method
|
320
317
|
end
|
321
318
|
end
|
322
319
|
end
|