roda 3.92.0 → 3.93.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 +2 -2
- data/lib/roda/plugins/assets_preloading.rb +2 -2
- data/lib/roda/plugins/content_security_policy.rb +3 -3
- data/lib/roda/plugins/mail_processor.rb +4 -1
- data/lib/roda/plugins/permissions_policy.rb +2 -2
- data/lib/roda/plugins/render_coverage.rb +1 -1
- data/lib/roda/plugins/route_csrf.rb +1 -1
- data/lib/roda/plugins/strip_path_prefix.rb +1 -1
- data/lib/roda/plugins/typecast_params.rb +61 -31
- data/lib/roda/plugins/typecast_params_sized_integers.rb +8 -7
- data/lib/roda/plugins/view_options.rb +1 -1
- data/lib/roda/response.rb +1 -1
- data/lib/roda/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1e04d3df576ad873687f27895cf5100f34a6142ee2204d4e74372d8da03ffe0
|
4
|
+
data.tar.gz: 6b4f577746d682fc763c765d6d9f787a251db3c392072d1fa123fe5bddab7e20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 845525a607910671a61b61645ecfa7243ab8565963169aff78e7908cd5a982c8cbd5f8420e9e53e6689488be5fa57bfba9fc7da714d5e892f79f205c0a895ccf
|
7
|
+
data.tar.gz: 37fe2d01f609363e382b0fffe45b2dc13c5c04d0467890db334417a44d42b8a906a3d95f0ec68e465b17b0c8c54667cd7ef93fe866e0ef48d0afdbf5916c5aaa
|
data/lib/roda/plugins/assets.rb
CHANGED
@@ -871,11 +871,11 @@ class Roda
|
|
871
871
|
def unnest_assets_hash(h)
|
872
872
|
case h
|
873
873
|
when Hash
|
874
|
-
h.
|
874
|
+
h.flat_map do |k,v|
|
875
875
|
assets = unnest_assets_hash(v)
|
876
876
|
assets = assets.map{|x| "#{k}/#{x}"} if roda_class.assets_opts[:group_subdirs]
|
877
877
|
assets
|
878
|
-
end
|
878
|
+
end
|
879
879
|
else
|
880
880
|
Array(h)
|
881
881
|
end
|
@@ -73,13 +73,13 @@ class Roda
|
|
73
73
|
# Return an array of paths/as pairs for the given asset
|
74
74
|
# types and/or groups.
|
75
75
|
def _preload_assets_array(assets)
|
76
|
-
assets.
|
76
|
+
assets.flat_map do |type|
|
77
77
|
paths = assets_paths(type)
|
78
78
|
type = type[0] if type.is_a?(Array)
|
79
79
|
as = TYPE_AS[type]
|
80
80
|
|
81
81
|
paths.map{|path| [path, as]}
|
82
|
-
end
|
82
|
+
end
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -135,7 +135,7 @@ class Roda
|
|
135
135
|
style-src
|
136
136
|
worker-src
|
137
137
|
'.split.each(&:freeze).each do |setting|
|
138
|
-
meth = setting.
|
138
|
+
meth = setting.tr('-', '_').freeze
|
139
139
|
|
140
140
|
# Setting method name sets the setting value, or removes it if no args are given.
|
141
141
|
define_method(meth) do |*args|
|
@@ -165,7 +165,7 @@ class Roda
|
|
165
165
|
end
|
166
166
|
|
167
167
|
%w'block-all-mixed-content upgrade-insecure-requests'.each(&:freeze).each do |setting|
|
168
|
-
meth = setting.
|
168
|
+
meth = setting.tr('-', '_').freeze
|
169
169
|
|
170
170
|
# Setting method name turns on setting if true or no argument given,
|
171
171
|
# or removes setting if false is given.
|
@@ -258,7 +258,7 @@ class Roda
|
|
258
258
|
raise RodaError, "unsupported CSP value used: #{v.inspect}"
|
259
259
|
end
|
260
260
|
when Symbol
|
261
|
-
s << " '" << v.to_s.
|
261
|
+
s << " '" << v.to_s.tr('_', '-') << "'"
|
262
262
|
else
|
263
263
|
raise RodaError, "unsupported CSP value used: #{v.inspect}"
|
264
264
|
end
|
@@ -138,7 +138,7 @@ class Roda
|
|
138
138
|
# Represents a permissions policy.
|
139
139
|
class Policy
|
140
140
|
SUPPORTED_SETTINGS.each do |setting|
|
141
|
-
meth = setting.
|
141
|
+
meth = setting.tr('-', '_').freeze
|
142
142
|
|
143
143
|
# Setting method name sets the setting value, or removes it if no args are given.
|
144
144
|
define_method(meth) do |*args|
|
@@ -284,7 +284,7 @@ class Roda
|
|
284
284
|
|
285
285
|
if default = opts[:default]
|
286
286
|
SUPPORTED_SETTINGS.each do |setting|
|
287
|
-
policy.send(setting.
|
287
|
+
policy.send(setting.tr('-', '_'), *default)
|
288
288
|
end
|
289
289
|
end
|
290
290
|
|
@@ -56,7 +56,7 @@ class Roda
|
|
56
56
|
compiled_path = nil
|
57
57
|
(self.opts[:render_coverage_strip_paths] || render_opts[:allowed_paths]).each do |dir|
|
58
58
|
if path.start_with?(dir + '/')
|
59
|
-
compiled_path = File.join(self.opts[:render_coverage_dir], path[dir.length+1, 10000000].
|
59
|
+
compiled_path = File.join(self.opts[:render_coverage_dir], path[dir.length+1, 10000000].tr('/', '-'))
|
60
60
|
break
|
61
61
|
end
|
62
62
|
end
|
@@ -186,7 +186,7 @@ class Roda
|
|
186
186
|
options[:csrf_failure] = :csrf_failure_method
|
187
187
|
app.define_roda_method(:_roda_route_csrf_failure, 1, &app.send(:convert_route_block, block))
|
188
188
|
end
|
189
|
-
options[:env_header] = "HTTP_#{options[:header].to_s.
|
189
|
+
options[:env_header] = "HTTP_#{options[:header].to_s.tr('-', '_').upcase}".freeze
|
190
190
|
options.freeze
|
191
191
|
end
|
192
192
|
|
@@ -16,7 +16,7 @@ class Roda
|
|
16
16
|
module StripPathPrefix
|
17
17
|
# Set the regexp to use when stripping prefixes from internal paths.
|
18
18
|
def self.configure(app, prefix=Dir.pwd)
|
19
|
-
prefix += '/' unless prefix
|
19
|
+
prefix += '/' unless prefix.end_with?("/")
|
20
20
|
app.opts[:strip_path_prefix] = /\A#{Regexp.escape(prefix)}/
|
21
21
|
end
|
22
22
|
|
@@ -244,17 +244,24 @@ class Roda
|
|
244
244
|
# when loading the typecast_params plugin. This block is executed in the context of the
|
245
245
|
# subclass, and calling +handle_type+ in the block can be used to add conversion methods.
|
246
246
|
# +handle_type+ accepts a type name, an options hash, and the block used to convert the type.
|
247
|
-
#
|
248
|
-
#
|
249
|
-
#
|
247
|
+
# Supported options are:
|
248
|
+
# +:invalid_value_message+ :: The message to use for type conversions that result in a nil value
|
249
|
+
# (a space and the parameter name is appended to this).
|
250
|
+
# +:max_input_bytesize+ :: The maximum bytesize of string input.
|
251
|
+
#
|
252
|
+
# You can override the invalid value message of an existing type using the
|
253
|
+
# +invalid_value_message+ method. You can also override the max input bytesize of an existing
|
254
|
+
# type using the +max_input_bytesize+ method.
|
250
255
|
#
|
251
256
|
# plugin :typecast_params do
|
252
|
-
# handle_type(:album, max_input_bytesize: 100
|
257
|
+
# handle_type(:album, max_input_bytesize: 100,
|
258
|
+
# invalid_value_message: "invalid album id in parameter") do |value|
|
253
259
|
# if id = convert_pos_int(val)
|
254
260
|
# Album[id]
|
255
261
|
# end
|
256
262
|
# end
|
257
263
|
# max_input_bytesize(:date, 256)
|
264
|
+
# invalid_value_message(:pos_int, "value must be greater than 0 for parameter")
|
258
265
|
# end
|
259
266
|
#
|
260
267
|
# By default, the typecast_params conversion procs are passed the parameter value directly
|
@@ -441,6 +448,8 @@ class Roda
|
|
441
448
|
# * foo!(key)
|
442
449
|
# * convert_foo(value) # private
|
443
450
|
# * _convert_array_foo(value) # private
|
451
|
+
# * _invalid_value_message_for_foo # private
|
452
|
+
# * _max_input_bytesize_for_foo # private
|
444
453
|
#
|
445
454
|
# This method is used to define all type conversions, even the built
|
446
455
|
# in ones. It can be called in subclasses to setup subclass-specific
|
@@ -449,25 +458,23 @@ class Roda
|
|
449
458
|
convert_meth = :"convert_#{type}"
|
450
459
|
define_method(convert_meth, &block)
|
451
460
|
|
452
|
-
max_input_bytesize = opts[:max_input_bytesize]
|
453
|
-
max_input_bytesize_meth = :"_max_input_bytesize_for_#{type}"
|
454
|
-
define_method(max_input_bytesize_meth){max_input_bytesize}
|
455
|
-
|
456
461
|
convert_array_meth = :"_convert_array_#{type}"
|
457
462
|
define_method(convert_array_meth) do |v|
|
458
463
|
raise Error, "expected array but received #{v.inspect}" unless v.is_a?(Array)
|
459
464
|
v.map! do |val|
|
460
|
-
check_allowed_bytesize(val,
|
465
|
+
check_allowed_bytesize(val, _max_input_bytesize_for(type))
|
461
466
|
check_null_byte(val)
|
462
467
|
send(convert_meth, val)
|
463
468
|
end
|
464
469
|
end
|
465
470
|
|
466
|
-
private convert_meth, convert_array_meth
|
467
|
-
|
471
|
+
private convert_meth, convert_array_meth
|
472
|
+
|
473
|
+
invalid_value_message(type, opts[:invalid_value_message])
|
474
|
+
max_input_bytesize(type, opts[:max_input_bytesize])
|
468
475
|
|
469
476
|
define_method(type) do |key, default=nil|
|
470
|
-
process_arg(convert_meth, key, default,
|
477
|
+
process_arg(convert_meth, key, default, type) if require_hash!
|
471
478
|
end
|
472
479
|
|
473
480
|
define_method(:"#{type}!") do |key|
|
@@ -475,8 +482,15 @@ class Roda
|
|
475
482
|
end
|
476
483
|
end
|
477
484
|
|
478
|
-
#
|
479
|
-
|
485
|
+
# Set the invalid message for the given type.
|
486
|
+
def self.invalid_value_message(type, message)
|
487
|
+
invalid_value_message_meth = :"_invalid_value_message_for_#{type}"
|
488
|
+
define_method(invalid_value_message_meth){message}
|
489
|
+
private invalid_value_message_meth
|
490
|
+
alias_method invalid_value_message_meth, invalid_value_message_meth
|
491
|
+
end
|
492
|
+
|
493
|
+
# Set the maximum input bytesize for the given type.
|
480
494
|
def self.max_input_bytesize(type, bytesize)
|
481
495
|
max_input_bytesize_meth = :"_max_input_bytesize_for_#{type}"
|
482
496
|
define_method(max_input_bytesize_meth){bytesize}
|
@@ -504,13 +518,13 @@ class Roda
|
|
504
518
|
v
|
505
519
|
end
|
506
520
|
|
507
|
-
handle_type(:nonempty_str) do |v|
|
521
|
+
handle_type(:nonempty_str, :invalid_value_message=>"empty string provided for parameter") do |v|
|
508
522
|
if (v = convert_str(v)) && !v.strip.empty?
|
509
523
|
v
|
510
524
|
end
|
511
525
|
end
|
512
526
|
|
513
|
-
handle_type(:bool) do |v|
|
527
|
+
handle_type(:bool, :invalid_value_message=>"empty string provided for parameter") do |v|
|
514
528
|
case v
|
515
529
|
when ''
|
516
530
|
nil
|
@@ -523,18 +537,18 @@ class Roda
|
|
523
537
|
end
|
524
538
|
end
|
525
539
|
|
526
|
-
handle_type(:int, :max_input_bytesize=>100) do |v|
|
540
|
+
handle_type(:int, :max_input_bytesize=>100, :invalid_value_message=>"empty string provided for parameter") do |v|
|
527
541
|
string_or_numeric!(v) && v.to_i
|
528
542
|
end
|
529
543
|
alias base_convert_int convert_int
|
530
544
|
|
531
|
-
handle_type(:pos_int, :max_input_bytesize=>100) do |v|
|
545
|
+
handle_type(:pos_int, :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, or non-positive integer provided for parameter") do |v|
|
532
546
|
if (v = base_convert_int(v)) && v > 0
|
533
547
|
v
|
534
548
|
end
|
535
549
|
end
|
536
550
|
|
537
|
-
handle_type(:Integer, :max_input_bytesize=>100) do |v|
|
551
|
+
handle_type(:Integer, :max_input_bytesize=>100, :invalid_value_message=>"empty string provided for parameter") do |v|
|
538
552
|
if string_or_numeric!(v)
|
539
553
|
case v
|
540
554
|
when String
|
@@ -550,11 +564,11 @@ class Roda
|
|
550
564
|
end
|
551
565
|
alias base_convert_Integer convert_Integer
|
552
566
|
|
553
|
-
handle_type(:float, :max_input_bytesize=>1000) do |v|
|
567
|
+
handle_type(:float, :max_input_bytesize=>1000, :invalid_value_message=>"empty string provided for parameter") do |v|
|
554
568
|
string_or_numeric!(v) && v.to_f
|
555
569
|
end
|
556
570
|
|
557
|
-
handle_type(:Float, :max_input_bytesize=>1000) do |v|
|
571
|
+
handle_type(:Float, :max_input_bytesize=>1000, :invalid_value_message=>"empty string provided for parameter") do |v|
|
558
572
|
string_or_numeric!(v) && ::Kernel::Float(v)
|
559
573
|
end
|
560
574
|
|
@@ -752,7 +766,7 @@ class Roda
|
|
752
766
|
def array(type, key, default=nil)
|
753
767
|
meth = :"_convert_array_#{type}"
|
754
768
|
raise ProgrammerError, "no typecast_params type registered for #{type.inspect}" unless respond_to?(meth, true)
|
755
|
-
process_arg(meth, key, default,
|
769
|
+
process_arg(meth, key, default, type) if require_hash!
|
756
770
|
end
|
757
771
|
|
758
772
|
# Call +array+ with the +type+, +key+, and +default+, but if the return value is nil or any value in
|
@@ -985,10 +999,10 @@ class Roda
|
|
985
999
|
|
986
1000
|
# If +key+ is not an array, convert the value at the given +key+ using the +meth+ method and +default+
|
987
1001
|
# value. If +key+ is an array, return an array with the conversion done for each respective member of +key+.
|
988
|
-
def process_arg(meth, key, default,
|
1002
|
+
def process_arg(meth, key, default, type)
|
989
1003
|
case key
|
990
1004
|
when String
|
991
|
-
v = process(meth, key, default,
|
1005
|
+
v = process(meth, key, default, type)
|
992
1006
|
|
993
1007
|
if @capture
|
994
1008
|
key = key.to_sym if symbolize?
|
@@ -1001,13 +1015,23 @@ class Roda
|
|
1001
1015
|
when Array
|
1002
1016
|
key.map do |k|
|
1003
1017
|
raise ProgrammerError, "non-String element in array argument passed to typecast_params: #{k.inspect}" unless k.is_a?(String)
|
1004
|
-
process_arg(meth, k, default,
|
1018
|
+
process_arg(meth, k, default, type)
|
1005
1019
|
end
|
1006
1020
|
else
|
1007
1021
|
raise ProgrammerError, "Unsupported argument for typecast_params conversion method: #{key.inspect}"
|
1008
1022
|
end
|
1009
1023
|
end
|
1010
1024
|
|
1025
|
+
# The invalid message to use if the given type conversion fails, which may be nil to use the default.
|
1026
|
+
def _invalid_value_message_for(type)
|
1027
|
+
send(:"_invalid_value_message_for_#{type}")
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
# The maximum input bytesize for the given type, which may be nil.
|
1031
|
+
def _max_input_bytesize_for(type)
|
1032
|
+
send(:"_max_input_bytesize_for_#{type}")
|
1033
|
+
end
|
1034
|
+
|
1011
1035
|
# Raise an Error if the value is a string with bytesize over max (if max is given)
|
1012
1036
|
def check_allowed_bytesize(v, max)
|
1013
1037
|
if max && v.is_a?(String) && v.bytesize > max
|
@@ -1024,18 +1048,24 @@ class Roda
|
|
1024
1048
|
|
1025
1049
|
# Get the value of +key+ for the object, and convert it to the expected type using +meth+.
|
1026
1050
|
# If the value either before or after conversion is nil, return the +default+ value.
|
1027
|
-
def process(meth, key, default,
|
1028
|
-
v = param_value(key)
|
1051
|
+
def process(meth, key, default, type)
|
1052
|
+
orig_v = v = param_value(key)
|
1029
1053
|
|
1030
|
-
|
1031
|
-
|
1054
|
+
if v.nil?
|
1055
|
+
if default == CHECK_NIL
|
1056
|
+
handle_error(key, :missing, "missing parameter for #{param_name(key)}")
|
1057
|
+
end
|
1058
|
+
else
|
1059
|
+
check_allowed_bytesize(v, _max_input_bytesize_for(type))
|
1032
1060
|
check_null_byte(v)
|
1033
1061
|
v = send(meth, v)
|
1034
1062
|
end
|
1035
1063
|
|
1036
1064
|
if v.nil?
|
1037
|
-
if default == CHECK_NIL
|
1038
|
-
|
1065
|
+
if !orig_v.nil? && default == CHECK_NIL
|
1066
|
+
invalid_value_message = _invalid_value_message_for(type)
|
1067
|
+
invalid_value_message ||= "invalid parameter value for"
|
1068
|
+
handle_error(key, :invalid_value, "#{invalid_value_message} #{param_name(key)}")
|
1039
1069
|
end
|
1040
1070
|
|
1041
1071
|
default
|
@@ -51,37 +51,37 @@ class Roda
|
|
51
51
|
max_signed = 2**(i-1)-1
|
52
52
|
max_unsigned = 2**i-1
|
53
53
|
|
54
|
-
handle_type(:"int#{i}", :max_input_bytesize=>100) do |v|
|
54
|
+
handle_type(:"int#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, or too-large integer provided for parameter") do |v|
|
55
55
|
if (v = base_convert_int(v)) && v >= min_signed && v <= max_signed
|
56
56
|
v
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
handle_type(:"uint#{i}", :max_input_bytesize=>100) do |v|
|
60
|
+
handle_type(:"uint#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, negative integer, or too-large integer provided for parameter") do |v|
|
61
61
|
if (v = base_convert_int(v)) && v >= 0 && v <= max_unsigned
|
62
62
|
v
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
handle_type(:"pos_int#{i}", :max_input_bytesize=>100) do |v|
|
66
|
+
handle_type(:"pos_int#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, non-positive integer, or too-large integer provided for parameter") do |v|
|
67
67
|
if (v = base_convert_int(v)) && v > 0 && v <= max_signed
|
68
68
|
v
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
handle_type(:"pos_uint#{i}", :max_input_bytesize=>100) do |v|
|
72
|
+
handle_type(:"pos_uint#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, non-positive integer, or too-large integer provided for parameter") do |v|
|
73
73
|
if (v = base_convert_int(v)) && v > 0 && v <= max_unsigned
|
74
74
|
v
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
handle_type(:"Integer#{i}", :max_input_bytesize=>100) do |v|
|
78
|
+
handle_type(:"Integer#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, or too-large integer provided for parameter") do |v|
|
79
79
|
if (v = base_convert_Integer(v)) && v >= min_signed && v <= max_signed
|
80
80
|
v
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
handle_type(:"Integeru#{i}", :max_input_bytesize=>100) do |v|
|
84
|
+
handle_type(:"Integeru#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, negative integer, or too-large integer provided for parameter") do |v|
|
85
85
|
if (v = base_convert_Integer(v)) && v >= 0 && v <= max_unsigned
|
86
86
|
v
|
87
87
|
end
|
@@ -91,8 +91,9 @@ class Roda
|
|
91
91
|
|
92
92
|
if default = opts[:default_size]
|
93
93
|
app::TypecastParams.class_eval do
|
94
|
+
meths = ['', 'convert_', '_convert_array_', '_max_input_bytesize_for_', '_invalid_value_message_for_']
|
94
95
|
%w[int uint pos_int pos_uint Integer Integeru].each do |type|
|
95
|
-
|
96
|
+
meths.each do |prefix|
|
96
97
|
alias_method :"#{prefix}#{type}", :"#{prefix}#{type}#{default}"
|
97
98
|
end
|
98
99
|
alias_method :"#{type}!", :"#{type}#{default}!"
|
data/lib/roda/response.rb
CHANGED
@@ -18,7 +18,7 @@ class Roda
|
|
18
18
|
Permissions-Policy Permissions-Policy-Report-Only Strict-Transport-Security'.
|
19
19
|
each do |value|
|
20
20
|
value = value.downcase if downcase
|
21
|
-
const_set(value.
|
21
|
+
const_set(value.tr('-', '_').upcase!.to_sym, value.freeze)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
data/lib/roda/version.rb
CHANGED