Module: Roda::RodaPlugins::Base::RequestMethods
- Defined in:
- lib/roda/request.rb
Overview
Instance methods for RodaRequest, mostly related to handling routing for the request.
Constant Summary collapse
- TERM =
Object.new
Instance Attribute Summary collapse
-
#captures ⇒ Object
readonly
The current captures for the request.
-
#remaining_path ⇒ Object
(also: #real_remaining_path)
readonly
The current path to match requests against.
-
#scope ⇒ Object
readonly
The Roda instance related to this request object.
Instance Method Summary collapse
-
#block_result(result) ⇒ Object
Handle match block return values.
-
#get(*args, &block) ⇒ Object
Match GET requests.
-
#halt(res = response.finish) ⇒ Object
Immediately stop execution of the route block and return the given rack response array of status, headers, and body.
-
#http_version ⇒ Object
What HTTP version the request was submitted with.
-
#initialize(scope, env) ⇒ Object
Store the roda instance and environment.
-
#inspect ⇒ Object
Show information about current request, including request class, request method and full path.
-
#is(*args, &block) ⇒ Object
Does a terminal match on the current path, matching only if the arguments have fully matched the path.
-
#is_get? ⇒ Boolean
Optimized method for whether this request is a
GETrequest. -
#matched_path ⇒ Object
The already matched part of the path, including the original SCRIPT_NAME.
-
#on(*args, &block) ⇒ Object
Does a match on the path, matching only if the arguments have matched the path.
-
#path ⇒ Object
This an an optimized version of Rack::Request#path.
-
#post(*args, &block) ⇒ Object
Match POST requests.
-
#redirect(path = default_redirect_path, status = default_redirect_status) ⇒ Object
Immediately redirect to the path using the status code.
-
#response ⇒ Object
The response related to the current request.
-
#roda_class ⇒ Object
Return the Roda class related to this request.
-
#root(&block) ⇒ Object
Match method that only matches
GETrequests where the current path is/. -
#run(app) ⇒ Object
Call the given rack app with the environment and return the response from the rack app as the response for this request.
-
#session ⇒ Object
The session for the current request.
Instance Attribute Details
#captures ⇒ Object (readonly)
The current captures for the request. This gets modified as routing occurs.
79 80 81 |
# File 'lib/roda/request.rb', line 79 def captures @captures end |
#remaining_path ⇒ Object (readonly) Also known as: real_remaining_path
The current path to match requests against.
267 268 269 |
# File 'lib/roda/request.rb', line 267 def remaining_path @remaining_path end |
#scope ⇒ Object (readonly)
The Roda instance related to this request object. Useful if routing methods need access to the scope of the Roda route block.
83 84 85 |
# File 'lib/roda/request.rb', line 83 def scope @scope end |
Instance Method Details
#block_result(result) ⇒ Object
Handle match block return values. By default, if a string is given and the response is empty, use the string as the response body.
95 96 97 98 99 100 |
# File 'lib/roda/request.rb', line 95 def block_result(result) res = response if res.empty? && (body = block_result_body(result)) res.write(body) end end |
#get(*args, &block) ⇒ Object
Match GET requests. If no arguments are provided, matches all GET requests, otherwise, matches only GET requests where the arguments given fully consume the path.
105 106 107 |
# File 'lib/roda/request.rb', line 105 def get(*args, &block) _verb(args, &block) if is_get? end |
#halt(res = response.finish) ⇒ Object
Immediately stop execution of the route block and return the given rack response array of status, headers, and body. If no argument is given, uses the current response.
r.halt [200, {'Content-Type'=>'text/html'}, ['Hello World!']]
response.status = 200
response['Content-Type'] = 'text/html'
response.write 'Hello World!'
r.halt
119 120 121 |
# File 'lib/roda/request.rb', line 119 def halt(res=response.finish) throw :halt, res end |
#http_version ⇒ Object
What HTTP version the request was submitted with.
144 145 146 147 148 149 150 |
# File 'lib/roda/request.rb', line 144 def http_version # Prefer SERVER_PROTOCOL as it is required in Rack 3. # Still fall back to HTTP_VERSION if SERVER_PROTOCOL # is not set, in case the server in use is not Rack 3 # compliant. @env['SERVER_PROTOCOL'] || @env['HTTP_VERSION'] end |
#initialize(scope, env) ⇒ Object
Store the roda instance and environment.
86 87 88 89 90 91 |
# File 'lib/roda/request.rb', line 86 def initialize(scope, env) @scope = scope @captures = [] @remaining_path = _remaining_path(env) @env = env end |
#inspect ⇒ Object
Show information about current request, including request class, request method and full path.
r.inspect
# => '#<Roda::RodaRequest GET /foo/bar>'
128 129 130 |
# File 'lib/roda/request.rb', line 128 def inspect "#<#{self.class.inspect} #{@env["REQUEST_METHOD"]} #{path}>" end |
#is(*args, &block) ⇒ Object
Does a terminal match on the current path, matching only if the arguments have fully matched the path. If it matches, the match block is executed, and when the match block returns, the rack response is returned.
r.remaining_path
# => "/foo/bar"
r.is 'foo' do
# does not match, as path isn't fully matched (/bar remaining)
end
r.is 'foo/bar' do
# matches as path is empty after matching
end
If no arguments are given, matches if the path is already fully matched.
r.on 'foo/bar' do
r.is do
# matches as path is already empty
end
end
Note that this matches only if the path after matching the arguments is empty, not if it still contains a trailing slash:
r.remaining_path
# => "/foo/bar/"
r.is 'foo/bar' do
# does not match, as path isn't fully matched (/ remaining)
end
r.is 'foo/bar/' do
# matches as path is empty after matching
end
r.on 'foo/bar' do
r.is "" do
# matches as path is empty after matching
end
end
196 197 198 199 200 201 202 203 204 205 |
# File 'lib/roda/request.rb', line 196 def is(*args, &block) if args.empty? if empty_path? always(&block) end else args << TERM if_match(args, &block) end end |
#is_get? ⇒ Boolean
Optimized method for whether this request is a GET request. Similar to the default Rack::Request get? method, but can be overridden without changing rack's behavior.
210 211 212 |
# File 'lib/roda/request.rb', line 210 def is_get? @env["REQUEST_METHOD"] == 'GET' end |
#matched_path ⇒ Object
The already matched part of the path, including the original SCRIPT_NAME.
250 251 252 253 |
# File 'lib/roda/request.rb', line 250 def matched_path e = @env e["SCRIPT_NAME"] + e["PATH_INFO"].chomp(@remaining_path) end |
#on(*args, &block) ⇒ Object
Does a match on the path, matching only if the arguments have matched the path. Because this doesn't fully match the path, this is usually used to setup branches of the routing tree, not for final handling of the request.
r.remaining_path
# => "/foo/bar"
r.on 'foo' do
# matches, path is /bar after matching
end
r.on 'bar' do
# does not match
end
Like other routing methods, If it matches, the match block is executed, and when the match block returns, the rack response is returned. However, in general you will call another routing method inside the match block that fully matches the path and does the final handling for the request:
r.on 'foo' do
r.is 'bar' do
# handle /foo/bar request
end
end
241 242 243 244 245 246 247 |
# File 'lib/roda/request.rb', line 241 def on(*args, &block) if args.empty? always(&block) else if_match(args, &block) end end |
#path ⇒ Object
This an an optimized version of Rack::Request#path.
r.env['SCRIPT_NAME'] = '/foo'
r.env['PATH_INFO'] = '/bar'
r.path
# => '/foo/bar'
261 262 263 264 |
# File 'lib/roda/request.rb', line 261 def path e = @env "#{e["SCRIPT_NAME"]}#{e["PATH_INFO"]}" end |
#post(*args, &block) ⇒ Object
Match POST requests. If no arguments are provided, matches all POST requests, otherwise, matches only POST requests where the arguments given fully consume the path.
276 277 278 |
# File 'lib/roda/request.rb', line 276 def post(*args, &block) _verb(args, &block) if post? end |
#redirect(path = default_redirect_path, status = default_redirect_status) ⇒ Object
Immediately redirect to the path using the status code. This ends the processing of the request:
r.redirect '/page1', 301 if r['param'] == 'value1'
r.redirect '/page2' # uses 302 status code
response.status = 404 # not reached
If you do not provide a path, by default it will redirect to the same path if the request is not a GET request. This is designed to make it easy to use where a POST request to a URL changes state, GET returns the current state, and you want to show the current state after changing:
r.is "foo" do
r.get do
# show state
end
r.post do
# change state
r.redirect
end
end
303 304 305 306 |
# File 'lib/roda/request.rb', line 303 def redirect(path=default_redirect_path, status=default_redirect_status) response.redirect(path, status) throw :halt, response.finish end |
#response ⇒ Object
The response related to the current request. See ResponseMethods for instance methods for the response, but in general the most common usage is to override the response status and headers:
response.status = 200
response['Header-Name'] = 'Header value'
314 315 316 |
# File 'lib/roda/request.rb', line 314 def response @scope.response end |
#roda_class ⇒ Object
Return the Roda class related to this request.
319 320 321 |
# File 'lib/roda/request.rb', line 319 def roda_class self.class.roda_class end |
#root(&block) ⇒ Object
Match method that only matches GET requests where the current path is /. If it matches, the match block is executed, and when the match block returns, the rack response is returned.
[r.request_method, r.remaining_path]
# => ['GET', '/']
r.root do
# matches
end
This is usuable inside other match blocks:
[r.request_method, r.remaining_path]
# => ['GET', '/foo/']
r.on 'foo' do
r.root do
# matches
end
end
Note that this does not match non-GET requests:
[r.request_method, r.remaining_path]
# => ['POST', '/']
r.root do
# does not match
end
Use r.post "" for POST requests where the current path is /.
Nor does it match empty paths:
[r.request_method, r.remaining_path]
# => ['GET', '/foo']
r.on 'foo' do
r.root do
# does not match
end
end
Use r.get true to handle GET requests where the current path is empty.
370 371 372 373 374 |
# File 'lib/roda/request.rb', line 370 def root(&block) if @remaining_path == "/" && is_get? always(&block) end end |
#run(app) ⇒ Object
Call the given rack app with the environment and return the response from the rack app as the response for this request. This ends the processing of the request:
r.run(proc{[403, {}, []]}) unless r['letmein'] == '1'
r.run(proc{[404, {}, []]})
response.status = 404 # not reached
This updates SCRIPT_NAME/PATH_INFO based on the current remaining_path before dispatching to another rack app, so the app still works as a URL mapper.
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
# File 'lib/roda/request.rb', line 387 def run(app) e = @env path = real_remaining_path sn = "SCRIPT_NAME" pi = "PATH_INFO" script_name = e[sn] path_info = e[pi] begin e[sn] += path_info.chomp(path) e[pi] = path throw :halt, app.call(e) ensure e[sn] = script_name e[pi] = path_info end end |
#session ⇒ Object
The session for the current request. Raises a RodaError if a session handler has not been loaded.
406 407 408 |
# File 'lib/roda/request.rb', line 406 def session @env['rack.session'] || raise(RodaError, "You're missing a session handler, try using the sessions plugin.") end |