roda 3.83.0 → 3.84.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/roda/plugins/hsts.rb +35 -0
- data/lib/roda/response.rb +1 -1
- data/lib/roda/version.rb +1 -1
- metadata +4 -179
- data/CHANGELOG +0 -691
- data/README.rdoc +0 -1136
- data/doc/conventions.rdoc +0 -177
- data/doc/release_notes/3.0.0.txt +0 -84
- data/doc/release_notes/3.1.0.txt +0 -24
- data/doc/release_notes/3.10.0.txt +0 -132
- data/doc/release_notes/3.11.0.txt +0 -54
- data/doc/release_notes/3.12.0.txt +0 -19
- data/doc/release_notes/3.13.0.txt +0 -38
- data/doc/release_notes/3.14.0.txt +0 -36
- data/doc/release_notes/3.14.1.txt +0 -43
- data/doc/release_notes/3.15.0.txt +0 -21
- data/doc/release_notes/3.16.0.txt +0 -52
- data/doc/release_notes/3.17.0.txt +0 -62
- data/doc/release_notes/3.18.0.txt +0 -170
- data/doc/release_notes/3.19.0.txt +0 -229
- data/doc/release_notes/3.2.0.txt +0 -22
- data/doc/release_notes/3.20.0.txt +0 -7
- data/doc/release_notes/3.21.0.txt +0 -5
- data/doc/release_notes/3.22.0.txt +0 -24
- data/doc/release_notes/3.23.0.txt +0 -28
- data/doc/release_notes/3.24.0.txt +0 -14
- data/doc/release_notes/3.25.0.txt +0 -12
- data/doc/release_notes/3.26.0.txt +0 -15
- data/doc/release_notes/3.27.0.txt +0 -15
- data/doc/release_notes/3.28.0.txt +0 -13
- data/doc/release_notes/3.29.0.txt +0 -15
- data/doc/release_notes/3.3.0.txt +0 -291
- data/doc/release_notes/3.30.0.txt +0 -14
- data/doc/release_notes/3.31.0.txt +0 -11
- data/doc/release_notes/3.32.0.txt +0 -42
- data/doc/release_notes/3.33.0.txt +0 -8
- data/doc/release_notes/3.34.0.txt +0 -17
- data/doc/release_notes/3.35.0.txt +0 -12
- data/doc/release_notes/3.36.0.txt +0 -17
- data/doc/release_notes/3.37.0.txt +0 -42
- data/doc/release_notes/3.38.0.txt +0 -5
- data/doc/release_notes/3.39.0.txt +0 -16
- data/doc/release_notes/3.4.0.txt +0 -24
- data/doc/release_notes/3.40.0.txt +0 -24
- data/doc/release_notes/3.41.0.txt +0 -9
- data/doc/release_notes/3.42.0.txt +0 -21
- data/doc/release_notes/3.43.0.txt +0 -34
- data/doc/release_notes/3.44.0.txt +0 -23
- data/doc/release_notes/3.45.0.txt +0 -22
- data/doc/release_notes/3.46.0.txt +0 -19
- data/doc/release_notes/3.47.0.txt +0 -13
- data/doc/release_notes/3.48.0.txt +0 -10
- data/doc/release_notes/3.49.0.txt +0 -18
- data/doc/release_notes/3.5.0.txt +0 -31
- data/doc/release_notes/3.50.0.txt +0 -21
- data/doc/release_notes/3.51.0.txt +0 -20
- data/doc/release_notes/3.52.0.txt +0 -20
- data/doc/release_notes/3.53.0.txt +0 -14
- data/doc/release_notes/3.54.0.txt +0 -48
- data/doc/release_notes/3.55.0.txt +0 -12
- data/doc/release_notes/3.56.0.txt +0 -33
- data/doc/release_notes/3.57.0.txt +0 -34
- data/doc/release_notes/3.58.0.txt +0 -16
- data/doc/release_notes/3.59.0.txt +0 -17
- data/doc/release_notes/3.6.0.txt +0 -21
- data/doc/release_notes/3.60.0.txt +0 -56
- data/doc/release_notes/3.61.0.txt +0 -24
- data/doc/release_notes/3.62.0.txt +0 -41
- data/doc/release_notes/3.63.0.txt +0 -36
- data/doc/release_notes/3.64.0.txt +0 -26
- data/doc/release_notes/3.65.0.txt +0 -12
- data/doc/release_notes/3.66.0.txt +0 -23
- data/doc/release_notes/3.67.0.txt +0 -25
- data/doc/release_notes/3.68.0.txt +0 -21
- data/doc/release_notes/3.69.0.txt +0 -33
- data/doc/release_notes/3.7.0.txt +0 -123
- data/doc/release_notes/3.70.0.txt +0 -19
- data/doc/release_notes/3.71.0.txt +0 -33
- data/doc/release_notes/3.72.0.txt +0 -48
- data/doc/release_notes/3.73.0.txt +0 -33
- data/doc/release_notes/3.74.0.txt +0 -28
- data/doc/release_notes/3.75.0.txt +0 -19
- data/doc/release_notes/3.76.0.txt +0 -18
- data/doc/release_notes/3.77.0.txt +0 -8
- data/doc/release_notes/3.78.0.txt +0 -99
- data/doc/release_notes/3.79.0.txt +0 -148
- data/doc/release_notes/3.8.0.txt +0 -27
- data/doc/release_notes/3.80.0.txt +0 -31
- data/doc/release_notes/3.81.0.txt +0 -24
- data/doc/release_notes/3.82.0.txt +0 -43
- data/doc/release_notes/3.83.0.txt +0 -6
- data/doc/release_notes/3.9.0.txt +0 -67
@@ -1,15 +0,0 @@
|
|
1
|
-
= Improvements
|
2
|
-
|
3
|
-
* The common_logger plugin now includes the SCRIPT_NAME when
|
4
|
-
logging, for greater compatibility with typical web server
|
5
|
-
logs.
|
6
|
-
|
7
|
-
* The exception_page plugin now handles invalid POST data.
|
8
|
-
Previously, invalid POST data would cause the exception page
|
9
|
-
display to raise an exception.
|
10
|
-
|
11
|
-
* An error is now raised if trying to load a plugin that is not a
|
12
|
-
module or a recognized plugin symbol.
|
13
|
-
|
14
|
-
* Specs and older release notes are no longer shipped in the
|
15
|
-
gem, reducing gem size by over 35%.
|
data/doc/release_notes/3.3.0.txt
DELETED
@@ -1,291 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A typecast_params plugin has been added for handling the
|
4
|
-
conversion of params to the expected type. This plugin is
|
5
|
-
recommended for all applications that deal with submitted
|
6
|
-
parameters.
|
7
|
-
|
8
|
-
Submitted parameters should be considered untrusted input, and in
|
9
|
-
standard use with browsers, parameters are submitted as strings
|
10
|
-
(or a hash/array containing strings). In most cases it makes sense
|
11
|
-
to explicitly convert the parameter to the desired type. While this
|
12
|
-
can be done via manual conversion:
|
13
|
-
|
14
|
-
key = request.params['key'].to_i
|
15
|
-
key = nil unless key > 0
|
16
|
-
|
17
|
-
the typecast_params plugin adds a friendlier interface:
|
18
|
-
|
19
|
-
key = typecast_params.pos_int('key')
|
20
|
-
|
21
|
-
As typecast_params is a fairly long method name, you may want to
|
22
|
-
consider aliasing it to something more terse in your application,
|
23
|
-
such as tp.
|
24
|
-
|
25
|
-
One advantage of using typecast_params is that access or conversion
|
26
|
-
errors are raised as a specific exception class
|
27
|
-
(Roda::RodaPlugins::TypecastParams::Error). This allows you to
|
28
|
-
handle this specific exception class globally and return an
|
29
|
-
appropriate 4xx response to the client. You can use the
|
30
|
-
Error#param_name and Error#reason methods to get more information
|
31
|
-
about the error.
|
32
|
-
|
33
|
-
typecast_params offers support for default values:
|
34
|
-
|
35
|
-
key = typecast_params.pos_int('key', 1)
|
36
|
-
|
37
|
-
The default value is only used if no value has been submitted for
|
38
|
-
the parameter, or if the conversion of the value results in nil.
|
39
|
-
Handling defaults for parameter conversion manually is more
|
40
|
-
difficult, since the parameter may not be present at all, or it may
|
41
|
-
be present but an empty string because the user did not enter a
|
42
|
-
value on the related form. Use of typecast_params for the
|
43
|
-
conversion handles both cases.
|
44
|
-
|
45
|
-
In many cases, parameters should be required, and if they aren't
|
46
|
-
submitted, that should be considered an error. typecast_params
|
47
|
-
handles this with ! methods:
|
48
|
-
|
49
|
-
key = typecast_params.pos_int!('key')
|
50
|
-
|
51
|
-
These ! methods raise an error instead of returning nil, and do not
|
52
|
-
allow defaults.
|
53
|
-
|
54
|
-
To make it easy to handle cases where many parameters need the same
|
55
|
-
conversion done, you can pass an array of keys to a conversion
|
56
|
-
method, and it will return an array of converted values:
|
57
|
-
|
58
|
-
key1, key2 = typecast_params.pos_int(['key1', 'key2'])
|
59
|
-
|
60
|
-
This is equivalent to:
|
61
|
-
|
62
|
-
key1 = typecast_params.pos_int('key1')
|
63
|
-
key2 = typecast_params.pos_int('key2')
|
64
|
-
|
65
|
-
The ! methods also support arrays of keys, ensuring that all
|
66
|
-
parameters have a value:
|
67
|
-
|
68
|
-
key1, key2 = typecast_params.pos_int!(['key1', 'key2'])
|
69
|
-
|
70
|
-
For handling of array parameters, where all entries in the array
|
71
|
-
use the same conversion, there is an array method which takes the
|
72
|
-
type as the first argument and the keys to convert as the second
|
73
|
-
argument:
|
74
|
-
|
75
|
-
keys = typecast_params.array(:pos_int, 'keys')
|
76
|
-
|
77
|
-
If you want to ensure that all entries in the array are converted
|
78
|
-
successfully and that there is a value for the array itself, you
|
79
|
-
can use array!:
|
80
|
-
|
81
|
-
keys = typecast_params.array!(:pos_int, 'keys')
|
82
|
-
|
83
|
-
This will raise an exception if any of the values in the array for
|
84
|
-
parameter keys cannot be converted to a positive integer.
|
85
|
-
|
86
|
-
Both array and array! support default values which are used if no
|
87
|
-
value is present for the parameter:
|
88
|
-
|
89
|
-
keys = typecast_params.array(:pos_int, 'keys', [])
|
90
|
-
keys = typecast_params.array!(:pos_int, 'keys', [])
|
91
|
-
|
92
|
-
You can also pass an array of keys to array or array!, if you would
|
93
|
-
like to perform the same conversion on multiple arrays:
|
94
|
-
|
95
|
-
foo_ids, bar_ids = typecast_params.array!(:pos_int, ['foo_ids', 'bar_ids'])
|
96
|
-
|
97
|
-
The previous examples have shown use of the pos_int method, which
|
98
|
-
uses to_i to convert the value to an integer, but returns nil if the
|
99
|
-
resulting integer is not positive. Unless you need to handle
|
100
|
-
negative numbers, it is recommended to use pos_int instead of int as
|
101
|
-
int will convert invalid values to 0 (since that is how
|
102
|
-
<tt>String#to_i</tt> works).
|
103
|
-
|
104
|
-
There are many built in methods for type conversion:
|
105
|
-
|
106
|
-
any :: Returns the value as is without conversion
|
107
|
-
str :: Raises if value is not already a string
|
108
|
-
nonempty_str :: Raises if value is not already a string, and
|
109
|
-
converts the empty string or string containing only
|
110
|
-
whitespace to nil
|
111
|
-
bool :: Converts entry to boolean if in one of the recognized
|
112
|
-
formats (case insensitive for strings):
|
113
|
-
nil :: nil, ''
|
114
|
-
true :: true, 1, '1', 't', 'true', 'yes', 'y', 'on'
|
115
|
-
false :: false, 0, '0', 'f', 'false', 'no', 'n', 'off'
|
116
|
-
If not in one of those formats, raises an error.
|
117
|
-
int :: Converts value to integer using to_i (note that invalid
|
118
|
-
input strings will be converted to 0)
|
119
|
-
pos_int :: Converts value using to_i, but non-positive values
|
120
|
-
are converted to nil
|
121
|
-
Integer :: Converts value to integer using
|
122
|
-
Kernel::Integer(value, 10)
|
123
|
-
float :: Converts value to float using to_f (note that invalid
|
124
|
-
input strings will be converted to 0.0)
|
125
|
-
Float :: Converts value to float using Kernel::Float(value)
|
126
|
-
Hash :: Raises if value is not already a hash
|
127
|
-
date :: Converts value to Date using Date.parse(value)
|
128
|
-
time :: Converts value to Time using Time.parse(value)
|
129
|
-
datetime :: Converts value to DateTime using DateTime.parse(value)
|
130
|
-
file :: Raises if value is not already a hash with a :tempfile key
|
131
|
-
whose value responds to read (this is the format rack uses
|
132
|
-
for uploaded files).
|
133
|
-
|
134
|
-
All of these methods also support ! methods (e.g. pos_int!), and all
|
135
|
-
of them can be used in the array and array! methods to support
|
136
|
-
arrays of values.
|
137
|
-
|
138
|
-
Since parameter hashes can be nested, the [] method can be used to
|
139
|
-
access nested
|
140
|
-
hashes:
|
141
|
-
|
142
|
-
# params: {'key'=>{'sub_key'=>'1'}}
|
143
|
-
typecast_params['key'].pos_int!('sub_key') # => 1
|
144
|
-
|
145
|
-
This works to an arbitrary depth:
|
146
|
-
|
147
|
-
# params: {'key'=>{'sub_key'=>{'sub_sub_key'=>'1'}}}
|
148
|
-
typecast_params['key']['sub_key'].pos_int!('sub_sub_key') # => 1
|
149
|
-
|
150
|
-
And also works with arrays at any depth, if those arrays contain
|
151
|
-
hashes:
|
152
|
-
|
153
|
-
# params: {'key'=>[{'sub_key'=>{'sub_sub_key'=>'1'}}]}
|
154
|
-
typecast_params['key'][0]['sub_key'].pos_int!('sub_sub_key') # => 1
|
155
|
-
|
156
|
-
# params: {'key'=>[{'sub_key'=>['1']}]}
|
157
|
-
typecast_params['key'][0].array!(:pos_int, 'sub_key') # => [1]
|
158
|
-
|
159
|
-
To allow easier access to nested data, there is a dig method:
|
160
|
-
|
161
|
-
typecast_params.dig(:pos_int, 'key', 'sub_key')
|
162
|
-
typecast_params.dig(:pos_int, 'key', 0, 'sub_key', 'sub_sub_key')
|
163
|
-
|
164
|
-
dig will return nil if any access while looking up the nested value
|
165
|
-
returns nil. There is also a dig! method, which will raise an Error
|
166
|
-
if dig would return nil:
|
167
|
-
|
168
|
-
typecast_params.dig!(:pos_int, 'key', 'sub_key')
|
169
|
-
typecast_params.dig!(:pos_int, 'key', 0, 'sub_key', 'sub_sub_key')
|
170
|
-
|
171
|
-
Note that none of these conversion methods modify request.params.
|
172
|
-
They purely do the conversion and return the converted value.
|
173
|
-
However, in some cases it is useful to do all the conversion up
|
174
|
-
front, and then pass a hash of converted parameters to an internal
|
175
|
-
method that expects to receive values in specific types. The
|
176
|
-
convert! method does this, and there is also a convert_each! method
|
177
|
-
designed for converting multiple values using the same block:
|
178
|
-
|
179
|
-
converted_params = typecast_params.convert! do |tp|
|
180
|
-
tp.int('page')
|
181
|
-
tp.pos_int!('artist_id')
|
182
|
-
tp.array!(:pos_int, 'album_ids')
|
183
|
-
tp.convert!('sales') do |stp|
|
184
|
-
tp.pos_int!(['num_sold', 'num_shipped'])
|
185
|
-
end
|
186
|
-
tp.convert!('members') do |mtp|
|
187
|
-
mtp.convert_each! do |stp|
|
188
|
-
stp.str!(['first_name', 'last_name'])
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
# converted_params:
|
194
|
-
# {
|
195
|
-
# 'page' => 1,
|
196
|
-
# 'artist_id' => 2,
|
197
|
-
# 'album_ids' => [3, 4],
|
198
|
-
# 'sales' => {
|
199
|
-
# 'num_sold' => 5,
|
200
|
-
# 'num_shipped' => 6
|
201
|
-
# },
|
202
|
-
# 'members' => [
|
203
|
-
# {'first_name' => 'Foo', 'last_name' => 'Bar'},
|
204
|
-
# {'first_name' => 'Baz', 'last_name' => 'Quux'}
|
205
|
-
# ]
|
206
|
-
# }
|
207
|
-
|
208
|
-
convert! and convert_each! only return values you explicitly specify
|
209
|
-
for conversion inside the passed block.
|
210
|
-
|
211
|
-
You can specify the :symbolize option to convert! or convert_each!,
|
212
|
-
which will symbolize the resulting hash keys:
|
213
|
-
|
214
|
-
converted_params = typecast_params.convert!(symbolize: true) do |tp|
|
215
|
-
tp.int('page')
|
216
|
-
tp.pos_int!('artist_id')
|
217
|
-
tp.array!(:pos_int, 'album_ids')
|
218
|
-
tp.convert!('sales') do |stp|
|
219
|
-
tp.pos_int!(['num_sold', 'num_shipped'])
|
220
|
-
end
|
221
|
-
tp.convert!('members') do |mtp|
|
222
|
-
mtp.convert_each! do |stp|
|
223
|
-
stp.str!(['first_name', 'last_name'])
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
# converted_params:
|
229
|
-
# {
|
230
|
-
# :page => 1,
|
231
|
-
# :artist_id => 2,
|
232
|
-
# :album_ids => [3, 4],
|
233
|
-
# :sales => {
|
234
|
-
# :num_sold => 5,
|
235
|
-
# :num_shipped => 6
|
236
|
-
# },
|
237
|
-
# :members => [
|
238
|
-
# {:first_name => 'Foo', :last_name => 'Bar'},
|
239
|
-
# {:first_name => 'Baz', :last_name => 'Quux'}
|
240
|
-
# ]
|
241
|
-
# }
|
242
|
-
|
243
|
-
Using the :symbolize option makes it simpler to transition from
|
244
|
-
untrusted external data (string keys), to trusted data that can be
|
245
|
-
used internally (trusted in the sense that the expected types are
|
246
|
-
used).
|
247
|
-
|
248
|
-
Note that if there are multiple conversion errors raised inside a
|
249
|
-
convert! or convert_each! block, they are recorded and a single
|
250
|
-
Roda::RodaPlugins::TypecastParams::Error instance is raised after
|
251
|
-
processing the block. TypecastParams::Error#param_names can be
|
252
|
-
called on the exception to get an array of all parameter names
|
253
|
-
with conversion issues, and TypecastParams::Error#all_errors
|
254
|
-
can be used to get an array of all Error instances.
|
255
|
-
|
256
|
-
Because of how convert! and convert_each! work, you should avoid
|
257
|
-
calling TypecastParams::Params#[] inside the block you pass to
|
258
|
-
these methods, because if the #[] call fails, it will skip the
|
259
|
-
reminder of the block.
|
260
|
-
|
261
|
-
Be aware that when you use convert! and convert_each!, the
|
262
|
-
conversion methods called inside the block may return nil if there
|
263
|
-
is a error raised, and nested calls to convert! and convert_each!
|
264
|
-
may not return values.
|
265
|
-
|
266
|
-
When loading the typecast_params plugin, a subclass of
|
267
|
-
TypecastParams::Params is created specific to the Roda application.
|
268
|
-
You can add support for custom types by passing a block when loading
|
269
|
-
the typecast_params plugin. This block is executed in the context
|
270
|
-
of the subclass, and calling handle_type in the block can be used to
|
271
|
-
add conversion methods. handle_type accepts a type name and the
|
272
|
-
block used to convert the type:
|
273
|
-
|
274
|
-
plugin :typecast_params do
|
275
|
-
handle_type(:album) do |value|
|
276
|
-
if id = convert_pos_int(val)
|
277
|
-
Album[id]
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
By default, the typecast_params conversion procs are passed the
|
283
|
-
parameter value directly from request.params without modification.
|
284
|
-
In some cases, it may be beneficial to strip leading and trailing
|
285
|
-
whitespace from parameter string values before processing, which
|
286
|
-
you can do by passing the strip: :all> option when loading the
|
287
|
-
plugin.
|
288
|
-
|
289
|
-
By design, typecast_params only deals with string keys, it is not
|
290
|
-
possible to use symbol keys as arguments to the conversion methods
|
291
|
-
and have them converted.
|
@@ -1,14 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A :relative_paths plugin option has been added to the assets
|
4
|
-
plugin. This option makes the paths to the asset files in the
|
5
|
-
link and script tags relative paths instead of absolute paths.
|
6
|
-
|
7
|
-
= Other Improvements
|
8
|
-
|
9
|
-
* The :header matcher in the header_matchers plugin now works
|
10
|
-
correctly for the Content-Type and Content-Length headers, which
|
11
|
-
are not prefixed with HTTP_ in the rack environment.
|
12
|
-
|
13
|
-
* The run_append_slash and run_handler plugins now work correctly
|
14
|
-
when used together.
|
@@ -1,11 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A relative_path plugin has been added, adding a relative_path
|
4
|
-
method that will take an absolute path and make it relative to the
|
5
|
-
current request by prepending an appropriate prefix. This is
|
6
|
-
helpful when using Roda as a static site generator to generate a
|
7
|
-
site that can be hosted at any subpath or directly from the
|
8
|
-
filesystem.
|
9
|
-
|
10
|
-
* In the path plugin, the path method now accepts a :relative
|
11
|
-
option for generating relative paths instead of absolute paths.
|
@@ -1,42 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* render_each in the render_each plugin now automatically handles
|
4
|
-
template names with subdirectories and extensions. Previously, these
|
5
|
-
caused issues unless the :local option was provided. So now you
|
6
|
-
can use:
|
7
|
-
|
8
|
-
render_each(foos, "items/foo")
|
9
|
-
|
10
|
-
instead of:
|
11
|
-
|
12
|
-
render_each(foos, "items/foo", :local=>:foo)
|
13
|
-
|
14
|
-
* each_partial has been added to the partials plugin. It operates
|
15
|
-
similarly to render_each, but uses the convention for partial
|
16
|
-
template naming. So this:
|
17
|
-
|
18
|
-
each_partial(foos, "items/foo")
|
19
|
-
|
20
|
-
is the same as:
|
21
|
-
|
22
|
-
render_each(foos, "items/_foo", :local=>:foo)
|
23
|
-
|
24
|
-
= Other Improvements
|
25
|
-
|
26
|
-
* The :dependencies option in the assets plugin now works correctly
|
27
|
-
with compiled templates in the render plugin in uncached mode
|
28
|
-
(the default in development). Previously, modifying a dependency
|
29
|
-
file would not result in recompiling the asset template when
|
30
|
-
requesting the main file.
|
31
|
-
|
32
|
-
* Method visibility issues in the following plugins have been fixed:
|
33
|
-
|
34
|
-
* content_security_policy
|
35
|
-
* default_headers
|
36
|
-
* indifferent_params
|
37
|
-
* placeholder_string_matchers
|
38
|
-
* symbol_matchers
|
39
|
-
|
40
|
-
Previously, these plugins made private methods public by mistake
|
41
|
-
when overriding them. Additionally, Roda.freeze no longer changes
|
42
|
-
the visibility of the set_default_headers private method.
|
@@ -1,8 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The path plugin now supports a url method, allowing for returning
|
4
|
-
the entire URL instead of just the path for class-based paths.
|
5
|
-
|
6
|
-
* The public plugin now supports a :brotli option that will directly
|
7
|
-
serve brotli-compressed files (with .br extension) similar to how the
|
8
|
-
:gzip option directly serves gzipped files (with the .gz extension).
|
@@ -1,17 +0,0 @@
|
|
1
|
-
= Improvements
|
2
|
-
|
3
|
-
* Multiple unneeded conditionals have been removed.
|
4
|
-
|
5
|
-
* pre_content and post_context sections in backtraces are no longer
|
6
|
-
included in the exception_page plugin output if they would be
|
7
|
-
empty.
|
8
|
-
|
9
|
-
* The match_affix plugin can be loaded again with a single argument.
|
10
|
-
It was originally designed to accept a single argument, but a bug
|
11
|
-
introduced in 2.29.0 made it require two arguments.
|
12
|
-
|
13
|
-
* Core Roda and all plugins that ship with Roda now have 100% branch
|
14
|
-
coverage.
|
15
|
-
|
16
|
-
* The sinatra_helpers plugin no longer emits statement not reached
|
17
|
-
warnings in verbose mode.
|
@@ -1,12 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* An r plugin has been added. This plugin adds an r method for the
|
4
|
-
request, useful for allowing the use of r.halt and r.redirect even
|
5
|
-
in methods where the r local variable is not in scope.
|
6
|
-
|
7
|
-
= Other Improvements
|
8
|
-
|
9
|
-
* Attempting to load a plugin with an argument or block when the plugin
|
10
|
-
does not accept arguments or a block now warns. This is because a
|
11
|
-
future update to support a block or an optional argument could break
|
12
|
-
the call.
|
@@ -1,17 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A multi_public plugin has been added, which allows serving static
|
4
|
-
files from multiple separate directories. This is especially
|
5
|
-
useful when there are different access control requirements per
|
6
|
-
directory.
|
7
|
-
|
8
|
-
* The content_security_policy now supports a
|
9
|
-
content_security_policy.report_to method to set the
|
10
|
-
report-to directive.
|
11
|
-
|
12
|
-
= Other Improvements
|
13
|
-
|
14
|
-
* When using the type_routing plugin and performing type routing
|
15
|
-
using the Accept request header, the Vary response header will be
|
16
|
-
added or updated so that http caches do not cache a response for one
|
17
|
-
type and serve it for a different type.
|
@@ -1,42 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A custom_matchers plugin has been added, which allows using
|
4
|
-
arbitrary objects as matchers, as long as the matcher has been
|
5
|
-
registered. You can register matchers using the custom_matcher
|
6
|
-
class method, which takes the class of the matcher, and a block
|
7
|
-
which is yielded the matcher object. The block should return
|
8
|
-
nil or false if the matcher doesn't match, and any other value
|
9
|
-
if the matcher does match. Example:
|
10
|
-
|
11
|
-
plugin :custom_matchers
|
12
|
-
method_segment = Struct.new(:request_method, :next_segment)
|
13
|
-
custom_matcher(method_segment) do |matcher|
|
14
|
-
# self is the request instance ("r" yielded in the route block below)
|
15
|
-
if matcher.request_method == self.request_method
|
16
|
-
match(matcher.next_segment)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
get_foo = method_segment.new('GET', 'foo')
|
21
|
-
post_any = method_segment.new('POST', String)
|
22
|
-
route do |r|
|
23
|
-
r.on('baz') do
|
24
|
-
r.on(get_foo) do
|
25
|
-
# GET method, /baz/foo prefix
|
26
|
-
end
|
27
|
-
|
28
|
-
r.is(post_any) do |seg|
|
29
|
-
# for POST /baz/bar, seg is "bar"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
r.on('quux') do
|
34
|
-
r.is(get_foo) do
|
35
|
-
# GET method, /quux/foo route
|
36
|
-
end
|
37
|
-
|
38
|
-
r.on(post_any) do |seg|
|
39
|
-
# for POST /quux/xyz, seg is "xyz"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
= Improvements
|
2
|
-
|
3
|
-
* The relative_path plugin is now faster if you are calling
|
4
|
-
relative_path or relative_prefix more than once when handling a
|
5
|
-
request.
|
6
|
-
|
7
|
-
* The typecast_params.convert! method in the typecast_params plugin
|
8
|
-
now handles explicit nil values the same as missing values.
|
9
|
-
Explicit nil values do not generally occur in normal Rack parameter
|
10
|
-
parsing, but they can occur when using the json_parser plugin to
|
11
|
-
parse JSON requests.
|
12
|
-
|
13
|
-
* Roda now avoids method redefinition warnings in verbose mode by
|
14
|
-
using a self alias. As Ruby 3 is dropping uninitialized instance
|
15
|
-
variable warnings, Roda will be verbose warning free if you are
|
16
|
-
using Ruby 3.
|
data/doc/release_notes/3.4.0.txt
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A middleware_stack plugin has been added for more detailed control
|
4
|
-
over middleware, allowing for the removal of middleware and the
|
5
|
-
insertion of middleware before existing middleware. Example:
|
6
|
-
|
7
|
-
plugin :middleware_stack
|
8
|
-
|
9
|
-
# Remove csrf middleware
|
10
|
-
middleware_stack.remove{|m, *args| m == Rack::Csrf}
|
11
|
-
|
12
|
-
# Insert csrf middleware before logger middleware
|
13
|
-
middleware_stack.before{|m, *args| m == Rack::CommonLogger}.
|
14
|
-
use(Rack::Csrf, raise: true)
|
15
|
-
|
16
|
-
# Insert csrf middleware after logger middleware
|
17
|
-
middleware_stack.after{|m, *args| m == Rack::CommonLogger}.
|
18
|
-
use(Rack::Csrf, raise: true)
|
19
|
-
|
20
|
-
= Other Improvements
|
21
|
-
|
22
|
-
* The head plugin now calls close on the response body if the body
|
23
|
-
responds to close. Previously an existing response body was
|
24
|
-
just ignored.
|
@@ -1,24 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A precompile_views method has been added to the
|
4
|
-
precompile_templates plugin. This method works with Roda's
|
5
|
-
optimized compiled view methods, allowing additional memory
|
6
|
-
sharing between parent and child processes.
|
7
|
-
|
8
|
-
* A freeze_template_caches! method has been added to the
|
9
|
-
precompile_templates plugin. This freezes the template caches,
|
10
|
-
preventing the compilation of additional templates, useful for
|
11
|
-
enforcing that only precompiled templates are used. Additionally,
|
12
|
-
this speeds up access to the template caches.
|
13
|
-
|
14
|
-
* RodaCache#freeze now returns the frozen internal hash, which can
|
15
|
-
then be accessed without a mutex. Previously, freeze only froze
|
16
|
-
the receiver and not the internal hash, so it didn't have the
|
17
|
-
expected effect.
|
18
|
-
|
19
|
-
= Other Improvements
|
20
|
-
|
21
|
-
* The view method in the render plugin is now faster in most cases
|
22
|
-
when a single argument is used. When freezing the application,
|
23
|
-
an additional optimization is performed to increase the
|
24
|
-
performance of the view method even further.
|
@@ -1,9 +0,0 @@
|
|
1
|
-
= Improvements
|
2
|
-
|
3
|
-
* The performance of the render plugin's view method when passed the
|
4
|
-
:content option and no other options or arguments has been improved
|
5
|
-
by about 3x, by calling compiled template methods directly.
|
6
|
-
|
7
|
-
* The compiled template method for the layout is cleared when the
|
8
|
-
render plugin is loaded again, which can fix issues when it is
|
9
|
-
loaded with different options that affect the layout.
|
@@ -1,21 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A recheck_precompiled_assets plugin has been added, which allows
|
4
|
-
for checking for updates to the precompiled asset metadata file,
|
5
|
-
and automatically using the updated data.
|
6
|
-
|
7
|
-
* The common_logger plugin now supports a :method plugin option to
|
8
|
-
specify the method to call on the logger.
|
9
|
-
|
10
|
-
= Other Improvements
|
11
|
-
|
12
|
-
* Plugins and middleware that use keyword arguments are now supported
|
13
|
-
in Ruby 3.
|
14
|
-
|
15
|
-
* The compile_assets class method in the assets plugin now uses an
|
16
|
-
atomic approach to writing the precompiled asset metadata file.
|
17
|
-
|
18
|
-
* Minor method visibility issues have been fixed. The custom_matchers
|
19
|
-
plugin no longer makes the unsupported_matcher request method
|
20
|
-
public, and the render plugin no longer makes the _layout_method
|
21
|
-
public when the application is frozen.
|
@@ -1,34 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A host_authorization plugin has been added to verify the requested
|
4
|
-
Host header is authorized. Using it can prevent DNS rebinding
|
5
|
-
attacks in cases where the application can receive requests for
|
6
|
-
arbitrary hosts.
|
7
|
-
|
8
|
-
To check for authorized hosts in your routing tree, you call the
|
9
|
-
check_host_authorization! method. For example, if you want to
|
10
|
-
check for authorized hosts after serving requests for public
|
11
|
-
files, you could do:
|
12
|
-
|
13
|
-
plugin :public
|
14
|
-
plugin :host_authorization, 'my-domain-name.example.com'
|
15
|
-
|
16
|
-
route do |r|
|
17
|
-
r.public
|
18
|
-
check_host_authorized!
|
19
|
-
|
20
|
-
# ... rest of routing tree
|
21
|
-
end
|
22
|
-
|
23
|
-
In addition to handling single domain names via a string, you can
|
24
|
-
provide an array of domain names, a regexp to match again, or a
|
25
|
-
proc.
|
26
|
-
|
27
|
-
By default, requests using unauthorized hosts receive an empty 403
|
28
|
-
response. If you would like to customize the response, you can
|
29
|
-
pass a block when loading the plugin:
|
30
|
-
|
31
|
-
plugin :host_authorization, 'my-domain-name.example.com' do |r|
|
32
|
-
response.status = 403
|
33
|
-
"Response Body Here"
|
34
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* An optimized_segment_matchers plugin has been added that offers
|
4
|
-
very fast matchers for arbitrary segments (the same segments
|
5
|
-
that would be matched by the String class matcher). The
|
6
|
-
on_segment method it offers accepts no arguments and yields
|
7
|
-
the next segment if there is a segment. The is_segment method
|
8
|
-
is similar, but only yields if the next segment is the final
|
9
|
-
segment.
|
10
|
-
|
11
|
-
= Other Improvements
|
12
|
-
|
13
|
-
* The send_file and attachment methods in the sinatra_helpers plugin
|
14
|
-
now support RFC 5987 UTF-8 and ISO-8859-1 encoded filenames,
|
15
|
-
allowing modern browsers to save files with encoded chracters. For
|
16
|
-
older browsers that do not support RFC 5987, unsupported characters
|
17
|
-
in filenames are replaced with dashes. This is considered to be an
|
18
|
-
improvement over the previous behavior of using Ruby's inspect
|
19
|
-
output for the filename, which could contain backslashes (backslash
|
20
|
-
is not an allowed chracter in Windows filenames).
|
21
|
-
|
22
|
-
* The performance of the String class matcher has been slightly
|
23
|
-
improved.
|
@@ -1,22 +0,0 @@
|
|
1
|
-
= Improvements
|
2
|
-
|
3
|
-
* The typecast_params plugin checks now checks for null bytes by
|
4
|
-
default before typecasting. If null bytes are present, it raises
|
5
|
-
an error. Most applications do not require null bytes in
|
6
|
-
parameters, and in some cases allowing them can lead to security
|
7
|
-
issues, especially when parameters are passed to C extensions.
|
8
|
-
In general, the benefit of forbidding null bytes in parameters is
|
9
|
-
greater than the cost.
|
10
|
-
|
11
|
-
If you would like to continue allowing null bytes, use the
|
12
|
-
:allow_null_bytes option when loading the plugin.
|
13
|
-
|
14
|
-
Note that this change does not affect uploaded files, since those
|
15
|
-
are expected to contain null bytes.
|
16
|
-
|
17
|
-
= Backwards Compatibility
|
18
|
-
|
19
|
-
* The change to the typecast_params plugin to raise an error for
|
20
|
-
null bytes can break applications that are expecting null bytes
|
21
|
-
to be passed in parameters. Such applications should use the
|
22
|
-
:allow_null_bytes option when loading the plugin.
|