module Roda::RodaPlugins::Base::RequestMethods

  1. lib/roda/request.rb

Instance methods for RodaRequest, mostly related to handling routing for the request.

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 Roda instance related to this request object. Useful if routing methods need access to the scope of the Roda route block.

Public Class methods

new(scope, env)

Store the roda instance and environment.

[show source]
   # File lib/roda/request.rb
85 def initialize(scope, env)
86   @scope = scope
87   @captures = []
88   @remaining_path = _remaining_path(env)
89   @env = env
90 end

Public Instance methods

block_result(result)

Handle match block return values. By default, if a string is given and the response is empty, use the string as the response body.

[show source]
   # File lib/roda/request.rb
94 def block_result(result)
95   res = response
96   if res.empty? && (body = block_result_body(result))
97     res.write(body)
98   end
99 end
get(*args, &block)

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.

[show source]
    # File lib/roda/request.rb
104 def get(*args, &block)
105   _verb(args, &block) if is_get?
106 end
halt(res=response.finish)

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
[show source]
    # File lib/roda/request.rb
118 def halt(res=response.finish)
119   throw :halt, res
120 end
http_version()
[show source]
    # File lib/roda/request.rb
132 def http_version
133   # Prefer SERVER_PROTOCOL as it is required in Rack 3.
134   # Still fall back to HTTP_VERSION if SERVER_PROTOCOL
135   # is not set, in case the server in use is not Rack 3
136   # compliant.
137   @env['SERVER_PROTOCOL'] || @env['HTTP_VERSION']
138 end
inspect()

Show information about current request, including request class, request method and full path.

r.inspect
# => '#<Roda::RodaRequest GET /foo/bar>'
[show source]
    # File lib/roda/request.rb
127 def inspect
128   "#<#{self.class.inspect} #{@env["REQUEST_METHOD"]} #{path}>"
129 end
is(*args, &block)

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
[show source]
    # File lib/roda/request.rb
193 def is(*args, &block)
194   if args.empty?
195     if empty_path?
196       always(&block)
197     end
198   else
199     args << TERM
200     if_match(args, &block)
201   end
202 end
is_get?()

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.

[show source]
    # File lib/roda/request.rb
207 def is_get?
208   @env["REQUEST_METHOD"] == 'GET'
209 end
matched_path()

The already matched part of the path, including the original SCRIPT_NAME.

[show source]
    # File lib/roda/request.rb
247 def matched_path
248   e = @env
249   e["SCRIPT_NAME"] + e["PATH_INFO"].chomp(@remaining_path)
250 end
on(*args, &block)

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
[show source]
    # File lib/roda/request.rb
238 def on(*args, &block)
239   if args.empty?
240     always(&block)
241   else
242     if_match(args, &block)
243   end
244 end
path()

This an an optimized version of Rack::Request#path.

r.env['SCRIPT_NAME'] = '/foo'
r.env['PATH_INFO'] = '/bar'
r.path
# => '/foo/bar'
[show source]
    # File lib/roda/request.rb
258 def path
259   e = @env
260   "#{e["SCRIPT_NAME"]}#{e["PATH_INFO"]}"
261 end
post(*args, &block)

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.

[show source]
    # File lib/roda/request.rb
273 def post(*args, &block)
274   _verb(args, &block) if post?
275 end
redirect(path=default_redirect_path, status=default_redirect_status)

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
[show source]
    # File lib/roda/request.rb
300 def redirect(path=default_redirect_path, status=default_redirect_status)
301   response.redirect(path, status)
302   throw :halt, response.finish
303 end
response()

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'
[show source]
    # File lib/roda/request.rb
311 def response
312   @scope.response
313 end
roda_class()

Return the Roda class related to this request.

[show source]
    # File lib/roda/request.rb
316 def roda_class
317   self.class.roda_class
318 end
root(&block)

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.

[show source]
    # File lib/roda/request.rb
367 def root(&block)
368   if @remaining_path == "/" && is_get?
369     always(&block)
370   end
371 end
run(app)

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.

[show source]
    # File lib/roda/request.rb
384 def run(app)
385   e = @env
386   path = real_remaining_path
387   sn = "SCRIPT_NAME"
388   pi = "PATH_INFO"
389   script_name = e[sn]
390   path_info = e[pi]
391   begin
392     e[sn] += path_info.chomp(path)
393     e[pi] = path
394     throw :halt, app.call(e)
395   ensure
396     e[sn] = script_name
397     e[pi] = path_info
398   end
399 end
session()

The session for the current request. Raises a RodaError if a session handler has not been loaded.

[show source]
    # File lib/roda/request.rb
403 def session
404   @env['rack.session'] || raise(RodaError, "You're missing a session handler, try using the sessions plugin.")
405 end