roda 3.105.0 → 3.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/roda/plugins/assets.rb +46 -2
- data/lib/roda/plugins/branch_locals.rb +2 -0
- data/lib/roda/plugins/chunked.rb +4 -2
- data/lib/roda/plugins/common_logger.rb +2 -0
- data/lib/roda/plugins/content_for.rb +2 -0
- data/lib/roda/plugins/content_security_policy.rb +4 -0
- data/lib/roda/plugins/csrf.rb +3 -0
- data/lib/roda/plugins/delay_build.rb +2 -0
- data/lib/roda/plugins/flash.rb +2 -0
- data/lib/roda/plugins/host_routing.rb +4 -0
- data/lib/roda/plugins/indifferent_params.rb +2 -0
- data/lib/roda/plugins/mailer.rb +2 -0
- data/lib/roda/plugins/middleware.rb +1 -0
- data/lib/roda/plugins/not_allowed.rb +2 -0
- data/lib/roda/plugins/params_capturing.rb +2 -0
- data/lib/roda/plugins/permissions_policy.rb +4 -0
- data/lib/roda/plugins/relative_path.rb +2 -0
- data/lib/roda/plugins/request_headers.rb +2 -0
- data/lib/roda/plugins/response_request.rb +7 -0
- data/lib/roda/plugins/route_block_args.rb +6 -0
- data/lib/roda/plugins/sessions.rb +7 -2
- data/lib/roda/plugins/shape_friendly.rb +232 -0
- data/lib/roda/plugins/sinatra_helpers.rb +1 -0
- data/lib/roda/plugins/static.rb +11 -0
- data/lib/roda/plugins/type_routing.rb +4 -2
- data/lib/roda/plugins/typecast_params.rb +2 -0
- data/lib/roda/plugins/url_escape.rb +39 -0
- data/lib/roda/plugins/view_options.rb +2 -0
- data/lib/roda/request.rb +2 -1
- data/lib/roda/session_middleware.rb +2 -1
- data/lib/roda/version.rb +1 -1
- data/lib/roda.rb +17 -5
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 84bb84bd98ebe0d00d48315d9036ae1c22d93c92715922a6dba297f225c9fec7
|
|
4
|
+
data.tar.gz: 7cf2abbe3656ec22aef206a4e895c2520a8f80dc0ed11ec058a8a5f4cf3194b5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 874ed7d5065e77c593bccd1939d3742acf3e65a0b6ea6eb95e02cd6ce9ca55c9819cfafe6ecfc61ce548075832b91c68800e7f5ae35774efb60949f0a86cb1ae
|
|
7
|
+
data.tar.gz: 40a37368dfc79527849fec46d615c26680cad15dd590b8b6a3dba0fa2809c2b90bacefa70f65b78566f88c62485f97afd715494a214fcc87050125ac7743d519
|
data/lib/roda/plugins/assets.rb
CHANGED
|
@@ -159,6 +159,35 @@ class Roda
|
|
|
159
159
|
# plugin :assets,
|
|
160
160
|
# css_opts: {style: :compressed}
|
|
161
161
|
#
|
|
162
|
+
# In Roda 4, automatic compression of assets will not be attempted. You will
|
|
163
|
+
# need to specify the compressor to use using a Proc or Method. Here are values
|
|
164
|
+
# that you can use.
|
|
165
|
+
#
|
|
166
|
+
# ==== yui
|
|
167
|
+
#
|
|
168
|
+
# require 'yuicompressor'
|
|
169
|
+
# plugin :assets,
|
|
170
|
+
# css_compressor: lambda{|v| ::YUICompressor.compress_css(v, munge: true) },
|
|
171
|
+
# js_compressor: lambda{|v| ::YUICompressor.compress_js(v, munge: true) }
|
|
172
|
+
#
|
|
173
|
+
# ==== closure-compiler
|
|
174
|
+
#
|
|
175
|
+
# require 'closure-compiler'
|
|
176
|
+
# plugin :assets, js_compressor: ::Closure::Compiler.new.method(:compile)
|
|
177
|
+
#
|
|
178
|
+
# ==== uglifier
|
|
179
|
+
#
|
|
180
|
+
# require 'uglifier'
|
|
181
|
+
# plugin :assets, js_compressor: Uglifier.method(:compile)
|
|
182
|
+
#
|
|
183
|
+
# ==== minjs
|
|
184
|
+
#
|
|
185
|
+
# require 'minjs'
|
|
186
|
+
# plugin :assets,
|
|
187
|
+
# js_compressor: proc { |content|
|
|
188
|
+
# Minjs::Compressor::Compressor.new(debug: false).compress(content).to_js
|
|
189
|
+
# }
|
|
190
|
+
#
|
|
162
191
|
# === Source Maps (CSS)
|
|
163
192
|
#
|
|
164
193
|
# The assets plugin does not have direct support for source maps, so it is
|
|
@@ -274,7 +303,7 @@ class Roda
|
|
|
274
303
|
# :compiled_path:: Path inside public folder in which compiled files are stored (default: :prefix)
|
|
275
304
|
# :concat_only :: Whether to just concatenate instead of concatenating
|
|
276
305
|
# and compressing files (default: false)
|
|
277
|
-
# :css_compressor :: Compressor to use for compressing CSS, either :yui, :none, or nil (the default, which will try
|
|
306
|
+
# :css_compressor :: Compressor to use for compressing CSS, either a Proc, Method, :yui, :none, or nil (the default, which will try
|
|
278
307
|
# :yui if available, but not fail if it is not available)
|
|
279
308
|
# :css_dir :: Directory name containing your css source, inside :path (default: 'css')
|
|
280
309
|
# :css_headers :: A hash of additional headers for your rendered css files
|
|
@@ -288,7 +317,7 @@ class Roda
|
|
|
288
317
|
# related group are contained in a subdirectory with the same name (default: true)
|
|
289
318
|
# :gzip :: Store gzipped compiled assets files, and serve those to clients who accept gzip encoding.
|
|
290
319
|
# :headers :: A hash of additional headers for both js and css rendered files
|
|
291
|
-
# :js_compressor :: Compressor to use for compressing javascript, either :yui, :closure, :uglifier, :minjs,
|
|
320
|
+
# :js_compressor :: Compressor to use for compressing javascript, either a Proc, Method, :yui, :closure, :uglifier, :minjs,
|
|
292
321
|
# :none, or nil (the default, which will try :yui, :closure, :uglifier, then :minjs, but
|
|
293
322
|
# not fail if any of them is not available)
|
|
294
323
|
# :js_dir :: Directory name containing your javascript source, inside :path (default: 'js')
|
|
@@ -454,6 +483,17 @@ class Roda
|
|
|
454
483
|
opts[:js_suffix] = (opts[:add_suffix] ? '.js' : '').freeze
|
|
455
484
|
opts[:css_suffix] = (opts[:add_suffix] ? '.css' : '').freeze
|
|
456
485
|
|
|
486
|
+
unless opts[:concat_only]
|
|
487
|
+
[:css_compressor, :js_compressor].each do |s|
|
|
488
|
+
case v = opts[s]
|
|
489
|
+
when nil, :none, Proc, Method
|
|
490
|
+
nil
|
|
491
|
+
else
|
|
492
|
+
RodaPlugins.warn "Support for the assets plugin #{s}: #{v.inspect} option will be removed in Roda 4. See the assets plugin documentation for how to use an appropriate proc or method."
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
|
|
457
497
|
opts.freeze
|
|
458
498
|
end
|
|
459
499
|
|
|
@@ -535,6 +575,7 @@ class Roda
|
|
|
535
575
|
app.read_asset_file(file, type)
|
|
536
576
|
end.join("\n")
|
|
537
577
|
|
|
578
|
+
# RODA4: Remove :concat_only option
|
|
538
579
|
unless o[:concat_only]
|
|
539
580
|
content = compress_asset(content, type)
|
|
540
581
|
end
|
|
@@ -564,6 +605,8 @@ class Roda
|
|
|
564
605
|
return content
|
|
565
606
|
when nil
|
|
566
607
|
# default, try different compressors
|
|
608
|
+
when Proc, Method
|
|
609
|
+
return compressor.call(content)
|
|
567
610
|
else
|
|
568
611
|
# Allow calling private compress methods
|
|
569
612
|
return send("compress_#{type}_#{compressor}", content)
|
|
@@ -579,6 +622,7 @@ class Roda
|
|
|
579
622
|
begin
|
|
580
623
|
# Allow calling private compress methods
|
|
581
624
|
if c = send("compress_#{type}_#{comp}", content)
|
|
625
|
+
RodaPlugins.warn "Support for automatic compression of assets by trying common asset compressor libraries will be removed in Roda 4. The #{comp} #{type.to_s.upcase} compressor is currently used. See the assets plugin documentation for how to use an appropriate value for the assets plugin :#{type}_compressor option."
|
|
582
626
|
return c
|
|
583
627
|
end
|
|
584
628
|
rescue LoadError, CompressorNotFound
|
|
@@ -21,6 +21,8 @@ class Roda
|
|
|
21
21
|
# have higher precedence than the render_locals plugin options, but lower precedence
|
|
22
22
|
# than options you directly pass to the view/render methods.
|
|
23
23
|
module BranchLocals
|
|
24
|
+
SCOPE_INSTANCE_VARIABLES = [:@_layout_locals, :@_view_locals].freeze
|
|
25
|
+
|
|
24
26
|
# Load the render_locals plugin before this plugin, since this plugin
|
|
25
27
|
# works by overriding methods in the render_locals plugin.
|
|
26
28
|
def self.load_dependencies(app)
|
data/lib/roda/plugins/chunked.rb
CHANGED
|
@@ -148,6 +148,8 @@ class Roda
|
|
|
148
148
|
# method is not called until template rendering, the flash may not be
|
|
149
149
|
# rotated.
|
|
150
150
|
module Chunked
|
|
151
|
+
SCOPE_INSTANCE_VARIABLES = [:@_chunked, :@_each_chunk_args, :@_delays, :@_flusher].freeze
|
|
152
|
+
|
|
151
153
|
# Depend on the render plugin
|
|
152
154
|
def self.load_dependencies(app, opts=OPTS)
|
|
153
155
|
app.plugin :render
|
|
@@ -215,7 +217,7 @@ class Roda
|
|
|
215
217
|
# If chunking by default, call chunked if it hasn't yet been
|
|
216
218
|
# called and chunking is not specifically disabled.
|
|
217
219
|
def view(*a)
|
|
218
|
-
if opts[:chunk_by_default] &&
|
|
220
|
+
if opts[:chunk_by_default] && @_chunked != false && !defined?(yield)
|
|
219
221
|
chunked(*a)
|
|
220
222
|
else
|
|
221
223
|
super
|
|
@@ -225,7 +227,7 @@ class Roda
|
|
|
225
227
|
# Render a response to the user in chunks. See Chunked for
|
|
226
228
|
# an overview. If a block is given, it is passed to #delay.
|
|
227
229
|
def chunked(template, opts=OPTS, &block)
|
|
228
|
-
|
|
230
|
+
if @_chunked.nil?
|
|
229
231
|
@_chunked = !self.opts[:force_chunked_encoding] || @_request.http_version == "HTTP/1.1"
|
|
230
232
|
end
|
|
231
233
|
|
|
@@ -20,6 +20,8 @@ class Roda
|
|
|
20
20
|
# plugin :common_logger, Logger.new('filename')
|
|
21
21
|
# plugin :common_logger, Logger.new('filename'), method: :debug
|
|
22
22
|
module CommonLogger
|
|
23
|
+
SCOPE_INSTANCE_VARIABLES = [:@_request_timer].freeze
|
|
24
|
+
|
|
23
25
|
MUTATE_LINE = RUBY_VERSION < '2.3' || RUBY_VERSION >= '3'
|
|
24
26
|
private_constant :MUTATE_LINE
|
|
25
27
|
|
|
@@ -55,6 +55,8 @@ class Roda
|
|
|
55
55
|
#
|
|
56
56
|
# plugin :content_for, append: false
|
|
57
57
|
module ContentFor
|
|
58
|
+
SCOPE_INSTANCE_VARIABLES = [:@_content_for].freeze
|
|
59
|
+
|
|
58
60
|
# Depend on the capture_erb plugin, since it uses capture_erb
|
|
59
61
|
# to capture the content.
|
|
60
62
|
def self.load_dependencies(app, _opts = OPTS)
|
|
@@ -111,6 +111,8 @@ class Roda
|
|
|
111
111
|
# is given. Also, there is a +report_only?+ method for returning whether report only
|
|
112
112
|
# mode is enabled.
|
|
113
113
|
module ContentSecurityPolicy
|
|
114
|
+
RESPONSE_INSTANCE_VARIABLES = [:@content_security_policy, :@skip_content_security_policy].freeze
|
|
115
|
+
|
|
114
116
|
# Represents a content security policy.
|
|
115
117
|
class Policy
|
|
116
118
|
'
|
|
@@ -192,6 +194,8 @@ class Roda
|
|
|
192
194
|
# Clear all settings, useful to remove any inherited settings.
|
|
193
195
|
def clear
|
|
194
196
|
@opts = {}
|
|
197
|
+
@report_only = nil
|
|
198
|
+
@header_value = nil
|
|
195
199
|
end
|
|
196
200
|
|
|
197
201
|
# Do not allow future modifications to any settings.
|
data/lib/roda/plugins/csrf.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
|
+
# RODA4: Remove plugin
|
|
4
|
+
|
|
3
5
|
require 'rack/csrf'
|
|
4
6
|
|
|
5
7
|
class Roda
|
|
@@ -7,6 +9,7 @@ class Roda
|
|
|
7
9
|
# This plugin is no longer recommended for use, it exists only for
|
|
8
10
|
# backwards compatibility. Consider using the route_csrf plugin
|
|
9
11
|
# instead, as that provides stronger CSRF protection.
|
|
12
|
+
# This plugin will no longer ship with Roda starting in Roda 4.
|
|
10
13
|
#
|
|
11
14
|
# The csrf plugin adds CSRF protection using rack_csrf, along with
|
|
12
15
|
# some csrf helper methods to use in your views. To use it, load
|
data/lib/roda/plugins/flash.rb
CHANGED
|
@@ -71,6 +71,8 @@ class Roda
|
|
|
71
71
|
# This plugin uses the host method on the request to get the hostname (this method
|
|
72
72
|
# is defined by Rack).
|
|
73
73
|
module HostRouting
|
|
74
|
+
REQUEST_INSTANCE_VARIABLES = [:@_host_routing_host].freeze
|
|
75
|
+
|
|
74
76
|
# Setup the host routing support. The block yields an object used to
|
|
75
77
|
# configure the plugin. Options:
|
|
76
78
|
#
|
|
@@ -110,6 +112,8 @@ class Roda
|
|
|
110
112
|
def initialize
|
|
111
113
|
@hosts = []
|
|
112
114
|
@host_hash = {}
|
|
115
|
+
@default_host = nil
|
|
116
|
+
@default_block = nil
|
|
113
117
|
end
|
|
114
118
|
|
|
115
119
|
# Run the DSL for the given block.
|
|
@@ -39,6 +39,8 @@ class Roda
|
|
|
39
39
|
# it affects all rack applications instead of just the Roda app that
|
|
40
40
|
# you load the plugin into.
|
|
41
41
|
module IndifferentParams
|
|
42
|
+
SCOPE_INSTANCE_VARIABLES = [:@_params].freeze
|
|
43
|
+
|
|
42
44
|
INDIFFERENT_PROC = lambda{|h,k| h[k.to_s] if k.is_a?(Symbol)}
|
|
43
45
|
|
|
44
46
|
if Rack.release > '2'
|
data/lib/roda/plugins/mailer.rb
CHANGED
|
@@ -127,6 +127,8 @@ class Roda
|
|
|
127
127
|
# Roda application if you want your helper methods to automatically be
|
|
128
128
|
# available in your email views.
|
|
129
129
|
module Mailer
|
|
130
|
+
RESPONSE_INSTANCE_VARIABLES = [:@mail, :@mail_attachments].freeze
|
|
131
|
+
|
|
130
132
|
# Error raised when the using the mail class method, but the routing
|
|
131
133
|
# tree doesn't return the mail object.
|
|
132
134
|
class Error < ::Roda::RodaError; end
|
|
@@ -125,6 +125,7 @@ class Roda
|
|
|
125
125
|
app.opts[:middleware_configure] = block if block
|
|
126
126
|
app.opts[:middleware_handle_result] = opts[:handle_result]
|
|
127
127
|
app.opts[:middleware_forward_response_headers] = opts[:forward_response_headers]
|
|
128
|
+
# RODA4: Make next_if_not_found default to true
|
|
128
129
|
app.opts[:middleware_next_if_not_found] = opts[:next_if_not_found]
|
|
129
130
|
end
|
|
130
131
|
|
|
@@ -68,6 +68,8 @@ class Roda
|
|
|
68
68
|
#
|
|
69
69
|
# This plugin depends on the all_verbs plugin.
|
|
70
70
|
module NotAllowed
|
|
71
|
+
REQUEST_INSTANCE_VARIABLES = [:@_is_verbs].freeze
|
|
72
|
+
|
|
71
73
|
# Depend on the all_verbs plugin, as this plugin overrides methods
|
|
72
74
|
# defined by it and calls super.
|
|
73
75
|
def self.load_dependencies(app)
|
|
@@ -55,6 +55,8 @@ class Roda
|
|
|
55
55
|
# the symbol_matchers plugin with custom symbol matching and are using
|
|
56
56
|
# symbols that capture multiple values or no values.
|
|
57
57
|
module ParamsCapturing
|
|
58
|
+
REQUEST_INSTANCE_VARIABLES = [:@_params_captures].freeze
|
|
59
|
+
|
|
58
60
|
module RequestMethods
|
|
59
61
|
# Lazily initialize captures entry when params is called.
|
|
60
62
|
def params
|
|
@@ -104,6 +104,8 @@ class Roda
|
|
|
104
104
|
# setting a policy. This is faster than calling +permissions_policy.clear+, since
|
|
105
105
|
# it does not duplicate the default policy.
|
|
106
106
|
module PermissionsPolicy
|
|
107
|
+
RESPONSE_INSTANCE_VARIABLES = [:@permissions_policy, :@skip_permissions_policy].freeze
|
|
108
|
+
|
|
107
109
|
SUPPORTED_SETTINGS = %w'
|
|
108
110
|
accelerometer
|
|
109
111
|
ambient-light-sensor
|
|
@@ -180,6 +182,8 @@ class Roda
|
|
|
180
182
|
# Clear all settings, useful to remove any inherited settings.
|
|
181
183
|
def clear
|
|
182
184
|
@opts = {}
|
|
185
|
+
@report_only = nil
|
|
186
|
+
@header_value = nil
|
|
183
187
|
end
|
|
184
188
|
|
|
185
189
|
# Do not allow future modifications to any settings.
|
|
@@ -31,6 +31,8 @@ class Roda
|
|
|
31
31
|
# This plugin is mostly designed for applications using Roda as a static
|
|
32
32
|
# site generator, where the generated site can be hosted at any subpath.
|
|
33
33
|
module RelativePath
|
|
34
|
+
SCOPE_INSTANCE_VARIABLES = [:@_relative_prefix].freeze
|
|
35
|
+
|
|
34
36
|
module InstanceMethods
|
|
35
37
|
# Return a relative path for the absolute path based on the current path
|
|
36
38
|
# of the request by adding the appropriate prefix.
|
|
@@ -10,6 +10,13 @@ class Roda
|
|
|
10
10
|
#
|
|
11
11
|
# plugin :response_request
|
|
12
12
|
module ResponseRequest
|
|
13
|
+
# This isn't set because it breaks usage with the error_handler/class_level_routing
|
|
14
|
+
# plugins and the shape_friendly plugin, due to those calling RodaResponse#initialize,
|
|
15
|
+
# which would reset @request to nil. It isn't strictly necessary to set this for
|
|
16
|
+
# shape friendliness, as the Roda#initialize sets it directly after creating the
|
|
17
|
+
# RodaRequest, so in normal use, the instance variable will already be set.
|
|
18
|
+
# RESPONSE_INSTANCE_VARIABLES = [:@request].freeze
|
|
19
|
+
|
|
13
20
|
module InstanceMethods
|
|
14
21
|
# Set the response's request to the current request.
|
|
15
22
|
def initialize(env)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
|
+
# RODA4: Remove plugin
|
|
4
|
+
|
|
3
5
|
#
|
|
4
6
|
class Roda
|
|
5
7
|
module RodaPlugins
|
|
@@ -22,6 +24,10 @@ class Roda
|
|
|
22
24
|
# end
|
|
23
25
|
# end
|
|
24
26
|
# end
|
|
27
|
+
#
|
|
28
|
+
# This plugin will be no longer ship with Roda starting in Roda 4. Users
|
|
29
|
+
# are encouraged to switch to defining local variables at the top of the
|
|
30
|
+
# route block instead of using this plugin.
|
|
25
31
|
module RouteBlockArgs
|
|
26
32
|
def self.configure(app, &block)
|
|
27
33
|
app.instance_exec do
|
|
@@ -67,7 +67,7 @@ class Roda
|
|
|
67
67
|
# given, it will be merged into the default cookie options.
|
|
68
68
|
# :env_key :: The key in `env` where the session should be located. Defaults to <tt>"rack.session"</tt>, the
|
|
69
69
|
# default key for sessions in Rack.
|
|
70
|
-
# :gzip_over :: For session data over this many bytes, compress it with the deflate algorithm (default: nil,
|
|
70
|
+
# :gzip_over (deprecated) :: For session data over this many bytes, compress it with the deflate algorithm (default: nil,
|
|
71
71
|
# so never compress). Note that compression should not be enabled if you are storing data in
|
|
72
72
|
# the session derived from user input and also storing sensitive data in the session.
|
|
73
73
|
# :key :: The cookie name to use (default: <tt>'roda.session'</tt>)
|
|
@@ -94,7 +94,7 @@ class Roda
|
|
|
94
94
|
# (default: 3600).
|
|
95
95
|
# :upgrade_from_rack_session_cookie_key :: The cookie name to use for transparently upgrading from
|
|
96
96
|
# Rack::Session:Cookie (defaults to <tt>'rack.session'</tt>).
|
|
97
|
-
# :upgrade_from_rack_session_cookie_secret :: The secret for the HMAC-SHA1 signature when allowing
|
|
97
|
+
# :upgrade_from_rack_session_cookie_secret (deprecated) :: The secret for the HMAC-SHA1 signature when allowing
|
|
98
98
|
# transparent upgrades from Rack::Session::Cookie. Using this
|
|
99
99
|
# option is only recommended during a short transition period,
|
|
100
100
|
# and is not enabled by default as it lowers security.
|
|
@@ -189,12 +189,17 @@ class Roda
|
|
|
189
189
|
opts[:session_version_num] = opts[:per_cookie_cipher_secret] ? 1 : 0
|
|
190
190
|
|
|
191
191
|
if opts[:upgrade_from_rack_session_cookie_secret]
|
|
192
|
+
RodaPlugins.warn("Support for upgrading rack session cookie sessions will be removed in Roda 4.")
|
|
192
193
|
opts[:upgrade_from_rack_session_cookie_key] ||= 'rack.session'
|
|
193
194
|
rsco = opts[:upgrade_from_rack_session_cookie_options] = Hash[opts[:upgrade_from_rack_session_cookie_options] || OPTS]
|
|
194
195
|
rsco[:path] ||= co[:path]
|
|
195
196
|
rsco[:domain] ||= co[:domain]
|
|
196
197
|
end
|
|
197
198
|
|
|
199
|
+
if opts[:gzip_over]
|
|
200
|
+
RodaPlugins.warn("Support for compressing session data will be removed in Roda 4.")
|
|
201
|
+
end
|
|
202
|
+
|
|
198
203
|
opts[:cipher_secret], opts[:hmac_secret] = split_secret(:secret, opts[:secret])
|
|
199
204
|
opts[:old_cipher_secret], opts[:old_hmac_secret] = (split_secret(:old_secret, opts[:old_secret]) if opts[:old_secret])
|
|
200
205
|
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
class Roda
|
|
5
|
+
module RodaPlugins
|
|
6
|
+
# The shape_friendly plugin makes the scope, request, and response objects
|
|
7
|
+
# used by Roda friendly to object shapes, which can result in better
|
|
8
|
+
# performance on modern versions of Ruby, especially when the JIT compiler
|
|
9
|
+
# is enabled. All plugins shipped with Roda integrate with this plugin.
|
|
10
|
+
#
|
|
11
|
+
# In order for this behavior to be beneficial for your application, you
|
|
12
|
+
# need to either avoid setting instance variables inside your routing
|
|
13
|
+
# tree, or you need to register each instance variable used, to ensure
|
|
14
|
+
# that all instances have the same shape.
|
|
15
|
+
#
|
|
16
|
+
# If you want to avoid using instance variables in your routing tree, you
|
|
17
|
+
# can switch to using local variables. If using the render plugin, you can
|
|
18
|
+
# pass data from your routing tree to your views using the +:locals+ option.
|
|
19
|
+
# When passing data from your routing tree to other routing trees, such as
|
|
20
|
+
# when using the hash_branches plugin, you can use the shared_vars plugin,
|
|
21
|
+
# which stores the data in the Rack environment.
|
|
22
|
+
#
|
|
23
|
+
# To register instance variables set in your applications routing tree,
|
|
24
|
+
# use a +:scope_instance_variables+ option when loading the plugin,
|
|
25
|
+
# listing the instance variable symbols you are setting in the route
|
|
26
|
+
# block scope:
|
|
27
|
+
#
|
|
28
|
+
# class MyApp < Roda
|
|
29
|
+
# plugin :shape_friendly, scope_instance_variables: [:@var1, @:var2]
|
|
30
|
+
#
|
|
31
|
+
# route do |r|
|
|
32
|
+
# r.root do
|
|
33
|
+
# @var1 = "a"
|
|
34
|
+
# @var1.inspect
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# @var2 = "b"
|
|
38
|
+
# @var2.inspect
|
|
39
|
+
# end
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# When developing external plugins, you can set one of three constants in
|
|
43
|
+
# the plugin module to integrate with this plugin to support shape friendly
|
|
44
|
+
# behavior:
|
|
45
|
+
#
|
|
46
|
+
# * +SCOPE_INSTANCE_VARIABLES+: For instance variables set in +InstanceMethods+.
|
|
47
|
+
# * +REQUEST_INSTANCE_VARIABLES+: For instance variables set in +RequestMethods+.
|
|
48
|
+
# * +RESPONSE_INSTANCE_VARIABLES+: For instance variables set in +ResponseMethods+.
|
|
49
|
+
#
|
|
50
|
+
# These constants are set in the plugin module, not in the plugin's
|
|
51
|
+
# +InstanceMethods+, +RequestMethods+, or +ResponseMethods+ modules, to
|
|
52
|
+
# avoid pollution of the related namespaces in the class loading the plugin.
|
|
53
|
+
module ShapeFriendly
|
|
54
|
+
# This is used by the base support and not by this plugin.
|
|
55
|
+
RESPONSE_INSTANCE_VARIABLES = [:@status].freeze
|
|
56
|
+
|
|
57
|
+
# Set the Roda application to create the private
|
|
58
|
+
# _initialize_nil_instance_variables for the plugin to use.
|
|
59
|
+
def self.configure(app, opts=OPTS)
|
|
60
|
+
if scope_ivs = opts[:scope_instance_variables]
|
|
61
|
+
app.opts[:shape_friendly_scope_instance_variables] = Array(scope_ivs).dup.freeze
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
app.instance_exec do
|
|
65
|
+
def_initialize_nil_instance_variables(app, :SCOPE_INSTANCE_VARIABLES)
|
|
66
|
+
def_initialize_nil_instance_variables(app::RodaRequest, :REQUEST_INSTANCE_VARIABLES)
|
|
67
|
+
def_initialize_nil_instance_variables(app::RodaResponse, :RESPONSE_INSTANCE_VARIABLES)
|
|
68
|
+
|
|
69
|
+
# Avoid overhead of super call if possible
|
|
70
|
+
include(instance_method(:initialize).owner == Roda::RodaPlugins::Base::InstanceMethods ? OptimizedInstanceMethods : UnoptimizedInstanceMethods)
|
|
71
|
+
app::RodaRequest.send(:include, app::RodaRequest.instance_method(:initialize).owner == Roda::RodaPlugins::Base::RequestMethods ? OptimizedRequestMethods : UnoptimizedRequestMethods)
|
|
72
|
+
app::RodaResponse.send(:include, app::RodaResponse.instance_method(:initialize).owner == Roda::RodaPlugins::Base::ResponseMethods ? OptimizedResponseMethods : UnoptimizedResponseMethods)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
module ClassMethods
|
|
77
|
+
# Automatically refresh the instance variables used if the plugin
|
|
78
|
+
# sets instance variables.
|
|
79
|
+
def plugin(plugin, *args, &block)
|
|
80
|
+
super
|
|
81
|
+
plugin = RodaPlugins.load_plugin(plugin) if plugin.is_a?(Symbol)
|
|
82
|
+
[
|
|
83
|
+
[self, :SCOPE_INSTANCE_VARIABLES],
|
|
84
|
+
[self::RodaRequest, :REQUEST_INSTANCE_VARIABLES],
|
|
85
|
+
[self::RodaResponse, :RESPONSE_INSTANCE_VARIABLES],
|
|
86
|
+
].each do |klass, ivs_const|
|
|
87
|
+
if plugin.const_defined?(ivs_const)
|
|
88
|
+
def_initialize_nil_instance_variables(klass, ivs_const)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
# :nocov:
|
|
94
|
+
ruby2_keywords(:plugin) if respond_to?(:ruby2_keywords, true)
|
|
95
|
+
# :nocov:
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
# If there are any intance variables configured in one of the plugins
|
|
100
|
+
# (looking for the +const+ constant in the plugin), override the
|
|
101
|
+
# private _initialize_nil_instance_variables method for the class,
|
|
102
|
+
# and have it initialize each instance variable to nil.
|
|
103
|
+
def def_initialize_nil_instance_variables(klass, const)
|
|
104
|
+
ivs = []
|
|
105
|
+
|
|
106
|
+
plugins.each do |mod|
|
|
107
|
+
ivs.concat(mod.const_get(const)) if mod.const_defined?(const)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
if const == :SCOPE_INSTANCE_VARIABLES && (scope_ivs = opts[:shape_friendly_scope_instance_variables])
|
|
111
|
+
ivs.concat(scope_ivs)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
ivs.each do |iv|
|
|
115
|
+
unless /\A@[a-z_][a-z0-9_]*\z/.match(iv)
|
|
116
|
+
raise RodaError, "invalid scope instance variable used"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
unless ivs.empty?
|
|
121
|
+
ivs.uniq!
|
|
122
|
+
|
|
123
|
+
klass.class_eval(<<-RUBY, __FILE__, __LINE__+1)
|
|
124
|
+
def _initialize_nil_instance_variables
|
|
125
|
+
#{ivs.reverse.join(" = ")} = nil
|
|
126
|
+
end
|
|
127
|
+
private :_initialize_nil_instance_variables
|
|
128
|
+
alias _initialize_nil_instance_variables _initialize_nil_instance_variables
|
|
129
|
+
RUBY
|
|
130
|
+
nil
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# :nocov:
|
|
136
|
+
if RUBY_VERSION >= '4.0'
|
|
137
|
+
# :nocov:
|
|
138
|
+
module InstanceMethods
|
|
139
|
+
private
|
|
140
|
+
|
|
141
|
+
def instance_variables_to_inspect
|
|
142
|
+
instance_variables.reject{|v| instance_variable_get(v).nil?}
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
module OptimizedInstanceMethods
|
|
148
|
+
# Initialize configured instance variables to nil.
|
|
149
|
+
def initialize(env)
|
|
150
|
+
_initialize_nil_instance_variables
|
|
151
|
+
klass = self.class
|
|
152
|
+
@_request = klass::RodaRequest.new(self, env)
|
|
153
|
+
@_response = klass::RodaResponse.new
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
private
|
|
157
|
+
|
|
158
|
+
def _initialize_nil_instance_variables
|
|
159
|
+
nil
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
module UnoptimizedInstanceMethods
|
|
164
|
+
# Initialize configured instance variables to nil.
|
|
165
|
+
def initialize(env)
|
|
166
|
+
_initialize_nil_instance_variables
|
|
167
|
+
super
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
private
|
|
171
|
+
|
|
172
|
+
def _initialize_nil_instance_variables
|
|
173
|
+
nil
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
module OptimizedRequestMethods
|
|
178
|
+
# Initialize configured instance variables to nil.
|
|
179
|
+
def initialize(scope, env)
|
|
180
|
+
_initialize_nil_instance_variables
|
|
181
|
+
@scope = scope
|
|
182
|
+
@captures = []
|
|
183
|
+
@remaining_path = _remaining_path(env)
|
|
184
|
+
@env = env
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
private
|
|
188
|
+
|
|
189
|
+
def _initialize_nil_instance_variables
|
|
190
|
+
nil
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
module UnoptimizedRequestMethods
|
|
195
|
+
# Initialize configured instance variables to nil.
|
|
196
|
+
def initialize(scope, env)
|
|
197
|
+
_initialize_nil_instance_variables
|
|
198
|
+
super
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
private
|
|
202
|
+
|
|
203
|
+
def _initialize_nil_instance_variables
|
|
204
|
+
nil
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
module OptimizedResponseMethods
|
|
209
|
+
def initialize
|
|
210
|
+
_initialize_nil_instance_variables
|
|
211
|
+
@headers = _initialize_headers
|
|
212
|
+
@body = []
|
|
213
|
+
@length = 0
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
module UnoptimizedResponseMethods
|
|
218
|
+
# Initialize configured instance variables to nil.
|
|
219
|
+
def initialize
|
|
220
|
+
_initialize_nil_instance_variables
|
|
221
|
+
super
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# For response methods, there is no default definition for
|
|
226
|
+
# _initialize_nil_instance_variables, as the plugin will always
|
|
227
|
+
# define a method in the class it is loaded into.
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
register_plugin(:shape_friendly, ShapeFriendly)
|
|
231
|
+
end
|
|
232
|
+
end
|
data/lib/roda/plugins/static.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
|
+
# RODA4: Remove plugin
|
|
4
|
+
|
|
3
5
|
require 'rack/static'
|
|
4
6
|
|
|
5
7
|
#
|
|
@@ -26,6 +28,15 @@ class Roda
|
|
|
26
28
|
# plugin :static, ['/js', '/css'] # path: /path/to/app/public
|
|
27
29
|
# plugin :static, ['/images'], root: 'pub' # path: /path/to/app/pub
|
|
28
30
|
# plugin :static, ['/media'], root: '/path/to/public' # path: /path/to/public
|
|
31
|
+
#
|
|
32
|
+
# This plugin will no longer ship with Roda starting in Roda 4. As the plugin only
|
|
33
|
+
# configures a middleware, you should switch to doing so directly. Translating
|
|
34
|
+
# the above example to direct middleware usage:
|
|
35
|
+
#
|
|
36
|
+
# require 'rack/static'
|
|
37
|
+
# use Rack::Static, urls: ['/js', '/css'], root: '/path/to/app/public'
|
|
38
|
+
# use Rack::Static, urls: ['/images'], root: '/path/to/app/pub'
|
|
39
|
+
# use Rack::Static, urls: ['/media'], root: '/path/to/public'
|
|
29
40
|
module Static
|
|
30
41
|
# Load the Rack::Static middleware. Use the paths given as the :urls option,
|
|
31
42
|
# and set the :root option to be relative to the application's :root option.
|
|
@@ -89,6 +89,8 @@ class Roda
|
|
|
89
89
|
# :use_header :: Whether to take the +Accept+ header into account.
|
|
90
90
|
# Default is +true+.
|
|
91
91
|
module TypeRouting
|
|
92
|
+
REQUEST_INSTANCE_VARIABLES = [:@requested_type, :@type_routing_extension].freeze
|
|
93
|
+
|
|
92
94
|
CONFIGURATION = {
|
|
93
95
|
:mimes => {
|
|
94
96
|
'text/json' => :json,
|
|
@@ -158,7 +160,7 @@ class Roda
|
|
|
158
160
|
|
|
159
161
|
# Returns the data type the client requests.
|
|
160
162
|
def requested_type
|
|
161
|
-
return @requested_type if
|
|
163
|
+
return @requested_type if @requested_type
|
|
162
164
|
|
|
163
165
|
opts = @scope.opts[:type_routing]
|
|
164
166
|
@requested_type = accept_response_type if opts[:use_header]
|
|
@@ -168,7 +170,7 @@ class Roda
|
|
|
168
170
|
# Append the type routing extension back to the path if it was
|
|
169
171
|
# removed before routing.
|
|
170
172
|
def real_remaining_path
|
|
171
|
-
if
|
|
173
|
+
if @type_routing_extension
|
|
172
174
|
"#{super}.#{@type_routing_extension}"
|
|
173
175
|
else
|
|
174
176
|
super
|
|
@@ -307,6 +307,8 @@ class Roda
|
|
|
307
307
|
# By design, typecast_params only deals with string keys, it is not possible to use
|
|
308
308
|
# symbol keys as arguments to the conversion methods and have them converted.
|
|
309
309
|
module TypecastParams
|
|
310
|
+
SCOPE_INSTANCE_VARIABLES = [:@_typecast_params, :@_typecast_query_params, :@_typecast_body_params].freeze
|
|
311
|
+
|
|
310
312
|
# Sentinal value for whether to raise exception during #process
|
|
311
313
|
CHECK_NIL = Object.new.freeze
|
|
312
314
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
require 'rack/utils'
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
class Roda
|
|
7
|
+
module RodaPlugins
|
|
8
|
+
# The url_escape plugin add url_escape and url_unescape methods
|
|
9
|
+
# to the route block scope.
|
|
10
|
+
#
|
|
11
|
+
# plugin :url_escape
|
|
12
|
+
#
|
|
13
|
+
# route do |r|
|
|
14
|
+
# link = "/path/q=#{url_escape(r.params["some_param"])}"
|
|
15
|
+
# response_body(link)
|
|
16
|
+
# end
|
|
17
|
+
module UrlEscape
|
|
18
|
+
module InstanceMethods
|
|
19
|
+
if RUBY_VERSION >= '2'
|
|
20
|
+
define_method(:url_escape, Rack::Utils.instance_method(:escape))
|
|
21
|
+
define_method(:url_unescape, Rack::Utils.instance_method(:unescape))
|
|
22
|
+
# :nocov:
|
|
23
|
+
else
|
|
24
|
+
def url_escape(v)
|
|
25
|
+
Rack::Utils.escape(v)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def url_unescape(v)
|
|
29
|
+
Rack::Utils.unescape(v)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
# :nocov:
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
register_plugin(:url_escape, UrlEscape)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
@@ -80,6 +80,8 @@ class Roda
|
|
|
80
80
|
# end
|
|
81
81
|
# end
|
|
82
82
|
module ViewOptions
|
|
83
|
+
SCOPE_INSTANCE_VARIABLES = [:@_view_subdir, :@_view_options, :@_layout_options].freeze
|
|
84
|
+
|
|
83
85
|
# Load the render plugin before this plugin, since this plugin
|
|
84
86
|
# works by overriding methods in the render plugin.
|
|
85
87
|
def self.load_dependencies(app)
|
data/lib/roda/request.rb
CHANGED
|
@@ -569,8 +569,9 @@ class Roda
|
|
|
569
569
|
if meth
|
|
570
570
|
return unless captures = scope.send(meth, *captures)
|
|
571
571
|
# :nocov:
|
|
572
|
+
# RODA4: Remove elsif block
|
|
572
573
|
elsif defined?(yield)
|
|
573
|
-
#
|
|
574
|
+
RodaPlugins.warn("Passing a block to RodaRequest#consume will be ignored in Roda 4. Update the code to pass a scope method symbol as the second argument.")
|
|
574
575
|
return unless captures = yield(*captures)
|
|
575
576
|
# :nocov:
|
|
576
577
|
end
|
|
@@ -29,6 +29,7 @@ class RodaSessionMiddleware
|
|
|
29
29
|
|
|
30
30
|
def initialize(req)
|
|
31
31
|
@req = req
|
|
32
|
+
@data = nil
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
# The Roda sessions plugin options used by the middleware for this
|
|
@@ -124,7 +125,7 @@ class RodaSessionMiddleware
|
|
|
124
125
|
|
|
125
126
|
# Whether the session has already been loaded from the cookie yet.
|
|
126
127
|
def loaded?
|
|
127
|
-
|
|
128
|
+
!!@data
|
|
128
129
|
end
|
|
129
130
|
|
|
130
131
|
def empty?
|
data/lib/roda/version.rb
CHANGED
data/lib/roda.rb
CHANGED
|
@@ -17,6 +17,7 @@ class Roda
|
|
|
17
17
|
@app = nil
|
|
18
18
|
@inherit_middleware = true
|
|
19
19
|
@middleware = []
|
|
20
|
+
@plugins = []
|
|
20
21
|
@opts = {}
|
|
21
22
|
@raw_route_block = nil
|
|
22
23
|
@route_block = nil
|
|
@@ -42,6 +43,9 @@ class Roda
|
|
|
42
43
|
# The settings/options hash for the current class.
|
|
43
44
|
attr_reader :opts
|
|
44
45
|
|
|
46
|
+
# The plugins loaded into the current class.
|
|
47
|
+
attr_reader :plugins
|
|
48
|
+
|
|
45
49
|
# The route block that this class uses.
|
|
46
50
|
attr_reader :route_block
|
|
47
51
|
|
|
@@ -67,29 +71,34 @@ class Roda
|
|
|
67
71
|
#
|
|
68
72
|
# If the :check_arity app option is not set to false, Roda will check that
|
|
69
73
|
# the arity of the block matches the expected arity, and compensate for
|
|
70
|
-
# cases where it does not.
|
|
71
|
-
# cases where the arity does not
|
|
74
|
+
# cases where it does not. The :check_arity default app option setting is
|
|
75
|
+
# :warn, in which case Roda will warn in the cases where the arity does not
|
|
76
|
+
# match what is expected.
|
|
72
77
|
#
|
|
73
78
|
# If the expected arity is :any, Roda must perform a dynamic arity check
|
|
74
79
|
# when the method is called, which can hurt performance even in the case
|
|
75
80
|
# where the arity matches. The :check_dynamic_arity app option can be
|
|
76
81
|
# set to false to turn off the dynamic arity checks. The
|
|
77
82
|
# :check_dynamic_arity app option can be to :warn to warn if Roda needs
|
|
78
|
-
# to adjust arity dynamically.
|
|
83
|
+
# to adjust arity dynamically. The default value of the :check_dynamic_arity
|
|
84
|
+
# app option is to use the same value as the :check_arity app option.
|
|
79
85
|
#
|
|
80
86
|
# Roda only checks arity for regular blocks, not lambda blocks, as the
|
|
81
87
|
# fixes Roda uses for regular blocks would not work for lambda blocks.
|
|
82
88
|
#
|
|
83
89
|
# Roda does not support blocks with required keyword arguments if the
|
|
84
90
|
# expected arity is 0 or 1.
|
|
91
|
+
#
|
|
92
|
+
# Support for the :check_arity and :check_dynamic_arity options will be
|
|
93
|
+
# removed in Roda 4.
|
|
85
94
|
def define_roda_method(meth, expected_arity, &block)
|
|
86
95
|
if meth.is_a?(String)
|
|
87
96
|
meth = roda_method_name(meth)
|
|
88
97
|
end
|
|
89
98
|
call_meth = meth
|
|
90
99
|
|
|
91
|
-
# RODA4:
|
|
92
|
-
if (check_arity = opts.fetch(:check_arity,
|
|
100
|
+
# RODA4: Remove support for :check_arity, default to false behavior
|
|
101
|
+
if (check_arity = opts.fetch(:check_arity, :warn)) && !block.lambda?
|
|
93
102
|
required_args, optional_args, rest, keyword = _define_roda_method_arg_numbers(block)
|
|
94
103
|
|
|
95
104
|
if keyword == :required && (expected_arity == 0 || expected_arity == 1)
|
|
@@ -224,6 +233,7 @@ class Roda
|
|
|
224
233
|
|
|
225
234
|
build_rack_app
|
|
226
235
|
@opts.freeze
|
|
236
|
+
@plugins.freeze
|
|
227
237
|
@middleware.freeze
|
|
228
238
|
|
|
229
239
|
super
|
|
@@ -250,6 +260,7 @@ class Roda
|
|
|
250
260
|
super
|
|
251
261
|
subclass.instance_variable_set(:@inherit_middleware, @inherit_middleware)
|
|
252
262
|
subclass.instance_variable_set(:@middleware, @inherit_middleware ? @middleware.dup : [])
|
|
263
|
+
subclass.instance_variable_set(:@plugins, @plugins.dup)
|
|
253
264
|
subclass.instance_variable_set(:@opts, opts.dup)
|
|
254
265
|
subclass.opts.delete(:subclassed)
|
|
255
266
|
subclass.opts.to_a.each do |k,v|
|
|
@@ -291,6 +302,7 @@ class Roda
|
|
|
291
302
|
end
|
|
292
303
|
|
|
293
304
|
plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
|
|
305
|
+
@plugins << plugin unless @plugins.include?(plugin)
|
|
294
306
|
include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
|
|
295
307
|
extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
|
|
296
308
|
self::RodaRequest.send(:include, plugin::RequestMethods) if defined?(plugin::RequestMethods)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: roda
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.107.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy Evans
|
|
@@ -292,6 +292,7 @@ files:
|
|
|
292
292
|
- lib/roda/plugins/sec_fetch_site_csrf.rb
|
|
293
293
|
- lib/roda/plugins/send_file.rb
|
|
294
294
|
- lib/roda/plugins/sessions.rb
|
|
295
|
+
- lib/roda/plugins/shape_friendly.rb
|
|
295
296
|
- lib/roda/plugins/shared_vars.rb
|
|
296
297
|
- lib/roda/plugins/sinatra_helpers.rb
|
|
297
298
|
- lib/roda/plugins/slash_path_empty.rb
|
|
@@ -309,6 +310,7 @@ files:
|
|
|
309
310
|
- lib/roda/plugins/typecast_params.rb
|
|
310
311
|
- lib/roda/plugins/typecast_params_sized_integers.rb
|
|
311
312
|
- lib/roda/plugins/unescape_path.rb
|
|
313
|
+
- lib/roda/plugins/url_escape.rb
|
|
312
314
|
- lib/roda/plugins/view_options.rb
|
|
313
315
|
- lib/roda/plugins/view_subdir_leading_slash.rb
|
|
314
316
|
- lib/roda/request.rb
|
|
@@ -338,7 +340,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
338
340
|
- !ruby/object:Gem::Version
|
|
339
341
|
version: '0'
|
|
340
342
|
requirements: []
|
|
341
|
-
rubygems_version: 4.0.
|
|
343
|
+
rubygems_version: 4.0.16
|
|
342
344
|
specification_version: 4
|
|
343
345
|
summary: Routing tree web toolkit
|
|
344
346
|
test_files: []
|