diff --git a/documentation.html b/documentation.html index b7fb31eb..d01d5e1b 100644 --- a/documentation.html +++ b/documentation.html @@ -21,7 +21,7 @@
-

Documentation for Roda (v3.78.0)

+

Documentation for Roda (v3.79.0)

README (Introduction to Roda, start here if new)

@@ -62,6 +62,7 @@

Plugins that Ship with Roda

  • hash_paths: Supports O(1) dispatching to multiple paths at all levels in the routing tree.
  • hash_routes: Provides a DSL to configure the hash_branches and hash_paths plugins.
  • head: Treat HEAD requests like GET requests with an empty response body.
  • +
  • hmac_paths: Prevent path enumeration and support access control using HMACs in paths.
  • hooks: Adds before/after hook methods.
  • match_hook: Adds a hook method which is called when a path segment is matched.
  • match_hook_args: Similar to match_hook plugin, but supports passing matchers and block args to hooks.
  • @@ -251,7 +252,7 @@

    Release Notes

  • - 3.78 | 3.77 | 3.76 | 3.75 | 3.74 | 3.73 | 3.72 | 3.71 | 3.70 + 3.79 | 3.78 | 3.77 | 3.76 | 3.75 | 3.74 | 3.73 | 3.72 | 3.71 | 3.70
  • diff --git a/index.html b/index.html index 00e5ac55..907d41df 100644 --- a/index.html +++ b/index.html @@ -104,7 +104,7 @@

    A Modular, Scalable Ruby Framework

  • Simple, Reliable API -

    Currently at version 3.78.0

    +

    Currently at version 3.79.0

  • diff --git a/rdoc/classes/Roda.html b/rdoc/classes/Roda.html index 8301de39..b7a2faa1 100644 --- a/rdoc/classes/Roda.html +++ b/rdoc/classes/Roda.html @@ -209,6 +209,9 @@

    class lib/roda/plugins/heartbeat.rb

  • +lib/roda/plugins/hmac_paths.rb +
  • +
  • lib/roda/plugins/hooks.rb
  • @@ -486,7 +489,7 @@

    Constants

    RodaMinorVersion = -78 +79  

    The minor version of Roda, updated for new feature releases of Roda.

    diff --git a/rdoc/classes/Roda/RodaPlugins.html b/rdoc/classes/Roda/RodaPlugins.html index 2d3f4380..b1fdff05 100644 --- a/rdoc/classes/Roda/RodaPlugins.html +++ b/rdoc/classes/Roda/RodaPlugins.html @@ -206,6 +206,9 @@

    module lib/roda/plugins/heartbeat.rb

  • +lib/roda/plugins/hmac_paths.rb +
  • +
  • lib/roda/plugins/hooks.rb
  • @@ -514,6 +517,7 @@

    Classes and Modules

  • Roda::RodaPlugins::Head
  • Roda::RodaPlugins::HeaderMatchers
  • Roda::RodaPlugins::Heartbeat
  • +
  • Roda::RodaPlugins::HmacPaths
  • Roda::RodaPlugins::Hooks
  • Roda::RodaPlugins::HostAuthorization
  • Roda::RodaPlugins::IndifferentParams
  • diff --git a/rdoc/classes/Roda/RodaPlugins/HmacPaths.html b/rdoc/classes/Roda/RodaPlugins/HmacPaths.html new file mode 100644 index 00000000..99315979 --- /dev/null +++ b/rdoc/classes/Roda/RodaPlugins/HmacPaths.html @@ -0,0 +1,197 @@ + + + +Roda::RodaPlugins::HmacPaths + + + + + + +
    +
    +

    module +Roda::RodaPlugins::HmacPaths +

    +
      +
    1. +lib/roda/plugins/hmac_paths.rb +
    2. +
    +
    +
    +
    +
    +

    The hmac_paths plugin allows protection of paths using an HMAC. This can be used to prevent users enumerating paths, since only paths with valid HMACs will be respected.

    + +

    To use the plugin, you must provide a secret option. This sets the secret for the HMACs. Make sure to keep this value secret, as this plugin does not provide protection against users who know the secret value. The secret must be at least 32 bytes.

    + +
    plugin :hmac_paths, secret: 'some-secret-value-with-at-least-32-bytes'
    +
    + +

    To generate a valid HMAC path, you call the hmac_path method:

    + +
    hmac_path('/widget/1')
    +# => "/0c2feaefdfc80cc73da19b060c713d4193c57022815238c6657ce2d99b5925eb/0/widget/1"
    +
    + +

    The first segment in the returned path is the HMAC. The second segment is flags for the type of paths (see below), and the rest of the path is as given.

    + +

    To protect a path or any subsection in the routing tree, you wrap the related code in an r.hmac_path block.

    + +
    route do |r|
    +  r.hmac_path do
    +    r.get 'widget', Integer do |widget_id|
    +      # ...
    +    end
    +  end
    +end
    +
    + +

    If first segment of the remaining path contains a valid HMAC for the rest of the path (considering the flags), then r.hmac_path will match and yield to the block, and routing continues inside the block with the HMAC and flags segments removed.

    + +

    In the above example, if you provide a user a link for widget with ID 1, there is no way for them to guess the valid path for the widget with ID 2, preventing a user from enumerating widgets, without relying on custom access control. Users can only access paths that have been generated by the application and provided to them, either directly or indirectly.

    + +

    In the above example, r.hmac_path is used at the root of the routing tree. If you would like to call it below the root of the routing tree, it works correctly, but you must pass hmac_path the :root option specifying where r.hmac_paths will be called from. Consider this example:

    + +
    route do |r|
    +  r.on 'widget' do
    +    r.hmac_path do
    +      r.get Integer do |widget_id|
    +        # ...
    +      end
    +    end
    +  end
    +
    +  r.on 'foobar' do
    +    r.hmac_path do
    +      r.get Integer do |foobar_id|
    +        # ...
    +      end
    +    end
    +  end
    +end
    +
    + +

    For security reasons, the hmac_path plugin does not allow an HMAC path designed for widgets to be a valid match in the r.hmac_path call inside the r.on 'foobar' block, preventing users who have a valid HMAC for a widget from looking at the page for a foobar with the same ID. When generating HMAC paths where the matching r.hmac_path call is not at the root of the routing tree, you must pass the :root option:

    + +
    hmac_path('/1', root: '/widget')
    +# => "/widget/daccafce3ce0df52e5ce774626779eaa7286085fcbde1e4681c74175ff0bbacd/0/1"
    +
    +hmac_path('/1', root: '/foobar')
    +# => "/foobar/c5fdaf482771d4f9f38cc13a1b2832929026a4ceb05e98ed6a0cd5a00bf180b7/0/1"
    +
    + +

    Note how the HMAC changes even though the path is the same.

    + +

    In addition to the :root option, there are additional options that further constrain use of the generated paths.

    + +

    The :method option creates a path that can only be called with a certain request method:

    + +
    hmac_path('/widget/1', method: :get)
    +# => "/d38c1e634ecf9a3c0ab9d0832555b035d91b35069efcbf2670b0dfefd4b62fdd/m/widget/1"
    +
    + +

    Note how this results in a different HMAC than the original hmac_path('/widget/1') call. This sets the flags segment to m, which means r.hmac_path will consider the request mehod when checking the HMAC, and will only match if the provided request method is GET. This allows you to provide a user the ability to submit a GET request for the underlying path, without providing them the ability to submit a POST request for the underlying path, with no other access control.

    + +

    The :params option accepts a hash of params, converts it into a query string, and includes the query string in the returned path. It sets the flags segment to p, which means r.hmac_path will check for that exact query string. Requests with an empty query string or a different string will not match.

    + +
    hmac_path('/widget/1', params: {foo: 'bar'})
    +# => "/fe8d03f9572d5af6c2866295bd3c12c2ea11d290b1cbd016c3b68ee36a678139/p/widget/1?foo=bar"
    +
    + +

    For GET requests, which cannot have request bodies, that is sufficient to ensure that the submitted params are exactly as specified. However, POST requests can have request bodies, and request body params override query string params in r.params. So if you are using this for POST requests (or other HTTP verbs that can have request bodies), use r.GET instead of r.params to specifically check query string parameters.

    + +

    You can use :root, :method, and :params at the same time:

    + +
    hmac_path('/1', root: '/widget', method: :get, params: {foo: 'bar'})
    +# => "/widget/9169af1b8f40c62a1c2bb15b1b377c65bda681b8efded0e613a4176387468c15/mp/1?foo=bar"
    +
    + +

    This gives you a path only valid for a GET request with a root of /widget and a query string of foo=bar.

    + +

    To handle secret rotation, you can provide an :old_secret option when loading the plugin.

    + +
    plugin :hmac_paths, secret: 'some-secret-value-with-at-least-32-bytes',
    +                    old_secret: 'previous-secret-value-with-at-least-32-bytes'
    +
    + +

    This will use :secret for constructing new paths, but will respect paths generated by :old_secret.

    +
    +
    +

    Methods

    +

    Public Class

    +
      +
    1. configure
    2. +
    +
    +
    +
    + +
    +
    +

    Public Class methods

    +
    + +
    +configure(app, opts=OPTS) + +
    +
    + +
    +
    + +[show source] + +
        # File lib/roda/plugins/hmac_paths.rb
    +132 def self.configure(app, opts=OPTS)
    +133   hmac_secret = opts[:secret]
    +134   unless hmac_secret.is_a?(String) && hmac_secret.bytesize >= 32
    +135     raise RodaError, "hmac_paths plugin :secret option must be a string containing at least 32 bytes"
    +136   end
    +137 
    +138   if hmac_old_secret = opts[:old_secret]
    +139     unless hmac_old_secret.is_a?(String) && hmac_old_secret.bytesize >= 32
    +140       raise RodaError, "hmac_paths plugin :old_secret option must be a string containing at least 32 bytes if present"
    +141     end
    +142   end
    +143 
    +144   app.opts[:hmac_paths_secret] = hmac_secret
    +145   app.opts[:hmac_paths_old_secret] = hmac_old_secret
    +146 end
    +
    +
    +
    +
    + +
    +
    + + +
    + + + diff --git a/rdoc/classes/Roda/RodaPlugins/HmacPaths/InstanceMethods.html b/rdoc/classes/Roda/RodaPlugins/HmacPaths/InstanceMethods.html new file mode 100644 index 00000000..d68e0697 --- /dev/null +++ b/rdoc/classes/Roda/RodaPlugins/HmacPaths/InstanceMethods.html @@ -0,0 +1,142 @@ + + + +Roda::RodaPlugins::HmacPaths::InstanceMethods + + + + + + +
    +
    +

    module +Roda::RodaPlugins::HmacPaths::InstanceMethods +

    +
      +
    1. +lib/roda/plugins/hmac_paths.rb +
    2. +
    +
    +
    +
    +
    +
    +

    Methods

    +

    Public Instance

    +
      +
    1. hmac_path
    2. +
    3. hmac_path_hmac
    4. +
    +
    +
    +
    +
    +
    +

    Public Instance methods

    +
    + +
    +hmac_path(path, opts=OPTS) + +
    +
    + +

    Return a path with an HMAC. Designed to be used with r.hmac_path, to make sure users can only request paths that they have been provided by the application (directly or indirectly). This can prevent users of a site from enumerating valid paths. The given path should be a string starting with /. Options:

    +
    :method +

    Limits the returned path to only be valid for the given request method.

    +
    :params +

    Includes parameters in the query string of the returned path, and limits the returned path to only be valid for that exact query string.

    +
    :root +

    Should be an empty string or string starting with /. This will be the already matched path of the routing tree using r.hmac_path. Defaults to the empty string, which will returns paths valid for r.hmac_path at the top level of the routing tree.

    +
    + +
    +
    + +[show source] + +
        # File lib/roda/plugins/hmac_paths.rb
    +161 def hmac_path(path, opts=OPTS)
    +162   unless path.is_a?(String) && path.getbyte(0) == 47
    +163     raise RodaError, "path must be a string starting with /"
    +164   end
    +165 
    +166   root = opts[:root] || ''
    +167   unless root.is_a?(String) && ((root_byte = root.getbyte(0)) == 47 || root_byte == nil)
    +168     raise RodaError, "root must be empty string or string starting with /"
    +169   end
    +170 
    +171   flags = String.new
    +172   path = path.dup
    +173 
    +174   if method = opts[:method]
    +175     flags << 'm'
    +176   end
    +177 
    +178   if params = opts[:params]
    +179     flags << 'p'
    +180     path << '?' << Rack::Utils.build_query(params)
    +181   end
    +182 
    +183   flags << '0' if flags.empty?
    +184   
    +185   hmac_path = if method
    +186     "#{method.to_s.upcase}:/#{flags}#{path}"
    +187   else
    +188     "/#{flags}#{path}"
    +189   end
    +190 
    +191   "#{root}/#{hmac_path_hmac(root, hmac_path)}/#{flags}#{path}"
    +192 end
    +
    +
    +
    + +
    +hmac_path_hmac(root, path, opts=OPTS) + +
    +
    + +

    The HMAC to use in hmac_path, for the given root, path, and options.

    + +
    +
    + +[show source] + +
        # File lib/roda/plugins/hmac_paths.rb
    +195 def hmac_path_hmac(root, path, opts=OPTS)
    +196   OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, hmac_path_hmac_secret(root, opts), path)
    +197 end
    +
    +
    +
    +
    + +
    +
    + + +
    + + + diff --git a/rdoc/classes/Roda/RodaPlugins/HmacPaths/RequestMethods.html b/rdoc/classes/Roda/RodaPlugins/HmacPaths/RequestMethods.html new file mode 100644 index 00000000..38c47172 --- /dev/null +++ b/rdoc/classes/Roda/RodaPlugins/HmacPaths/RequestMethods.html @@ -0,0 +1,115 @@ + + + +Roda::RodaPlugins::HmacPaths::RequestMethods + + + + + + +
    +
    +

    module +Roda::RodaPlugins::HmacPaths::RequestMethods +

    +
      +
    1. +lib/roda/plugins/hmac_paths.rb +
    2. +
    +
    +
    +
    +
    +
    +

    Methods

    +

    Public Instance

    +
      +
    1. hmac_path
    2. +
    +
    +
    +
    +
    +
    +

    Public Instance methods

    +
    + +
    +hmac_path(opts=OPTS, &block) + +
    +
    + +

    Looks at the first segment of the remaining path, and if it contains a valid HMAC for the rest of the path considering the flags in the second segment and the given options, the block matches and is yielded to, and the result of the block is returned. Otherwise, the block does not matches and routing continues after the call.

    + +
    +
    + +[show source] + +
        # File lib/roda/plugins/hmac_paths.rb
    +214 def hmac_path(opts=OPTS, &block)
    +215   orig_path = remaining_path
    +216   mpath = matched_path
    +217 
    +218   on String do |submitted_hmac|
    +219     rpath = remaining_path
    +220 
    +221     if submitted_hmac.bytesize == 64
    +222       on String do |flags|
    +223         if flags.bytesize >= 1
    +224           if flags.include?('m')
    +225             rpath = "#{env['REQUEST_METHOD'].to_s.upcase}:#{rpath}"
    +226           end
    +227 
    +228           if flags.include?('p')
    +229             rpath = "#{rpath}?#{env["QUERY_STRING"]}"
    +230           end
    +231 
    +232           if hmac_path_valid?(mpath, rpath, submitted_hmac)
    +233             always(&block)
    +234           end
    +235         end
    +236 
    +237         # Return from method without matching
    +238         @remaining_path = orig_path
    +239         return
    +240       end
    +241     end
    +242 
    +243     # Return from method without matching
    +244     @remaining_path = orig_path
    +245     return
    +246   end
    +247 end
    +
    +
    +
    +
    + +
    +
    + + +
    + + + diff --git a/rdoc/classes/Roda/RodaPlugins/Render/ClassMethods.html b/rdoc/classes/Roda/RodaPlugins/Render/ClassMethods.html index 16ddaecf..0bd587ec 100644 --- a/rdoc/classes/Roda/RodaPlugins/Render/ClassMethods.html +++ b/rdoc/classes/Roda/RodaPlugins/Render/ClassMethods.html @@ -68,9 +68,9 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -441 def create_template(opts, template_opts)
    -442   opts[:template_class].new(opts[:path], 1, template_opts, &opts[:template_block])
    -443 end
    +445 def create_template(opts, template_opts) +446 opts[:template_class].new(opts[:path], 1, template_opts, &opts[:template_block]) +447 end
    @@ -89,18 +89,18 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -426 def freeze
    -427   begin
    -428     _freeze_layout_method
    -429   rescue
    -430     # This is only for optimization, if any errors occur, they can be ignored.
    -431     # One possibility for error is the app doesn't use a layout, but doesn't
    -432     # specifically set the :layout=>false plugin option.
    -433     nil
    -434   end
    -435 
    -436   super
    -437 end
    +430 def freeze +431 begin +432 _freeze_layout_method +433 rescue +434 # This is only for optimization, if any errors occur, they can be ignored. +435 # One possibility for error is the app doesn't use a layout, but doesn't +436 # specifically set the :layout=>false plugin option. +437 nil +438 end +439 +440 super +441 end
    @@ -119,15 +119,15 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -454 def inherited(subclass)
    -455   super
    -456   opts = subclass.opts[:render] = subclass.opts[:render].dup
    -457   if COMPILED_METHOD_SUPPORT
    -458     opts[:template_method_cache] = (opts[:cache_class] || RodaCache).new
    -459   end
    -460   opts[:cache] = opts[:cache].dup
    -461   opts.freeze
    -462 end
    +458 def inherited(subclass) +459 super +460 opts = subclass.opts[:render] = subclass.opts[:render].dup +461 if COMPILED_METHOD_SUPPORT +462 opts[:template_method_cache] = (opts[:cache_class] || RodaCache).new +463 end +464 opts[:cache] = opts[:cache].dup +465 opts.freeze +466 end
    @@ -146,9 +146,9 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -447 def inline_template_block(content)
    -448   Proc.new{content}
    -449 end
    +451 def inline_template_block(content) +452 Proc.new{content} +453 end
    @@ -167,9 +167,9 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -465 def render_opts
    -466   opts[:render]
    -467 end
    +469 def render_opts +470 opts[:render] +471 end
    diff --git a/rdoc/classes/Roda/RodaPlugins/Render/InstanceMethods.html b/rdoc/classes/Roda/RodaPlugins/Render/InstanceMethods.html index 3381b283..4ac3c19f 100644 --- a/rdoc/classes/Roda/RodaPlugins/Render/InstanceMethods.html +++ b/rdoc/classes/Roda/RodaPlugins/Render/InstanceMethods.html @@ -66,16 +66,16 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -493 def render(template, opts = (no_opts = true; optimized_template = _cached_template_method(template); OPTS), &block)
    -494   if optimized_template
    -495     send(optimized_template, OPTS, &block)
    -496   elsif !no_opts && opts.length == 1 && (locals = opts[:locals]) && (optimized_template = _optimized_render_method_for_locals(template, locals))
    -497     send(optimized_template, locals, &block)
    -498   else
    -499     opts = render_template_opts(template, opts)
    -500     retrieve_template(opts).render((opts[:scope]||self), (opts[:locals]||OPTS), &block)
    -501   end
    -502 end
    +497 def render(template, opts = (no_opts = true; optimized_template = _cached_template_method(template); OPTS), &block) +498 if optimized_template +499 send(optimized_template, OPTS, &block) +500 elsif !no_opts && opts.length == 1 && (locals = opts[:locals]) && (optimized_template = _optimized_render_method_for_locals(template, locals)) +501 send(optimized_template, locals, &block) +502 else +503 opts = render_template_opts(template, opts) +504 retrieve_template(opts).render((opts[:scope]||self), (opts[:locals]||OPTS), &block) +505 end +506 end
    @@ -94,9 +94,9 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -505 def render_opts
    -506   self.class.render_opts
    -507 end
    +509 def render_opts +510 self.class.render_opts +511 end
    @@ -115,35 +115,35 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -514 def view(template, opts = (content = _optimized_view_content(template) unless defined?(yield); OPTS), &block)
    -515   if content
    -516     # First, check if the optimized layout method has already been created,
    -517     # and use it if so.  This way avoids the extra conditional and local variable
    -518     # assignments in the next section.
    -519     if layout_method = _layout_method
    -520       return send(layout_method, OPTS){content}
    -521     end
    -522 
    -523     # If we have an optimized template method but no optimized layout method, create the
    -524     # optimized layout method if possible and use it.  If you can't create the optimized
    -525     # layout method, fall through to the slower approach.
    -526     if layout_template = self.class.opts[:render][:optimize_layout]
    -527       retrieve_template(:template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
    -528       if layout_method = _layout_method
    -529         return send(layout_method, OPTS){content}
    -530       end
    -531     end
    -532   else
    -533     opts = parse_template_opts(template, opts)
    -534     content = opts[:content] || render_template(opts, &block)
    -535   end
    -536 
    -537   if layout_opts  = view_layout_opts(opts)
    -538     content = render_template(layout_opts){content}
    +518 def view(template, opts = (content = _optimized_view_content(template) unless defined?(yield); OPTS), &block)
    +519   if content
    +520     # First, check if the optimized layout method has already been created,
    +521     # and use it if so.  This way avoids the extra conditional and local variable
    +522     # assignments in the next section.
    +523     if layout_method = _layout_method
    +524       return send(layout_method, OPTS){content}
    +525     end
    +526 
    +527     # If we have an optimized template method but no optimized layout method, create the
    +528     # optimized layout method if possible and use it.  If you can't create the optimized
    +529     # layout method, fall through to the slower approach.
    +530     if layout_template = self.class.opts[:render][:optimize_layout]
    +531       retrieve_template(:template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
    +532       if layout_method = _layout_method
    +533         return send(layout_method, OPTS){content}
    +534       end
    +535     end
    +536   else
    +537     opts = parse_template_opts(template, opts)
    +538     content = opts[:content] || render_template(opts, &block)
     539   end
     540 
    -541   content
    -542 end
    +541 if layout_opts = view_layout_opts(opts) +542 content = render_template(layout_opts){content} +543 end +544 +545 content +546 end
    diff --git a/rdoc/classes/Roda/RodaPlugins/Render/TemplateMtimeWrapper.html b/rdoc/classes/Roda/RodaPlugins/Render/TemplateMtimeWrapper.html index 5c7b7b67..e3525231 100644 --- a/rdoc/classes/Roda/RodaPlugins/Render/TemplateMtimeWrapper.html +++ b/rdoc/classes/Roda/RodaPlugins/Render/TemplateMtimeWrapper.html @@ -53,7 +53,7 @@

    Public Instance

  • compiled_method
  • compiled_method_lambda
  • define_compiled_method
  • -
  • modified?
  • +
  • if_modified
  • render
  • template_last_modified
  • @@ -107,15 +107,15 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -393 def compiled_method(locals_keys=EMPTY_ARRAY, roda_class=nil)
    -394   Render.tilt_template_compiled_method(@template, locals_keys, roda_class)
    -395 end
    +396 def compiled_method(locals_keys=EMPTY_ARRAY, roda_class=nil) +397 Render.tilt_template_compiled_method(@template, locals_keys, roda_class) +398 end
    -compiled_method_lambda(template, roda_class, method_name, locals_keys=EMPTY_ARRAY) +compiled_method_lambda(roda_class, method_name, locals_keys=EMPTY_ARRAY)
    @@ -128,17 +128,18 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -400 def compiled_method_lambda(template, roda_class, method_name, locals_keys=EMPTY_ARRAY)
    -401   mod = roda_class::RodaCompiledTemplates
    -402   lambda do |locals, &block|
    -403     if template.modified?
    -404       mod.send(:define_method, method_name, Render.tilt_template_compiled_method(template, locals_keys, roda_class))
    -405       mod.send(:private, method_name)
    -406     end
    -407 
    -408     send(method_name, locals, &block)
    -409   end
    -410 end
    +403 def compiled_method_lambda(roda_class, method_name, locals_keys=EMPTY_ARRAY) +404 mod = roda_class::RodaCompiledTemplates +405 template = self +406 lambda do |locals, &block| +407 template.if_modified do +408 mod.send(:define_method, method_name, Render.tilt_template_compiled_method(template, locals_keys, roda_class)) +409 mod.send(:private, method_name) +410 end +411 +412 send(method_name, locals, &block) +413 end +414 end
    @@ -157,27 +158,27 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -374 def define_compiled_method(roda_class, method_name, locals_keys=EMPTY_ARRAY)
    -375   mod = roda_class::RodaCompiledTemplates
    -376   internal_method_name = :"_#{method_name}"
    -377   begin
    -378     mod.send(:define_method, internal_method_name, send(:compiled_method, locals_keys, roda_class))
    -379   rescue ::NotImplementedError
    -380     return false
    -381   end
    -382 
    -383   mod.send(:private, internal_method_name)
    -384   mod.send(:define_method, method_name, &compiled_method_lambda(self, roda_class, internal_method_name, locals_keys))
    -385   mod.send(:private, method_name)
    -386 
    -387   method_name
    -388 end
    -
    - -
    - +377 def define_compiled_method(roda_class, method_name, locals_keys=EMPTY_ARRAY) +378 mod = roda_class::RodaCompiledTemplates +379 internal_method_name = :"_#{method_name}" +380 begin +381 mod.send(:define_method, internal_method_name, compiled_method(locals_keys, roda_class)) +382 rescue ::NotImplementedError +383 return false +384 end +385 +386 mod.send(:private, internal_method_name) +387 mod.send(:define_method, method_name, &compiled_method_lambda(roda_class, internal_method_name, locals_keys)) +388 mod.send(:private, method_name) +389 +390 method_name +391 end +
    + +
    +
    -modified?() +if_modified()
    @@ -186,25 +187,23 @@

    Public Instance methods

    - + [show source] -
        # File lib/roda/plugins/render.rb
    -355 def modified?
    -356   begin
    -357     mtime = template_last_modified
    -358   rescue
    -359     # ignore errors
    -360   else
    -361     if mtime != @mtime
    -362       @mtime = mtime
    -363       reset_template
    -364       return true
    -365     end
    -366   end
    -367 
    -368   false
    -369 end
    +
        # File lib/roda/plugins/render.rb
    +360 def if_modified
    +361   begin
    +362     mtime = template_last_modified
    +363   rescue
    +364     # ignore errors
    +365   else
    +366     if mtime != @mtime
    +367       reset_template
    +368       yield
    +369       @mtime = mtime
    +370     end
    +371   end
    +372 end
    @@ -224,9 +223,14 @@

    Public Instance methods

        # File lib/roda/plugins/render.rb
     337 def render(*args, &block)
    -338   modified?
    -339   @template.render(*args, &block)
    -340 end
    +338 res = nil +339 modified = false +340 if_modified do +341 res = @template.render(*args, &block) +342 modified = true +343 end +344 modified ? res : @template.render(*args, &block) +345 end
    @@ -245,13 +249,13 @@

    Public Instance methods

    [show source]
        # File lib/roda/plugins/render.rb
    -345 def template_last_modified
    -346   if deps = @dependencies
    -347     deps.map{|f| File.mtime(f)}.max
    -348   else
    -349     File.mtime(@path)
    -350   end
    -351 end
    +350 def template_last_modified +351 if deps = @dependencies +352 deps.map{|f| File.mtime(f)}.max +353 else +354 File.mtime(@path) +355 end +356 end
    diff --git a/rdoc/created.rid b/rdoc/created.rid index 77853ce9..33191845 100644 --- a/rdoc/created.rid +++ b/rdoc/created.rid @@ -1,6 +1,6 @@ -Wed, 13 Mar 2024 10:31:18 -0700 +Fri, 12 Apr 2024 08:38:22 -0700 README.rdoc Wed, 18 Oct 2023 15:53:01 -0700 -CHANGELOG Wed, 13 Mar 2024 10:26:39 -0700 +CHANGELOG Fri, 12 Apr 2024 07:38:02 -0700 doc/CHANGELOG.old Fri, 11 Mar 2022 10:33:07 -0800 MIT-LICENSE Thu, 12 Jan 2023 07:50:45 -0800 lib/roda.rb Mon, 14 Aug 2023 09:53:11 -0700 @@ -63,6 +63,7 @@ lib/roda/plugins/hash_routes.rb Mon, 13 Jun 2022 13:28:17 -0700 lib/roda/plugins/head.rb Fri, 08 Feb 2019 09:07:06 -0800 lib/roda/plugins/header_matchers.rb Mon, 19 Jun 2023 16:20:51 -0700 lib/roda/plugins/heartbeat.rb Mon, 19 Jun 2023 16:20:51 -0700 +lib/roda/plugins/hmac_paths.rb Fri, 12 Apr 2024 07:38:02 -0700 lib/roda/plugins/hooks.rb Sat, 06 Apr 2019 23:21:10 -0700 lib/roda/plugins/host_authorization.rb Mon, 12 Apr 2021 11:05:35 -0700 lib/roda/plugins/indifferent_params.rb Thu, 02 Feb 2023 11:13:09 -0800 @@ -107,7 +108,7 @@ lib/roda/plugins/r.rb Thu, 13 Aug 2020 12:32:01 -0700 lib/roda/plugins/recheck_precompiled_assets.rb Thu, 18 Feb 2021 14:23:19 -0800 lib/roda/plugins/redirect_http_to_https.rb Wed, 18 Oct 2023 14:59:20 -0700 lib/roda/plugins/relative_path.rb Mon, 14 Dec 2020 12:59:45 -0800 -lib/roda/plugins/render.rb Fri, 10 Mar 2023 10:19:46 -0800 +lib/roda/plugins/render.rb Wed, 03 Apr 2024 15:44:47 -0700 lib/roda/plugins/render_coverage.rb Fri, 10 Mar 2023 10:19:46 -0800 lib/roda/plugins/render_each.rb Mon, 12 Sep 2022 13:47:50 -0700 lib/roda/plugins/render_locals.rb Mon, 12 Sep 2022 13:47:50 -0700 @@ -141,7 +142,7 @@ lib/roda/plugins/view_options.rb Mon, 12 Sep 2022 13:47:50 -0700 lib/roda/request.rb Fri, 17 Mar 2023 08:33:20 -0700 lib/roda/response.rb Fri, 23 Feb 2024 14:44:14 -0800 lib/roda/session_middleware.rb Sun, 04 Aug 2019 14:34:46 -0700 -lib/roda/version.rb Wed, 13 Mar 2024 10:26:39 -0700 +lib/roda/version.rb Fri, 12 Apr 2024 07:38:02 -0700 doc/conventions.rdoc Mon, 16 Oct 2023 12:10:05 -0700 doc/release_notes/1.0.0.txt Tue, 19 Aug 2014 09:04:25 -0700 doc/release_notes/1.1.0.txt Tue, 11 Nov 2014 11:35:26 -0800 @@ -256,5 +257,6 @@ doc/release_notes/3.75.0.txt Thu, 14 Dec 2023 14:42:40 -0800 doc/release_notes/3.76.0.txt Fri, 12 Jan 2024 07:49:35 -0800 doc/release_notes/3.77.0.txt Mon, 12 Feb 2024 09:15:48 -0800 doc/release_notes/3.78.0.txt Wed, 13 Mar 2024 10:26:39 -0700 +doc/release_notes/3.79.0.txt Fri, 12 Apr 2024 07:38:02 -0700 doc/release_notes/3.8.0.txt Thu, 17 May 2018 13:49:47 -0700 doc/release_notes/3.9.0.txt Mon, 11 Jun 2018 12:33:07 -0700 diff --git a/rdoc/files/CHANGELOG.html b/rdoc/files/CHANGELOG.html index 4dd57d75..505df569 100644 --- a/rdoc/files/CHANGELOG.html +++ b/rdoc/files/CHANGELOG.html @@ -31,12 +31,19 @@

    CHANGELOG
    Last Update: -2024-03-13 10:26:39 -0700 +2024-04-12 07:38:02 -0700
    +

    3.79.0 (2024-04-12)

    +
    • +

      Do not update template mtime when there is an error reloading templates in the render plugin (jeremyevans)

      +
    • +

      Add hmac_paths plugin for preventing path enumeration and supporting access control (jeremyevans)

      +
    +

    3.78.0 (2024-03-13)

    • Add permissions_policy plugin for setting Permissions-Policy header (jeremyevans)

      diff --git a/rdoc/files/doc/release_notes/3_79_0_txt.html b/rdoc/files/doc/release_notes/3_79_0_txt.html new file mode 100644 index 00000000..f7ddbeb6 --- /dev/null +++ b/rdoc/files/doc/release_notes/3_79_0_txt.html @@ -0,0 +1,163 @@ + + + +3.79.0.txt + + + + + + +
      +
      +

      3.79.0.txt +

      +
      +doc/release_notes/3.79.0.txt +
      +
      +Last Update: +2024-04-12 07:38:02 -0700 +
      +
      +
      +
      +
      +

      New Features

      +
      • +

        The hmac_paths plugin allows protection of paths using an HMAC. This can be used to prevent users enumerating paths, since only paths with valid HMACs will be respected.

        + +

        To use the plugin, you must provide a :secret option. This sets the secret for the HMACs. Make sure to keep this value secret, as this plugin does not provide protection against users who know the secret value. The secret must be at least 32 bytes.

        + +
        plugin :hmac_paths, secret: 'some-secret-value-with-at-least-32-bytes'
        +
        + +

        To generate a valid HMAC path, you call the hmac_path method:

        + +
        hmac_path('/widget/1')
        +# => "/0c2feaefdfc80cc73da19b060c713d4193c57022815238c6657ce2d99b5925eb/0/widget/1"
        +
        + +

        The first segment in the returned path is the HMAC. The second segment is flags for the type of paths (see below), and the rest of the path is as given.

        + +

        To protect a path or any subsection in the routing tree, you wrap the related code in an r.hmac_path block.

        + +
        route do |r|
        +  r.hmac_path do
        +    r.get 'widget', Integer do |widget_id|
        +      # ...
        +    end
        +  end
        +end
        +
        + +

        If first segment of the remaining path contains a valid HMAC for the rest of the path (considering the flags), then r.hmac_path will match and yield to the block, and routing continues inside the block with the HMAC and flags segments removed.

        + +

        In the above example, if you provide a user a link for widget with ID 1, there is no way for them to guess the valid path for the widget with ID 2, preventing a user from enumerating widgets, without relying on custom access control. Users can only access paths that have been generated by the application and provided to them, either directly or indirectly.

        + +

        In the above example, r.hmac_path is used at the root of the routing tree. If you would like to call it below the root of the routing tree, it works correctly, but you must pass hmac_path the :root option specifying where r.hmac_paths will be called from. Consider this example:

        + +
        route do |r|
        +  r.on 'widget' do
        +    r.hmac_path do
        +      r.get Integer do |widget_id|
        +        # ...
        +      end
        +    end
        +  end
        +
        +  r.on 'foobar' do
        +    r.hmac_path do
        +      r.get Integer do |foobar_id|
        +        # ...
        +      end
        +    end
        +  end
        +end
        +
        + +

        For security reasons, the hmac_path plugin does not allow an HMAC path designed for widgets to be a valid match in the r.hmac_path call inside the “r.on ‘foobar’” block, preventing users who have a valid HMAC for a widget from looking at the page for a foobar with the same ID. When generating HMAC paths where the matching r.hmac_path call is not at the root of the routing tree, you must pass the :root option:

        + +
        hmac_path('/1', root: '/widget')
        +# => "/widget/daccafce3ce0df52e5ce774626779eaa7286085fcbde1e4681c74175ff0bbacd/0/1"
        +
        +hmac_path('/1', root: '/foobar')
        +# => "/foobar/c5fdaf482771d4f9f38cc13a1b2832929026a4ceb05e98ed6a0cd5a00bf180b7/0/1"
        +
        + +

        Note how the HMAC changes even though the path is the same.

        + +

        In addition to the :root option, there are additional options that further constrain use of the generated paths.

        + +

        The :method option creates a path that can only be called with a certain request method:

        + +
        hmac_path('/widget/1', method: :get)
        +# => "/d38c1e634ecf9a3c0ab9d0832555b035d91b35069efcbf2670b0dfefd4b62fdd/m/widget/1"
        +
        + +

        Note how this results in a different HMAC than the original hmac_path(‘/widget/1’) call. This sets the flags segment to “m”, which means r.hmac_path will consider the request mehod when checking the HMAC, and will only match if the provided request method is GET. This allows you to provide a user the ability to submit a GET request for the underlying path, without providing them the ability to submit a POST request for the underlying path, with no other access control.

        + +

        The :params option accepts a hash of params, converts it into a query string, and includes the query string in the returned path. It sets the flags segment to p, which means r.hmac_path will check for that exact query string. Requests with an empty query string or a different string will not match.

        + +
        hmac_path('/widget/1', params: {foo: 'bar'})
        +# => "/fe8d03f9572d5af6c2866295bd3c12c2ea11d290b1cbd016c3b68ee36a678139/p/widget/1?foo=bar"
        +
        + +

        For GET requests, which cannot have request bodies, that is sufficient to ensure that the submitted params are exactly as specified. However, POST requests can have request bodies, and request body params override query string params in r.params. So if you are using this for POST requests (or other HTTP verbs that can have request bodies), use r.GET instead of r.params to specifically check query string parameters.

        + +

        You can use :root, :method, and :params at the same time:

        + +
        hmac_path('/1', root: '/widget', method: :get, params: {foo: 'bar'})
        +# => "/widget/9169af1b8f40c62a1c2bb15b1b377c65bda681b8efded0e613a4176387468c15/mp/1?foo=bar"
        +
        + +

        This gives you a path only valid for a GET request with a root of “/widget” and a query string of “foo=bar”.

        + +

        To handle secret rotation, you can provide an :old_secret option when loading the plugin.

        + +
        plugin :hmac_paths, secret: 'some-secret-value-with-at-least-32-bytes',
        +                    old_secret: 'previous-secret-value-with-at-least-32-bytes'
        +
        + +

        This will use :secret for constructing new paths, but will respect paths generated by :old_secret.

        +
      + +

      Other Improvements

      +
      • +

        When not using cached templates in the render plugin, the render plugin now has better handling when a template is modified and results in an error. Previously, the error would be raised on the first request after the template modification, but subsequent requests would use the previous template value. The render plugin will no longer update the last modified time in this case, so if a template is modified and introduces an error (e.g. SyntaxError in an erb template), all future requests that use the template will result in the error being raised, until the template is fixed.

        +
      + +

      Backwards Compatibility

      +
      • +

        The internal TemplateMtimeWrapper API has been modified. As documented, this is an internal class and the API can change in any Roda version. However, if any code was relying on the previous implementation of TemplateMtimeWrapper#modified?, it will need to be modified, as that method has been replaced with TemplateMtimeWrapper#if_modified.

        + +

        Additionally, the TemplateMtimeWrapper#compiled_method_lambda API has also changed.

        +
      +
      +
      +
      + +
      +
      + + +
      + + + diff --git a/rdoc/files/lib/roda/plugins/hmac_paths_rb.html b/rdoc/files/lib/roda/plugins/hmac_paths_rb.html new file mode 100644 index 00000000..f6f12460 --- /dev/null +++ b/rdoc/files/lib/roda/plugins/hmac_paths_rb.html @@ -0,0 +1,58 @@ + + + +hmac_paths.rb + + + + + + +
      +
      +

      hmac_paths.rb +

      +
      +lib/roda/plugins/hmac_paths.rb +
      +
      +Last Update: +2024-04-12 07:38:02 -0700 +
      +
      +
      +
      +
      +
      +
      +

      Required files

      +
        +
      1. openssl
      2. +
      +
      +
      + +
      +
      + + +
      + + + diff --git a/rdoc/files/lib/roda/plugins/render_rb.html b/rdoc/files/lib/roda/plugins/render_rb.html index d7de771a..657d96cc 100644 --- a/rdoc/files/lib/roda/plugins/render_rb.html +++ b/rdoc/files/lib/roda/plugins/render_rb.html @@ -31,7 +31,7 @@

      render.rb

    Last Update: -2023-03-10 10:19:46 -0800 +2024-04-03 15:44:47 -0700
    diff --git a/rdoc/files/lib/roda/version_rb.html b/rdoc/files/lib/roda/version_rb.html index c306bfa8..518f2010 100644 --- a/rdoc/files/lib/roda/version_rb.html +++ b/rdoc/files/lib/roda/version_rb.html @@ -31,7 +31,7 @@

    version.rb

    Last Update: -2024-03-13 10:26:39 -0700 +2024-04-12 07:38:02 -0700
    diff --git a/rdoc/fr_class_index.html b/rdoc/fr_class_index.html index a7f92380..3b5a2d04 100644 --- a/rdoc/fr_class_index.html +++ b/rdoc/fr_class_index.html @@ -148,6 +148,9 @@ Roda::RodaPlugins::HeaderMatchers::RequestMethods
    Roda::RodaPlugins::Heartbeat Roda::RodaPlugins::Heartbeat::InstanceMethods +
    Roda::RodaPlugins::HmacPaths +Roda::RodaPlugins::HmacPaths::InstanceMethods +Roda::RodaPlugins::HmacPaths::RequestMethods
    Roda::RodaPlugins::Hooks Roda::RodaPlugins::Hooks::ClassMethods Roda::RodaPlugins::Hooks::InstanceMethods diff --git a/rdoc/fr_file_index.html b/rdoc/fr_file_index.html index 6428ea25..43c28112 100644 --- a/rdoc/fr_file_index.html +++ b/rdoc/fr_file_index.html @@ -128,6 +128,7 @@
  • 3.76.0.txt
  • 3.77.0.txt
  • 3.78.0.txt
  • +
  • 3.79.0.txt
  • 3.8.0.txt
  • 3.9.0.txt
  • roda.rb
  • @@ -190,6 +191,7 @@
  • head.rb
  • header_matchers.rb
  • heartbeat.rb
  • +
  • hmac_paths.rb
  • hooks.rb
  • host_authorization.rb
  • indifferent_params.rb
  • diff --git a/rdoc/fr_method_index.html b/rdoc/fr_method_index.html index 599e0f37..c940b889 100644 --- a/rdoc/fr_method_index.html +++ b/rdoc/fr_method_index.html @@ -37,154 +37,155 @@
  • #route_block (Roda::RodaPlugins::Base::ClassMethods)
  • #scope (Roda::RodaPlugins::Base::RequestMethods)
  • #status (Roda::RodaPlugins::Base::ResponseMethods)
  • -
  • ::configure (Roda::RodaPlugins::DefaultStatus)
  • -
  • ::configure (Roda::RodaPlugins::JsonParser)
  • -
  • ::configure (Roda::RodaPlugins::Mailer)
  • -
  • ::configure (Roda::RodaPlugins::Json)
  • -
  • ::configure (Roda::RodaPlugins::ClassLevelRouting)
  • -
  • ::configure (Roda::RodaPlugins::InvalidRequestBody)
  • -
  • ::configure (Roda::RodaPlugins::ErrorHandler)
  • -
  • ::configure (Roda::RodaPlugins::RouteCsrf)
  • -
  • ::configure (Roda::RodaPlugins::AdditionalRenderEngines)
  • ::configure (Roda::RodaPlugins::CommonLogger)
  • -
  • ::configure (Roda::RodaPlugins::AdditionalViewDirectories)
  • +
  • ::configure (Roda::RodaPlugins::PermissionsPolicy)
  • +
  • ::configure (Roda::RodaPlugins::Path)
  • +
  • ::configure (Roda::RodaPlugins::ClassLevelRouting)
  • ::configure (Roda::RodaPlugins::ContentFor)
  • -
  • ::configure (Roda::RodaPlugins::Assets)
  • -
  • ::configure (Roda::RodaPlugins::IntegerMatcherMax)
  • ::configure (Roda::RodaPlugins::ContentSecurityPolicy)
  • -
  • ::configure (Roda::RodaPlugins::RouteBlockArgs)
  • -
  • ::configure (Roda::RodaPlugins::MatchAffix)
  • -
  • ::configure (Roda::RodaPlugins::HostAuthorization)
  • -
  • ::configure (Roda::RodaPlugins::RequestAref)
  • -
  • ::configure (Roda::RodaPlugins::Hooks)
  • -
  • ::configure (Roda::RodaPlugins::Heartbeat)
  • -
  • ::configure (Roda::RodaPlugins::RenderLocals)
  • -
  • ::configure (Roda::RodaPlugins::MatchHookArgs)
  • -
  • ::configure (Roda::RodaPlugins::Middleware)
  • +
  • ::configure (Roda::RodaPlugins::SymbolMatchers)
  • ::configure (Roda::RodaPlugins::CookieFlags)
  • -
  • ::configure (Roda::RodaPlugins::AutoloadHashBranches)
  • -
  • ::configure (Roda::RodaPlugins::HashRoutes)
  • +
  • ::configure (Roda::RodaPlugins::AdditionalRenderEngines)
  • ::configure (Roda::RodaPlugins::Cookies)
  • -
  • ::configure (Roda::RodaPlugins::Chunked)
  • -
  • ::configure (Roda::RodaPlugins::RunAppendSlash)
  • -
  • ::configure (Roda::RodaPlugins::AutoloadNamedRoutes)
  • -
  • ::configure (Roda::RodaPlugins::MultiPublic)
  • -
  • ::configure (Roda::RodaPlugins::HashPaths)
  • -
  • ::configure (Roda::RodaPlugins::ErrorMail)
  • +
  • ::configure (Roda::RodaPlugins::AdditionalViewDirectories)
  • +
  • ::configure (Roda::RodaPlugins::StripPathPrefix)
  • +
  • ::configure (Roda::RodaPlugins::Assets)
  • +
  • ::configure (Roda::RodaPlugins::SymbolViews)
  • +
  • ::configure (Roda::RodaPlugins::TimestampPublic)
  • +
  • ::configure (Roda::RodaPlugins::Public)
  • ::configure (Roda::RodaPlugins::Csrf)
  • -
  • ::configure (Roda::RodaPlugins::MultiRoute)
  • -
  • ::configure (Roda::RodaPlugins::MultiRun)
  • +
  • ::configure (Roda::RodaPlugins::RecheckPrecompiledAssets)
  • +
  • ::configure (Roda::RodaPlugins::NotFound)
  • ::configure (Roda::RodaPlugins::CustomBlockResults)
  • -
  • ::configure (Roda::RodaPlugins::HashBranches)
  • -
  • ::configure (Roda::RodaPlugins::Sessions)
  • -
  • ::configure (Roda::RodaPlugins::RenderCoverage)
  • +
  • ::configure (Roda::RodaPlugins::RedirectHttpToHttps)
  • +
  • ::configure (Roda::RodaPlugins::Chunked)
  • ::configure (Roda::RodaPlugins::CustomMatchers)
  • -
  • ::configure (Roda::RodaPlugins::NamedRoutes)
  • -
  • ::configure (Roda::RodaPlugins::SinatraHelpers)
  • -
  • ::configure (Roda::RodaPlugins::HashBranchViewSubdir)
  • +
  • ::configure (Roda::RodaPlugins::Render)
  • ::configure (Roda::RodaPlugins::DefaultHeaders)
  • +
  • ::configure (Roda::RodaPlugins::AutoloadHashBranches)
  • ::configure (Roda::RodaPlugins::NamedTemplates)
  • -
  • ::configure (Roda::RodaPlugins::Render)
  • -
  • ::configure (Roda::RodaPlugins::RedirectHttpToHttps)
  • -
  • ::configure (Roda::RodaPlugins::NotFound)
  • +
  • ::configure (Roda::RodaPlugins::DefaultStatus)
  • +
  • ::configure (Roda::RodaPlugins::NamedRoutes)
  • ::configure (Roda::RodaPlugins::DirectCall)
  • -
  • ::configure (Roda::RodaPlugins::RecheckPrecompiledAssets)
  • -
  • ::configure (Roda::RodaPlugins::FilterCommonLogger)
  • +
  • ::configure (Roda::RodaPlugins::AutoloadNamedRoutes)
  • ::configure (Roda::RodaPlugins::Environments)
  • -
  • ::configure (Roda::RodaPlugins::SymbolViews)
  • -
  • ::configure (Roda::RodaPlugins::Public)
  • +
  • ::configure (Roda::RodaPlugins::TypeRouting)
  • +
  • ::configure (Roda::RodaPlugins::TypecastParams)
  • ::configure (Roda::RodaPlugins::ErrorEmail)
  • -
  • ::configure (Roda::RodaPlugins::Path)
  • +
  • ::configure (Roda::RodaPlugins::RenderCoverage)
  • +
  • ::configure (Roda::RodaPlugins::ErrorHandler)
  • +
  • ::configure (Roda::RodaPlugins::ErrorMail)
  • +
  • ::configure (Roda::RodaPlugins::RenderLocals)
  • +
  • ::configure (Roda::RodaPlugins::MultiRun)
  • +
  • ::configure (Roda::RodaPlugins::RequestAref)
  • ::configure (Roda::RodaPlugins::PathRewriter)
  • -
  • ::configure (Roda::RodaPlugins::PermissionsPolicy)
  • -
  • ::configure (Roda::RodaPlugins::StripPathPrefix)
  • +
  • ::configure (Roda::RodaPlugins::MultiRoute)
  • +
  • ::configure (Roda::RodaPlugins::HostAuthorization)
  • +
  • ::configure (Roda::RodaPlugins::MultiPublic)
  • +
  • ::configure (Roda::RodaPlugins::FilterCommonLogger)
  • +
  • ::configure (Roda::RodaPlugins::RouteBlockArgs)
  • +
  • ::configure (Roda::RodaPlugins::HashBranchViewSubdir)
  • +
  • ::configure (Roda::RodaPlugins::RouteCsrf)
  • +
  • ::configure (Roda::RodaPlugins::Middleware)
  • +
  • ::configure (Roda::RodaPlugins::MatchHookArgs)
  • +
  • ::configure (Roda::RodaPlugins::HashBranches)
  • +
  • ::configure (Roda::RodaPlugins::MatchAffix)
  • +
  • ::configure (Roda::RodaPlugins::HashPaths)
  • +
  • ::configure (Roda::RodaPlugins::RunAppendSlash)
  • +
  • ::configure (Roda::RodaPlugins::Mailer)
  • +
  • ::configure (Roda::RodaPlugins::HashRoutes)
  • +
  • ::configure (Roda::RodaPlugins::Sessions)
  • ::configure (Roda::RodaPlugins::StatusHandler)
  • -
  • ::configure (Roda::RodaPlugins::SymbolMatchers)
  • -
  • ::configure (Roda::RodaPlugins::TypecastParams)
  • -
  • ::configure (Roda::RodaPlugins::TypeRouting)
  • -
  • ::configure (Roda::RodaPlugins::TimestampPublic)
  • +
  • ::configure (Roda::RodaPlugins::SinatraHelpers)
  • ::configure (Roda::RodaPlugins::Static)
  • +
  • ::configure (Roda::RodaPlugins::JsonParser)
  • +
  • ::configure (Roda::RodaPlugins::Json)
  • +
  • ::configure (Roda::RodaPlugins::InvalidRequestBody)
  • +
  • ::configure (Roda::RodaPlugins::IntegerMatcherMax)
  • +
  • ::configure (Roda::RodaPlugins::Heartbeat)
  • +
  • ::configure (Roda::RodaPlugins::HmacPaths)
  • +
  • ::configure (Roda::RodaPlugins::Hooks)
  • ::create (Roda::RodaPlugins::TypecastParams::Error)
  • ::css (Roda::RodaPlugins::ExceptionPage)
  • ::decode64 (Roda::RodaPlugins::Base64_)
  • ::deprecate_constant (Roda::RodaPlugins)
  • ::handle_type (Roda::RodaPlugins::TypecastParams::Params)
  • ::js (Roda::RodaPlugins::ExceptionPage)
  • -
  • ::load_dependencies (Roda::RodaPlugins::LinkTo)
  • -
  • ::load_dependencies (Roda::RodaPlugins::PrecompileTemplates)
  • +
  • ::load_dependencies (Roda::RodaPlugins::MultiView)
  • +
  • ::load_dependencies (Roda::RodaPlugins::Sessions)
  • ::load_dependencies (Roda::RodaPlugins::ExceptionPage)
  • -
  • ::load_dependencies (Roda::RodaPlugins::SymbolMatchers)
  • -
  • ::load_dependencies (Roda::RodaPlugins::StaticRouting)
  • -
  • ::load_dependencies (Roda::RodaPlugins::ErbH)
  • +
  • ::load_dependencies (Roda::RodaPlugins::ContentFor)
  • +
  • ::load_dependencies (Roda::RodaPlugins::HashRoutes)
  • +
  • ::load_dependencies (Roda::RodaPlugins::MatchAffix)
  • +
  • ::load_dependencies (Roda::RodaPlugins::MatchHook)
  • ::load_dependencies (Roda::RodaPlugins::RouteCsrf)
  • -
  • ::load_dependencies (Roda::RodaPlugins::RecheckPrecompiledAssets)
  • -
  • ::load_dependencies (Roda::RodaPlugins::AdditionalRenderEngines)
  • -
  • ::load_dependencies (Roda::RodaPlugins::FilterCommonLogger)
  • -
  • ::load_dependencies (Roda::RodaPlugins::Partials)
  • -
  • ::load_dependencies (Roda::RodaPlugins::PadrinoRender)
  • -
  • ::load_dependencies (Roda::RodaPlugins::NotFound)
  • -
  • ::load_dependencies (Roda::RodaPlugins::NotAllowed)
  • -
  • ::load_dependencies (Roda::RodaPlugins::PlaceholderStringMatchers)
  • ::load_dependencies (Roda::RodaPlugins::HashBranchViewSubdir)
  • -
  • ::load_dependencies (Roda::RodaPlugins::NamedTemplates)
  • -
  • ::load_dependencies (Roda::RodaPlugins::TypecastParamsSizedIntegers)
  • -
  • ::load_dependencies (Roda::RodaPlugins::RenderCoverage)
  • -
  • ::load_dependencies (Roda::RodaPlugins::BranchLocals)
  • +
  • ::load_dependencies (Roda::RodaPlugins::MultiPublic)
  • +
  • ::load_dependencies (Roda::RodaPlugins::FilterCommonLogger)
  • +
  • ::load_dependencies (Roda::RodaPlugins::InjectERB)
  • +
  • ::load_dependencies (Roda::RodaPlugins::StaticRouting)
  • +
  • ::load_dependencies (Roda::RodaPlugins::LinkTo)
  • +
  • ::load_dependencies (Roda::RodaPlugins::MultiRoute)
  • +
  • ::load_dependencies (Roda::RodaPlugins::RenderLocals)
  • +
  • ::load_dependencies (Roda::RodaPlugins::RenderEach)
  • ::load_dependencies (Roda::RodaPlugins::SinatraHelpers)
  • +
  • ::load_dependencies (Roda::RodaPlugins::BranchLocals)
  • +
  • ::load_dependencies (Roda::RodaPlugins::Partials)
  • ::load_dependencies (Roda::RodaPlugins::ViewOptions)
  • -
  • ::load_dependencies (Roda::RodaPlugins::AdditionalViewDirectories)
  • -
  • ::load_dependencies (Roda::RodaPlugins::Sessions)
  • -
  • ::load_dependencies (Roda::RodaPlugins::MultiView)
  • -
  • ::load_dependencies (Roda::RodaPlugins::MultiRoute)
  • +
  • ::load_dependencies (Roda::RodaPlugins::RenderCoverage)
  • +
  • ::load_dependencies (Roda::RodaPlugins::MultibyteStringMatcher)
  • ::load_dependencies (Roda::RodaPlugins::AutoloadNamedRoutes)
  • +
  • ::load_dependencies (Roda::RodaPlugins::NamedTemplates)
  • +
  • ::load_dependencies (Roda::RodaPlugins::AutoloadHashBranches)
  • ::load_dependencies (Roda::RodaPlugins::CaptureERB)
  • -
  • ::load_dependencies (Roda::RodaPlugins::RenderEach)
  • +
  • ::load_dependencies (Roda::RodaPlugins::NotAllowed)
  • ::load_dependencies (Roda::RodaPlugins::Chunked)
  • -
  • ::load_dependencies (Roda::RodaPlugins::MultiPublic)
  • -
  • ::load_dependencies (Roda::RodaPlugins::RenderLocals)
  • -
  • ::load_dependencies (Roda::RodaPlugins::HashRoutes)
  • -
  • ::load_dependencies (Roda::RodaPlugins::AutoloadHashBranches)
  • ::load_dependencies (Roda::RodaPlugins::AssetsPreloading)
  • -
  • ::load_dependencies (Roda::RodaPlugins::MatchHook)
  • -
  • ::load_dependencies (Roda::RodaPlugins::MatchAffix)
  • -
  • ::load_dependencies (Roda::RodaPlugins::InjectERB)
  • +
  • ::load_dependencies (Roda::RodaPlugins::NotFound)
  • +
  • ::load_dependencies (Roda::RodaPlugins::RecheckPrecompiledAssets)
  • +
  • ::load_dependencies (Roda::RodaPlugins::PadrinoRender)
  • +
  • ::load_dependencies (Roda::RodaPlugins::PrecompileTemplates)
  • ::load_dependencies (Roda::RodaPlugins::Assets)
  • -
  • ::load_dependencies (Roda::RodaPlugins::ContentFor)
  • -
  • ::load_dependencies (Roda::RodaPlugins::MultibyteStringMatcher)
  • +
  • ::load_dependencies (Roda::RodaPlugins::AdditionalViewDirectories)
  • +
  • ::load_dependencies (Roda::RodaPlugins::AdditionalRenderEngines)
  • +
  • ::load_dependencies (Roda::RodaPlugins::SymbolMatchers)
  • +
  • ::load_dependencies (Roda::RodaPlugins::TypecastParamsSizedIntegers)
  • +
  • ::load_dependencies (Roda::RodaPlugins::PlaceholderStringMatchers)
  • +
  • ::load_dependencies (Roda::RodaPlugins::ErbH)
  • ::load_plugin (Roda::RodaPlugins)
  • ::max_input_bytesize (Roda::RodaPlugins::TypecastParams::Params)
  • ::nest (Roda::RodaPlugins::TypecastParams::Params)
  • -
  • ::new (Roda::RodaPlugins::MiddlewareStack::Stack)
  • ::new (Roda::RodaCache)
  • -
  • ::new (Roda::RodaPlugins::Chunked::StreamBody)
  • -
  • ::new (Roda::RodaPlugins::Base::RequestMethods)
  • -
  • ::new (Roda::RodaPlugins::PermissionsPolicy::ResponseMethods)
  • -
  • ::new (Roda::RodaPlugins::Streaming::Stream)
  • +
  • ::new (Roda::RodaPlugins::ClassLevelRouting::InstanceMethods)
  • +
  • ::new (Roda::RodaPlugins::Middleware::Forwarder)
  • ::new (Roda::RodaPlugins::PathRewriter::RequestMethods)
  • ::new (Roda::RodaPlugins::Mailer::InstanceMethods)
  • -
  • ::new (Roda::RodaPlugins::Streaming::AsyncStream)
  • +
  • ::new (RodaSessionMiddleware::SessionHash)
  • +
  • ::new (Roda::RodaPlugins::Chunked::StreamBody)
  • +
  • ::new (Roda::RodaPlugins::MiddlewareStack::Stack)
  • ::new (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • -
  • ::new (Roda::RodaPlugins::Base::ResponseMethods)
  • +
  • ::new (Roda::RodaPlugins::DisallowFileUploads::RequestMethods)
  • ::new (Roda::RodaPlugins::Flash::FlashHash)
  • -
  • ::new (Roda::RodaPlugins::ResponseRequest::InstanceMethods)
  • +
  • ::new (Roda::RodaPlugins::PermissionsPolicy::Policy)
  • ::new (Roda::RodaPlugins::RecheckPrecompiledAssets::CompiledAssetsHash)
  • -
  • ::new (Roda::RodaPlugins::RequestHeaders::Headers)
  • -
  • ::new (Roda::RodaPlugins::IndifferentParams::QueryParser::Params)
  • -
  • ::new (Roda::RodaPlugins::ClassLevelRouting::InstanceMethods)
  • +
  • ::new (Roda::RodaPlugins::Base::RequestMethods)
  • +
  • ::new (Roda::RodaPlugins::SinatraHelpers::DelayedBody)
  • +
  • ::new (Roda::RodaPlugins::PermissionsPolicy::ResponseMethods)
  • ::new (Roda::RodaPlugins::ContentSecurityPolicy::ResponseMethods)
  • +
  • ::new (Roda::RodaPlugins::Streaming::Stream)
  • +
  • ::new (Roda::RodaPlugins::MiddlewareStack::StackPosition)
  • ::new (Roda::RodaPlugins::Base::InstanceMethods)
  • -
  • ::new (Roda::RodaPlugins::TypecastParams::Params)
  • -
  • ::new (RodaSessionMiddleware::SessionHash)
  • -
  • ::new (Roda::RodaPlugins::Chunked::Body)
  • ::new (Roda::RodaPlugins::Render::TemplateMtimeWrapper)
  • ::new (RodaSessionMiddleware)
  • -
  • ::new (Roda::RodaPlugins::Head::CloseLater)
  • -
  • ::new (Roda::RodaPlugins::SinatraHelpers::DelayedBody)
  • -
  • ::new (Roda::RodaPlugins::MiddlewareStack::StackPosition)
  • -
  • ::new (Roda::RodaPlugins::Middleware::Forwarder)
  • -
  • ::new (Roda::RodaPlugins::PermissionsPolicy::Policy)
  • +
  • ::new (Roda::RodaPlugins::IndifferentParams::QueryParser::Params)
  • +
  • ::new (Roda::RodaPlugins::Streaming::AsyncStream)
  • +
  • ::new (Roda::RodaPlugins::ResponseRequest::InstanceMethods)
  • ::new (Roda::RodaPlugins::HashRoutes::DSL)
  • -
  • ::new (Roda::RodaPlugins::DisallowFileUploads::RequestMethods)
  • +
  • ::new (Roda::RodaPlugins::Base::ResponseMethods)
  • +
  • ::new (Roda::RodaPlugins::TypecastParams::Params)
  • +
  • ::new (Roda::RodaPlugins::Chunked::Body)
  • +
  • ::new (Roda::RodaPlugins::RequestHeaders::Headers)
  • +
  • ::new (Roda::RodaPlugins::Head::CloseLater)
  • ::register_plugin (Roda::RodaPlugins)
  • ::split_secret (Roda::RodaPlugins::Sessions)
  • ::start_timer (Roda::RodaPlugins::CommonLogger)
  • @@ -192,23 +193,23 @@
  • ::urlsafe_decode64 (Roda::RodaPlugins::Base64_)
  • ::urlsafe_encode64 (Roda::RodaPlugins::Base64_)
  • #<< (Roda::RodaPlugins::Streaming::Stream)
  • -
  • #POST (Roda::RodaPlugins::InvalidRequestBody::RequestMethods)
  • #POST (Roda::RodaPlugins::JsonParser::RequestMethods)
  • +
  • #POST (Roda::RodaPlugins::InvalidRequestBody::RequestMethods)
  • +
  • #[] (Roda::RodaPlugins::RequestHeaders::Headers)
  • #[] (Roda::RodaPlugins::Base::ResponseMethods)
  • #[] (Roda::RodaPlugins::TypecastParams::Params)
  • -
  • #[] (RodaSessionMiddleware::SessionHash)
  • -
  • #[] (Roda::RodaPlugins::RequestHeaders::Headers)
  • #[] (Roda::RodaPlugins::RecheckPrecompiledAssets::CompiledAssetsHash)
  • #[] (Roda::RodaCache)
  • -
  • #[]= (Roda::RodaPlugins::RecheckPrecompiledAssets::CompiledAssetsHash)
  • +
  • #[] (RodaSessionMiddleware::SessionHash)
  • #[]= (RodaSessionMiddleware::SessionHash)
  • -
  • #[]= (Roda::RodaPlugins::Base::ResponseMethods)
  • -
  • #[]= (Roda::RodaPlugins::Flash::FlashHash)
  • #[]= (Roda::RodaCache)
  • +
  • #[]= (Roda::RodaPlugins::Flash::FlashHash)
  • +
  • #[]= (Roda::RodaPlugins::RecheckPrecompiledAssets::CompiledAssetsHash)
  • +
  • #[]= (Roda::RodaPlugins::Base::ResponseMethods)
  • #_match_hook_args (Roda::RodaPlugins::MatchHookArgs::InstanceMethods)
  • #_remaining_path (RodaSessionMiddleware::RequestMethods)
  • -
  • #_roda_handle_main_route (Roda::RodaPlugins::ErrorHandler::InstanceMethods)
  • #_roda_handle_main_route (Roda::RodaPlugins::Base::InstanceMethods)
  • +
  • #_roda_handle_main_route (Roda::RodaPlugins::ErrorHandler::InstanceMethods)
  • #_roda_handle_route (Roda::RodaPlugins::Base::InstanceMethods)
  • #_roda_main_route (Roda::RodaPlugins::Base::InstanceMethods)
  • #_roda_run_main_route (Roda::RodaPlugins::BeforeHook::InstanceMethods)
  • @@ -225,8 +226,8 @@
  • #append_view_subdir (Roda::RodaPlugins::ViewOptions::InstanceMethods)
  • #array (Roda::RodaPlugins::TypecastParams::Params)
  • #array! (Roda::RodaPlugins::TypecastParams::Params)
  • -
  • #assets (Roda::RodaPlugins::Assets::RequestMethods)
  • #assets (Roda::RodaPlugins::Assets::InstanceMethods)
  • +
  • #assets (Roda::RodaPlugins::Assets::RequestMethods)
  • #assets_matchers (Roda::RodaPlugins::Assets::RequestClassMethods)
  • #assets_opts (Roda::RodaPlugins::Assets::ClassMethods)
  • #assets_paths (Roda::RodaPlugins::Assets::InstanceMethods)
  • @@ -235,21 +236,21 @@
  • #autoload_hash_branch_dir (Roda::RodaPlugins::AutoloadHashBranches::ClassMethods)
  • #autoload_named_route (Roda::RodaPlugins::AutoloadNamedRoutes::ClassMethods)
  • #back (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • -
  • #before (Roda::RodaPlugins::MiddlewareStack::Stack)
  • #before (Roda::RodaPlugins::Hooks::ClassMethods)
  • +
  • #before (Roda::RodaPlugins::MiddlewareStack::Stack)
  • #block_result (Roda::RodaPlugins::Base::RequestMethods)
  • #body (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • #body= (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • #build! (Roda::RodaPlugins::DelayBuild::ClassMethods)
  • #cache_control (Roda::RodaPlugins::Caching::ResponseMethods)
  • #cached_matcher (Roda::RodaPlugins::Base::RequestClassMethods)
  • -
  • #call (Roda::RodaPlugins::Middleware::Forwarder)
  • +
  • #call (Roda::RodaPlugins::Base::ClassMethods)
  • +
  • #call (Roda::RodaPlugins::Middleware::InstanceMethods)
  • #call (Roda::RodaPlugins::BeforeHook::InstanceMethods)
  • +
  • #call (Roda::RodaPlugins::Base::InstanceMethods)
  • +
  • #call (Roda::RodaPlugins::Middleware::Forwarder)
  • #call (Roda::RodaPlugins::ErrorHandler::InstanceMethods)
  • #call (Roda::RodaPlugins::DirectCall::ClassMethods)
  • -
  • #call (Roda::RodaPlugins::Base::InstanceMethods)
  • -
  • #call (Roda::RodaPlugins::Base::ClassMethods)
  • -
  • #call (Roda::RodaPlugins::Middleware::InstanceMethods)
  • #call (RodaSessionMiddleware)
  • #capture_erb (Roda::RodaPlugins::CaptureERB::InstanceMethods)
  • #check_csrf! (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • @@ -264,9 +265,9 @@
  • #clear_named_route_regexp! (Roda::RodaPlugins::MultiRoute::RequestClassMethods)
  • #clear_session (Roda::RodaPlugins::Sessions::InstanceMethods)
  • #client_error? (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • -
  • #close (Roda::RodaPlugins::Streaming::AsyncStream)
  • -
  • #close (Roda::RodaPlugins::Head::CloseLater)
  • #close (Roda::RodaPlugins::Streaming::Stream)
  • +
  • #close (Roda::RodaPlugins::Head::CloseLater)
  • +
  • #close (Roda::RodaPlugins::Streaming::AsyncStream)
  • #closed? (Roda::RodaPlugins::Streaming::Stream)
  • #compile_assets (Roda::RodaPlugins::Assets::ClassMethods)
  • #compiled_method (Roda::RodaPlugins::Render::TemplateMtimeWrapper)
  • @@ -288,13 +289,13 @@
  • #csrf_metatag (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • #csrf_metatag (Roda::RodaPlugins::Csrf::InstanceMethods)
  • #csrf_path (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • -
  • #csrf_tag (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • #csrf_tag (Roda::RodaPlugins::Csrf::InstanceMethods)
  • -
  • #csrf_token (Roda::RodaPlugins::Csrf::InstanceMethods)
  • +
  • #csrf_tag (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • #csrf_token (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • +
  • #csrf_token (Roda::RodaPlugins::Csrf::InstanceMethods)
  • #custom_matcher (Roda::RodaPlugins::CustomMatchers::ClassMethods)
  • -
  • #default_headers (Roda::RodaPlugins::DefaultHeaders::ClassMethods)
  • #default_headers (Roda::RodaPlugins::DefaultHeaders::ResponseMethods)
  • +
  • #default_headers (Roda::RodaPlugins::DefaultHeaders::ClassMethods)
  • #default_headers (Roda::RodaPlugins::Base::ResponseMethods)
  • #default_status (Roda::RodaPlugins::Base::ResponseMethods)
  • #define_compiled_method (Roda::RodaPlugins::Render::TemplateMtimeWrapper)
  • @@ -309,22 +310,22 @@
  • #dispatch_from (Roda::RodaPlugins::HashRoutes::DSL)
  • #each (Roda::RodaPlugins::Head::CloseLater)
  • #each (Roda::RodaPlugins::Streaming::AsyncStream)
  • +
  • #each (Roda::RodaPlugins::Streaming::Stream)
  • #each (Roda::RodaPlugins::RecheckPrecompiledAssets::CompiledAssetsHash)
  • #each (RodaSessionMiddleware::SessionHash)
  • -
  • #each (Roda::RodaPlugins::Chunked::StreamBody)
  • #each (Roda::RodaPlugins::SinatraHelpers::DelayedBody)
  • -
  • #each (Roda::RodaPlugins::Streaming::Stream)
  • #each (Roda::RodaPlugins::Chunked::Body)
  • +
  • #each (Roda::RodaPlugins::Chunked::StreamBody)
  • #each_chunk (Roda::RodaPlugins::Chunked::InstanceMethods)
  • #each_partial (Roda::RodaPlugins::Partials::InstanceMethods)
  • +
  • #empty? (Roda::RodaPlugins::SinatraHelpers::DelayedBody)
  • #empty? (Roda::RodaPlugins::Base::ResponseMethods)
  • #empty? (RodaSessionMiddleware::SessionHash)
  • -
  • #empty? (Roda::RodaPlugins::SinatraHelpers::DelayedBody)
  • #env (Roda::RodaPlugins::Base::InstanceMethods)
  • #environment (Roda::RodaPlugins::Environments::ClassMethods)
  • #environment= (Roda::RodaPlugins::Environments::ClassMethods)
  • -
  • #error (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • #error (Roda::RodaPlugins::ErrorHandler::ClassMethods)
  • +
  • #error (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • #error_email (Roda::RodaPlugins::ErrorEmail::InstanceMethods)
  • #error_email_content (Roda::RodaPlugins::ErrorEmail::InstanceMethods)
  • #error_mail (Roda::RodaPlugins::ErrorMail::InstanceMethods)
  • @@ -338,44 +339,44 @@
  • #expand_path (Roda::RodaPlugins::Base::ClassMethods)
  • #expand_path (Roda::RodaPlugins::StripPathPrefix::ClassMethods)
  • #expires (Roda::RodaPlugins::Caching::ResponseMethods)
  • -
  • #fetch (RodaSessionMiddleware::SessionHash)
  • #fetch (Roda::RodaPlugins::TypecastParams::Params)
  • +
  • #fetch (RodaSessionMiddleware::SessionHash)
  • #finish (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • #finish (Roda::RodaPlugins::DropBody::ResponseMethods)
  • +
  • #finish (Roda::RodaPlugins::Base::ResponseMethods)
  • #finish (Roda::RodaPlugins::DeleteEmptyHeaders::ResponseMethods)
  • -
  • #finish (Roda::RodaPlugins::Mailer::ResponseMethods)
  • #finish (Roda::RodaPlugins::Caching::ResponseMethods)
  • -
  • #finish (Roda::RodaPlugins::Base::ResponseMethods)
  • -
  • #finish_with_body (Roda::RodaPlugins::Base::ResponseMethods)
  • +
  • #finish (Roda::RodaPlugins::Mailer::ResponseMethods)
  • #finish_with_body (Roda::RodaPlugins::DeleteEmptyHeaders::ResponseMethods)
  • +
  • #finish_with_body (Roda::RodaPlugins::Base::ResponseMethods)
  • #flash (Roda::RodaPlugins::Flash::InstanceMethods)
  • #flush (Roda::RodaPlugins::Chunked::InstanceMethods)
  • #forward_next (Roda::RodaPlugins::Middleware::RequestMethods)
  • -
  • #freeze (Roda::RodaPlugins::CustomBlockResults::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::MatchHookArgs::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::AutoloadHashBranches::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::Hooks::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::PermissionsPolicy::Policy)
  • +
  • #freeze (Roda::RodaPlugins::MultiRoute::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::PathRewriter::ClassMethods)
  • #freeze (Roda::RodaPlugins::MultiRun::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::StatusHandler::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • #freeze (Roda::RodaPlugins::ClassLevelRouting::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::HashRoutes::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::HashPaths::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • +
  • #freeze (Roda::RodaPlugins::Path::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::MatchHookArgs::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::HashBranches::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::AutoloadNamedRoutes::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::PermissionsPolicy::Policy)
  • +
  • #freeze (Roda::RodaPlugins::HashBranchViewSubdir::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::AutoloadHashBranches::ClassMethods)
  • #freeze (Roda::RodaPlugins::NamedRoutes::ClassMethods)
  • #freeze (Roda::RodaCache)
  • -
  • #freeze (Roda::RodaPlugins::PathRewriter::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::Base::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::AutoloadNamedRoutes::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::CustomBlockResults::ClassMethods)
  • #freeze (Roda::RodaPlugins::DefaultHeaders::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::HashBranchViewSubdir::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::Path::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::NamedTemplates::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::MailProcessor::ClassMethods)
  • #freeze (Roda::RodaPlugins::Render::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::MultiRoute::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::StatusHandler::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::Base::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::NamedTemplates::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::HashRoutes::ClassMethods)
  • #freeze (Roda::RodaPlugins::TypecastParams::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::HashPaths::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::HashBranches::ClassMethods)
  • -
  • #freeze (Roda::RodaPlugins::MailProcessor::ClassMethods)
  • +
  • #freeze (Roda::RodaPlugins::Hooks::ClassMethods)
  • #freeze_template_caches! (Roda::RodaPlugins::PrecompileTemplates::ClassMethods)
  • #get (Roda::RodaPlugins::Base::RequestMethods)
  • #h (Roda::RodaPlugins::H::InstanceMethods)
  • @@ -389,47 +390,51 @@
  • #handle_stream_error (Roda::RodaPlugins::Streaming::InstanceMethods)
  • #handled_mail_hook (Roda::RodaPlugins::MailProcessor::InstanceMethods)
  • #has_key? (RodaSessionMiddleware::SessionHash)
  • -
  • #hash_branch (Roda::RodaPlugins::HashBranchViewSubdir::ClassMethods)
  • #hash_branch (Roda::RodaPlugins::HashBranches::ClassMethods)
  • +
  • #hash_branch (Roda::RodaPlugins::HashBranchViewSubdir::ClassMethods)
  • #hash_branches (Roda::RodaPlugins::HashBranches::RequestMethods)
  • #hash_matcher (Roda::RodaPlugins::HashMatcher::ClassMethods)
  • #hash_path (Roda::RodaPlugins::HashPaths::ClassMethods)
  • #hash_paths (Roda::RodaPlugins::HashPaths::RequestMethods)
  • -
  • #hash_routes (Roda::RodaPlugins::HashRoutes::RequestMethods)
  • #hash_routes (Roda::RodaPlugins::HashRoutes::ClassMethods)
  • +
  • #hash_routes (Roda::RodaPlugins::HashRoutes::RequestMethods)
  • #header (Roda::RodaPlugins::MailProcessor::RequestMethods)
  • #header_key (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • #header_key (Roda::RodaPlugins::PermissionsPolicy::Policy)
  • -
  • #header_value (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • #header_value (Roda::RodaPlugins::PermissionsPolicy::Policy)
  • +
  • #header_value (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • #headers (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • #headers (Roda::RodaPlugins::RequestHeaders::RequestMethods)
  • +
  • #hmac_path (Roda::RodaPlugins::HmacPaths::RequestMethods)
  • +
  • #hmac_path (Roda::RodaPlugins::HmacPaths::InstanceMethods)
  • +
  • #hmac_path_hmac (Roda::RodaPlugins::HmacPaths::InstanceMethods)
  • #http_version (Roda::RodaPlugins::Base::RequestMethods)
  • +
  • #if_modified (Roda::RodaPlugins::Render::TemplateMtimeWrapper)
  • #include (Roda::RodaPlugins::Base::ClassMethods)
  • #include? (RodaSessionMiddleware::SessionHash)
  • #informational? (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • -
  • #inherited (Roda::RodaPlugins::MultiRoute::ClassMethods)
  • -
  • #inherited (Roda::RodaPlugins::TypecastParams::ClassMethods)
  • -
  • #inherited (Roda::RodaPlugins::Base::ClassMethods)
  • -
  • #inherited (Roda::RodaPlugins::NamedRoutes::ClassMethods)
  • #inherited (Roda::RodaPlugins::HashBranches::ClassMethods)
  • #inherited (Roda::RodaPlugins::HashPaths::ClassMethods)
  • #inherited (Roda::RodaPlugins::Render::ClassMethods)
  • +
  • #inherited (Roda::RodaPlugins::TypecastParams::ClassMethods)
  • +
  • #inherited (Roda::RodaPlugins::MultiRoute::ClassMethods)
  • +
  • #inherited (Roda::RodaPlugins::Base::ClassMethods)
  • #inherited (Roda::RodaPlugins::HashBranchViewSubdir::ClassMethods)
  • +
  • #inherited (Roda::RodaPlugins::NamedRoutes::ClassMethods)
  • #inject_erb (Roda::RodaPlugins::InjectERB::InstanceMethods)
  • #inline_template_block (Roda::RodaPlugins::Render::ClassMethods)
  • #inspect (Roda::RodaPlugins::Base::ResponseClassMethods)
  • -
  • #inspect (Roda::RodaPlugins::Base::RequestClassMethods)
  • #inspect (Roda::RodaPlugins::Base::ResponseMethods)
  • -
  • #inspect (RodaSessionMiddleware::SessionHash)
  • #inspect (Roda::RodaPlugins::Base::RequestMethods)
  • -
  • #is (Roda::RodaPlugins::OptimizedMatching::RequestMethods)
  • -
  • #is (Roda::RodaPlugins::NotAllowed::RequestMethods)
  • +
  • #inspect (Roda::RodaPlugins::Base::RequestClassMethods)
  • +
  • #inspect (RodaSessionMiddleware::SessionHash)
  • #is (Roda::RodaPlugins::Base::RequestMethods)
  • #is (Roda::RodaPlugins::HashRoutes::DSL)
  • +
  • #is (Roda::RodaPlugins::OptimizedMatching::RequestMethods)
  • +
  • #is (Roda::RodaPlugins::NotAllowed::RequestMethods)
  • #is_exactly (Roda::RodaPlugins::OptimizedStringMatchers::RequestMethods)
  • -
  • #is_get? (Roda::RodaPlugins::Head::RequestMethods)
  • #is_get? (Roda::RodaPlugins::Base::RequestMethods)
  • +
  • #is_get? (Roda::RodaPlugins::Head::RequestMethods)
  • #is_segment (Roda::RodaPlugins::OptimizedSegmentMatchers::RequestMethods)
  • #join (Roda::RodaPlugins::SinatraHelpers::DelayedBody)
  • #json_result_classes (Roda::RodaPlugins::Json::ClassMethods)
  • @@ -440,9 +445,9 @@
  • #length (Roda::RodaPlugins::SinatraHelpers::DelayedBody)
  • #link_to (Roda::RodaPlugins::LinkTo::InstanceMethods)
  • #loaded? (RodaSessionMiddleware::SessionHash)
  • +
  • #mail (Roda::RodaPlugins::Mailer::ClassMethods)
  • #mail (Roda::RodaPlugins::Mailer::RequestMethods)
  • #mail (Roda::RodaPlugins::MailProcessor::InstanceMethods)
  • -
  • #mail (Roda::RodaPlugins::Mailer::ClassMethods)
  • #mail_attachments (Roda::RodaPlugins::Mailer::ResponseMethods)
  • #mail_recipients (Roda::RodaPlugins::MailProcessor::InstanceMethods)
  • #mail_text (Roda::RodaPlugins::MailProcessor::InstanceMethods)
  • @@ -454,13 +459,12 @@
  • #match_params! (Roda::RodaPlugins::ParamMatchers::RequestMethods)
  • #match_prefix (Roda::RodaPlugins::PathMatchers::RequestMethods)
  • #match_suffix (Roda::RodaPlugins::PathMatchers::RequestMethods)
  • -
  • #matched_path (Roda::RodaPlugins::UnescapePath::RequestMethods)
  • #matched_path (Roda::RodaPlugins::Base::RequestMethods)
  • +
  • #matched_path (Roda::RodaPlugins::UnescapePath::RequestMethods)
  • #merge! (RodaSessionMiddleware::SessionHash)
  • #middleware_stack (Roda::RodaPlugins::MiddlewareStack::ClassMethods)
  • -
  • #mime_type (Roda::RodaPlugins::SinatraHelpers::ClassMethods)
  • #mime_type (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • -
  • #modified? (Roda::RodaPlugins::Render::TemplateMtimeWrapper)
  • +
  • #mime_type (Roda::RodaPlugins::SinatraHelpers::ClassMethods)
  • #multi_public (Roda::RodaPlugins::MultiPublic::RequestMethods)
  • #multi_route (Roda::RodaPlugins::MultiRoute::RequestMethods)
  • #multi_run (Roda::RodaPlugins::MultiRun::RequestMethods)
  • @@ -475,12 +479,12 @@
  • #new (Roda::RodaPlugins::Middleware::ClassMethods)
  • #no_chunk! (Roda::RodaPlugins::Chunked::InstanceMethods)
  • #no_mail! (Roda::RodaPlugins::Mailer::InstanceMethods)
  • -
  • #not_found (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • #not_found (Roda::RodaPlugins::NotFound::ClassMethods)
  • +
  • #not_found (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • #not_found? (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • -
  • #on (Roda::RodaPlugins::HashRoutes::DSL)
  • -
  • #on (Roda::RodaPlugins::OptimizedMatching::RequestMethods)
  • #on (Roda::RodaPlugins::Base::RequestMethods)
  • +
  • #on (Roda::RodaPlugins::OptimizedMatching::RequestMethods)
  • +
  • #on (Roda::RodaPlugins::HashRoutes::DSL)
  • #on_branch (Roda::RodaPlugins::OptimizedStringMatchers::RequestMethods)
  • #on_segment (Roda::RodaPlugins::OptimizedSegmentMatchers::RequestMethods)
  • #on_type (Roda::RodaPlugins::TypeRouting::RequestMethods)
  • @@ -498,8 +502,8 @@
  • #path (Roda::RodaPlugins::Path::ClassMethods)
  • #path_block (Roda::RodaPlugins::Path::ClassMethods)
  • #path_classes (Roda::RodaPlugins::Path::ClassMethods)
  • -
  • #permissions_policy (Roda::RodaPlugins::PermissionsPolicy::ResponseMethods)
  • #permissions_policy (Roda::RodaPlugins::PermissionsPolicy::InstanceMethods)
  • +
  • #permissions_policy (Roda::RodaPlugins::PermissionsPolicy::ResponseMethods)
  • #persist_session (Roda::RodaPlugins::Sessions::RequestMethods)
  • #plugin (Roda::RodaPlugins::Base::ClassMethods)
  • #post (Roda::RodaPlugins::Base::RequestMethods)
  • @@ -508,30 +512,30 @@
  • #preload_assets_link_header (Roda::RodaPlugins::AssetsPreloading::InstanceMethods)
  • #preload_assets_link_tags (Roda::RodaPlugins::AssetsPreloading::InstanceMethods)
  • #present? (Roda::RodaPlugins::TypecastParams::Params)
  • -
  • #process_mail (Roda::RodaPlugins::MailProcessor::InstanceMethods)
  • #process_mail (Roda::RodaPlugins::MailProcessor::ClassMethods)
  • +
  • #process_mail (Roda::RodaPlugins::MailProcessor::InstanceMethods)
  • #process_mailbox (Roda::RodaPlugins::MailProcessor::ClassMethods)
  • #public (Roda::RodaPlugins::Public::RequestMethods)
  • #r (Roda::RodaPlugins::R::InstanceMethods)
  • #rcpt (Roda::RodaPlugins::MailProcessor::ClassMethods)
  • #read_asset_file (Roda::RodaPlugins::Assets::InstanceMethods)
  • #real_remaining_path (Roda::RodaPlugins::TypeRouting::RequestMethods)
  • -
  • #redirect (Roda::RodaPlugins::Base::ResponseMethods)
  • -
  • #redirect (Roda::RodaPlugins::Base::RequestMethods)
  • #redirect (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • +
  • #redirect (Roda::RodaPlugins::Base::RequestMethods)
  • +
  • #redirect (Roda::RodaPlugins::Base::ResponseMethods)
  • #redirect? (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • #redirect_http_to_https (Roda::RodaPlugins::RedirectHttpToHttps::RequestMethods)
  • #refresh_multi_run_regexp! (Roda::RodaPlugins::MultiRun::RequestClassMethods)
  • #relative_path (Roda::RodaPlugins::RelativePath::InstanceMethods)
  • #relative_prefix (Roda::RodaPlugins::RelativePath::InstanceMethods)
  • #remove (Roda::RodaPlugins::MiddlewareStack::Stack)
  • -
  • #render (Roda::RodaPlugins::Render::InstanceMethods)
  • -
  • #render (Roda::RodaPlugins::PadrinoRender::InstanceMethods)
  • #render (Roda::RodaPlugins::Render::TemplateMtimeWrapper)
  • +
  • #render (Roda::RodaPlugins::PadrinoRender::InstanceMethods)
  • +
  • #render (Roda::RodaPlugins::Render::InstanceMethods)
  • #render_asset (Roda::RodaPlugins::Assets::InstanceMethods)
  • #render_each (Roda::RodaPlugins::RenderEach::InstanceMethods)
  • -
  • #render_opts (Roda::RodaPlugins::Render::ClassMethods)
  • #render_opts (Roda::RodaPlugins::Render::InstanceMethods)
  • +
  • #render_opts (Roda::RodaPlugins::Render::ClassMethods)
  • #replace (Roda::RodaPlugins::RecheckPrecompiledAssets::CompiledAssetsHash)
  • #replace (RodaSessionMiddleware::SessionHash)
  • #report_only (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • @@ -545,33 +549,33 @@
  • #response_delegate (Roda::RodaPlugins::Delegate::ClassMethods)
  • #response_module (Roda::RodaPlugins::ModuleInclude::ClassMethods)
  • #rewrite_path (Roda::RodaPlugins::PathRewriter::ClassMethods)
  • -
  • #roda_class (Roda::RodaPlugins::Base::ResponseMethods)
  • #roda_class (Roda::RodaPlugins::Base::RequestMethods)
  • +
  • #roda_class (Roda::RodaPlugins::Base::ResponseMethods)
  • +
  • #root (Roda::RodaPlugins::Base::RequestMethods)
  • #root (Roda::RodaPlugins::EmptyRoot::RequestMethods)
  • #root (Roda::RodaPlugins::NotAllowed::RequestMethods)
  • -
  • #root (Roda::RodaPlugins::Base::RequestMethods)
  • #route (Roda::RodaPlugins::MultiRoute::ClassMethods)
  • -
  • #route (Roda::RodaPlugins::Base::ClassMethods)
  • #route (Roda::RodaPlugins::NamedRoutes::ClassMethods)
  • #route (Roda::RodaPlugins::NamedRoutes::RequestMethods)
  • -
  • #run (Roda::RodaPlugins::RunHandler::RequestMethods)
  • +
  • #route (Roda::RodaPlugins::Base::ClassMethods)
  • #run (Roda::RodaPlugins::RunRequireSlash::RequestMethods)
  • +
  • #run (Roda::RodaPlugins::RunHandler::RequestMethods)
  • +
  • #run (Roda::RodaPlugins::MultiRun::ClassMethods)
  • #run (Roda::RodaPlugins::RunAppendSlash::RequestMethods)
  • #run (Roda::RodaPlugins::Base::RequestMethods)
  • -
  • #run (Roda::RodaPlugins::MultiRun::ClassMethods)
  • #send_early_hints (Roda::RodaPlugins::EarlyHints::InstanceMethods)
  • #send_file (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • #sendmail (Roda::RodaPlugins::Mailer::ClassMethods)
  • #server_error? (Roda::RodaPlugins::SinatraHelpers::ResponseMethods)
  • -
  • #session (Roda::RodaPlugins::Base::RequestMethods)
  • #session (Roda::RodaPlugins::Sessions::RequestMethods)
  • +
  • #session (Roda::RodaPlugins::Base::RequestMethods)
  • #session (Roda::RodaPlugins::Base::InstanceMethods)
  • #session_created_at (Roda::RodaPlugins::Sessions::RequestMethods)
  • #session_updated_at (Roda::RodaPlugins::Sessions::RequestMethods)
  • #set_cookie (Roda::RodaPlugins::Cookies::ResponseMethods)
  • #set_default_headers (Roda::RodaPlugins::Base::ClassMethods)
  • -
  • #set_header (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • #set_header (Roda::RodaPlugins::PermissionsPolicy::Policy)
  • +
  • #set_header (Roda::RodaPlugins::ContentSecurityPolicy::Policy)
  • #set_layout_locals (Roda::RodaPlugins::BranchLocals::InstanceMethods)
  • #set_layout_options (Roda::RodaPlugins::ViewOptions::InstanceMethods)
  • #set_view_locals (Roda::RodaPlugins::BranchLocals::InstanceMethods)
  • @@ -603,17 +607,17 @@
  • #uri (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • #url (Roda::RodaPlugins::Path::InstanceMethods)
  • #url (Roda::RodaPlugins::SinatraHelpers::RequestMethods)
  • -
  • #use (Roda::RodaPlugins::MiddlewareStack::StackPosition)
  • #use (Roda::RodaPlugins::Base::ClassMethods)
  • +
  • #use (Roda::RodaPlugins::MiddlewareStack::StackPosition)
  • #use_request_specific_csrf_tokens? (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • #valid_csrf? (Roda::RodaPlugins::RouteCsrf::InstanceMethods)
  • #values (RodaSessionMiddleware::SessionHash)
  • -
  • #view (Roda::RodaPlugins::HashRoutes::DSL)
  • #view (Roda::RodaPlugins::Render::InstanceMethods)
  • #view (Roda::RodaPlugins::Chunked::InstanceMethods)
  • +
  • #view (Roda::RodaPlugins::HashRoutes::DSL)
  • #views (Roda::RodaPlugins::HashRoutes::DSL)
  • -
  • #write (Roda::RodaPlugins::Base::ResponseMethods)
  • #write (Roda::RodaPlugins::Streaming::Stream)
  • +
  • #write (Roda::RodaPlugins::Base::ResponseMethods)