Instance methods for RodaRequest
, mostly related to handling routing for the request.
Methods
Public Class
Public Instance
Constants
TERM | = | Object.new |
Attributes
captures | [R] |
The current captures for the request. This gets modified as routing occurs. |
real_remaining_path | [R] |
The current path to match requests against. |
remaining_path | [R] |
The current path to match requests against. |
scope | [R] |
The |
Public Class methods
Store the roda instance and environment.
# File lib/roda/request.rb 84 def initialize(scope, env) 85 @scope = scope 86 @captures = [] 87 @remaining_path = _remaining_path(env) 88 @env = env 89 end
Public Instance methods
Handle match block return values. By default, if a string is given and the response is empty, use the string as the response body.
# File lib/roda/request.rb 93 def block_result(result) 94 res = response 95 if res.empty? && (body = block_result_body(result)) 96 res.write(body) 97 end 98 end
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.
# File lib/roda/request.rb 103 def get(*args, &block) 104 _verb(args, &block) if is_get? 105 end
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
# File lib/roda/request.rb 117 def halt(res=response.finish) 118 throw :halt, res 119 end
# File lib/roda/request.rb 131 def http_version 132 # Prefer SERVER_PROTOCOL as it is required in Rack 3. 133 # Still fall back to HTTP_VERSION if SERVER_PROTOCOL 134 # is not set, in case the server in use is not Rack 3 135 # compliant. 136 @env['SERVER_PROTOCOL'] || @env['HTTP_VERSION'] 137 end
Show information about current request, including request class, request method and full path.
r.inspect # => '#<Roda::RodaRequest GET /foo/bar>'
# File lib/roda/request.rb 126 def inspect 127 "#<#{self.class.inspect} #{@env["REQUEST_METHOD"]} #{path}>" 128 end
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
# File lib/roda/request.rb 192 def is(*args, &block) 193 if args.empty? 194 if empty_path? 195 always(&block) 196 end 197 else 198 args << TERM 199 if_match(args, &block) 200 end 201 end
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.
# File lib/roda/request.rb 206 def is_get? 207 @env["REQUEST_METHOD"] == 'GET' 208 end
The already matched part of the path, including the original SCRIPT_NAME.
# File lib/roda/request.rb 246 def matched_path 247 e = @env 248 e["SCRIPT_NAME"] + e["PATH_INFO"].chomp(@remaining_path) 249 end
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
# File lib/roda/request.rb 237 def on(*args, &block) 238 if args.empty? 239 always(&block) 240 else 241 if_match(args, &block) 242 end 243 end
This an an optimized version of Rack::Request#path.
r.env['SCRIPT_NAME'] = '/foo' r.env['PATH_INFO'] = '/bar' r.path # => '/foo/bar'
# File lib/roda/request.rb 257 def path 258 e = @env 259 "#{e["SCRIPT_NAME"]}#{e["PATH_INFO"]}" 260 end
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.
# File lib/roda/request.rb 272 def post(*args, &block) 273 _verb(args, &block) if post? 274 end
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
# File lib/roda/request.rb 299 def redirect(path=default_redirect_path, status=default_redirect_status) 300 response.redirect(path, status) 301 throw :halt, response.finish 302 end
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'
# File lib/roda/request.rb 310 def response 311 @scope.response 312 end
Return the Roda
class related to this request.
# File lib/roda/request.rb 315 def roda_class 316 self.class.roda_class 317 end
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.
# File lib/roda/request.rb 366 def root(&block) 367 if @remaining_path == "/" && is_get? 368 always(&block) 369 end 370 end
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.
# File lib/roda/request.rb 383 def run(app) 384 e = @env 385 path = real_remaining_path 386 sn = "SCRIPT_NAME" 387 pi = "PATH_INFO" 388 script_name = e[sn] 389 path_info = e[pi] 390 begin 391 e[sn] += path_info.chomp(path) 392 e[pi] = path 393 throw :halt, app.call(e) 394 ensure 395 e[sn] = script_name 396 e[pi] = path_info 397 end 398 end
The session for the current request. Raises a RodaError
if a session handler has not been loaded.
# File lib/roda/request.rb 402 def session 403 @env['rack.session'] || raise(RodaError, "You're missing a session handler, try using the sessions plugin.") 404 end