roda 3.43.1 → 3.44.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/CHANGELOG +6 -0
- data/doc/release_notes/3.44.0.txt +23 -0
- data/lib/roda/plugins/optimized_segment_matchers.rb +53 -0
- data/lib/roda/plugins/optimized_string_matchers.rb +2 -1
- data/lib/roda/plugins/sinatra_helpers.rb +24 -2
- data/lib/roda/request.rb +2 -2
- data/lib/roda/version.rb +2 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b60182ef0483279ac1d1983495ba020c1803d6c1fe0fa84af882142f816f72bc
|
4
|
+
data.tar.gz: 20f6053b7c73fed454dc3f39e55a516d7a5461a4005356b5788480b8aab36f14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89359f0c972c236bee671606fc7254f4999c6fc03f1b0ef8ff7c9691b581b6e796197b9fbee6fd109ae4d1026624f041d2e64c6182dbf8c80818756543923c9d
|
7
|
+
data.tar.gz: 2d786d8641f5195a65874f3326abe07057748e4de2df7d0a8e8cd9439b6afceb08e65b6a3733e15b0289e273cc070033c1dc466e1909880410b4d05541fa04ae
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
= 3.44.0 (2021-05-12)
|
2
|
+
|
3
|
+
* Add optimized_segment_matchers plugin for optimized matchers for a single String class argument (jeremyevans)
|
4
|
+
|
5
|
+
* Use RFC 5987 UTF-8 and ISO-8859-1 encoded filenames when using send_file and attachment in the sinatra_helpers plugin (jeremyevans)
|
6
|
+
|
1
7
|
= 3.43.1 (2021-04-13)
|
2
8
|
|
3
9
|
* [SECURITY] Fix issue where loading content_security_policy plugin after default_headers plugin had no effect (jeremyevans)
|
@@ -0,0 +1,23 @@
|
|
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.
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
class Roda
|
5
|
+
module RodaPlugins
|
6
|
+
# The optimized_segment_matchers plugin adds two optimized matcher methods,
|
7
|
+
# +r.on_segment+ and +r.is_segment+. +r.on_segment+ is an optimized version of
|
8
|
+
# +r.on String+ that accepts no arguments and yields the next segment if there
|
9
|
+
# is a segment. +r.is_segment+ is an optimized version of +r.is String+ that accepts
|
10
|
+
# no arguments and yields the next segment only if it is the last segment.
|
11
|
+
#
|
12
|
+
# plugin :optimized_segment_matchers
|
13
|
+
#
|
14
|
+
# route do |r|
|
15
|
+
# r.on_segment do |x|
|
16
|
+
# # matches any segment (e.g. /a, /b, but not /)
|
17
|
+
# r.is_segment do |y|
|
18
|
+
# # matches only if final segment (e.g. /a/b, /b/c, but not /c, /c/d/, /c/d/e)
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
module OptimizedSegmentMatchers
|
23
|
+
module RequestMethods
|
24
|
+
# Optimized version of +r.on String+ that yields the next segment if there
|
25
|
+
# is a segment.
|
26
|
+
def on_segment
|
27
|
+
rp = @remaining_path
|
28
|
+
if rp.getbyte(0) == 47
|
29
|
+
if last = rp.index('/', 1)
|
30
|
+
@remaining_path = rp[last, rp.length]
|
31
|
+
always{yield rp[1, last-1]}
|
32
|
+
elsif (len = rp.length) > 1
|
33
|
+
@remaining_path = ""
|
34
|
+
always{yield rp[1, len]}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Optimized version of +r.is String+ that yields the next segment only if it
|
40
|
+
# is the final segment.
|
41
|
+
def is_segment
|
42
|
+
rp = @remaining_path
|
43
|
+
if rp.getbyte(0) == 47 && !rp.index('/', 1) && (len = rp.length) > 1
|
44
|
+
@remaining_path = ""
|
45
|
+
always{yield rp[1, len]}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
register_plugin(:optimized_segment_matchers, OptimizedSegmentMatchers)
|
52
|
+
end
|
53
|
+
end
|
@@ -19,7 +19,8 @@ class Roda
|
|
19
19
|
# end
|
20
20
|
# end
|
21
21
|
#
|
22
|
-
#
|
22
|
+
# If you are using the placeholder_string_matchers plugin, note
|
23
|
+
# that both of these methods only work with plain strings, not
|
23
24
|
# with strings with embedded colons for capturing. Matching will work
|
24
25
|
# correctly in such cases, but the captures will not be yielded to the
|
25
26
|
# match blocks.
|
@@ -211,6 +211,10 @@ class Roda
|
|
211
211
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
212
212
|
# OTHER DEALINGS IN THE SOFTWARE.
|
213
213
|
module SinatraHelpers
|
214
|
+
UTF8_ENCODING = Encoding.find('UTF-8')
|
215
|
+
ISO88591_ENCODING = Encoding.find('ISO-8859-1')
|
216
|
+
BINARY_ENCODING = Encoding.find('BINARY')
|
217
|
+
|
214
218
|
# Depend on the status_303 plugin.
|
215
219
|
def self.load_dependencies(app, _opts = nil)
|
216
220
|
app.plugin :status_303
|
@@ -432,7 +436,25 @@ class Roda
|
|
432
436
|
# instructing the user agents to prompt to save.
|
433
437
|
def attachment(filename = nil, disposition='attachment')
|
434
438
|
if filename
|
435
|
-
|
439
|
+
param_filename = File.basename(filename)
|
440
|
+
encoding = param_filename.encoding
|
441
|
+
|
442
|
+
needs_encoding = param_filename.gsub!(/[^ 0-9a-zA-Z!\#$&\+\.\^_`\|~]+/, '-')
|
443
|
+
params = "; filename=#{param_filename.inspect}"
|
444
|
+
|
445
|
+
if needs_encoding && (encoding == UTF8_ENCODING || encoding == ISO88591_ENCODING)
|
446
|
+
# File name contains non attr-char characters from RFC 5987 Section 3.2.1
|
447
|
+
|
448
|
+
encoded_filename = File.basename(filename).force_encoding(BINARY_ENCODING)
|
449
|
+
# Similar regexp as above, but treat each byte separately, and encode
|
450
|
+
# space characters, since those aren't allowed in attr-char
|
451
|
+
encoded_filename.gsub!(/[^0-9a-zA-Z!\#$&\+\.\^_`\|~]/) do |c|
|
452
|
+
"%%%X" % c.ord
|
453
|
+
end
|
454
|
+
|
455
|
+
encoded_params = "; filename*=#{encoding.to_s}''#{encoded_filename}"
|
456
|
+
end
|
457
|
+
|
436
458
|
unless @headers["Content-Type"]
|
437
459
|
ext = File.extname(filename)
|
438
460
|
unless ext.empty?
|
@@ -440,7 +462,7 @@ class Roda
|
|
440
462
|
end
|
441
463
|
end
|
442
464
|
end
|
443
|
-
@headers["Content-Disposition"] = "#{disposition}#{params}"
|
465
|
+
@headers["Content-Disposition"] = "#{disposition}#{params}#{encoded_params}"
|
444
466
|
end
|
445
467
|
|
446
468
|
# Whether or not the status is set to 1xx. Returns nil if status not yet set.
|
data/lib/roda/request.rb
CHANGED
@@ -468,8 +468,8 @@ class Roda
|
|
468
468
|
if last = rp.index('/', 1)
|
469
469
|
@captures << rp[1, last-1]
|
470
470
|
@remaining_path = rp[last, rp.length]
|
471
|
-
elsif rp.length > 1
|
472
|
-
@captures << rp[1,
|
471
|
+
elsif (len = rp.length) > 1
|
472
|
+
@captures << rp[1, len]
|
473
473
|
@remaining_path = ""
|
474
474
|
end
|
475
475
|
end
|
data/lib/roda/version.rb
CHANGED
@@ -4,11 +4,11 @@ class Roda
|
|
4
4
|
RodaMajorVersion = 3
|
5
5
|
|
6
6
|
# The minor version of Roda, updated for new feature releases of Roda.
|
7
|
-
RodaMinorVersion =
|
7
|
+
RodaMinorVersion = 44
|
8
8
|
|
9
9
|
# The patch version of Roda, updated only for bug fixes from the last
|
10
10
|
# feature release.
|
11
|
-
RodaPatchVersion =
|
11
|
+
RodaPatchVersion = 0
|
12
12
|
|
13
13
|
# The full version of Roda as a string.
|
14
14
|
RodaVersion = "#{RodaMajorVersion}.#{RodaMinorVersion}.#{RodaPatchVersion}".freeze
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.44.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -214,6 +214,7 @@ extra_rdoc_files:
|
|
214
214
|
- doc/release_notes/3.41.0.txt
|
215
215
|
- doc/release_notes/3.42.0.txt
|
216
216
|
- doc/release_notes/3.43.0.txt
|
217
|
+
- doc/release_notes/3.44.0.txt
|
217
218
|
- doc/release_notes/3.5.0.txt
|
218
219
|
- doc/release_notes/3.6.0.txt
|
219
220
|
- doc/release_notes/3.7.0.txt
|
@@ -264,6 +265,7 @@ files:
|
|
264
265
|
- doc/release_notes/3.41.0.txt
|
265
266
|
- doc/release_notes/3.42.0.txt
|
266
267
|
- doc/release_notes/3.43.0.txt
|
268
|
+
- doc/release_notes/3.44.0.txt
|
267
269
|
- doc/release_notes/3.5.0.txt
|
268
270
|
- doc/release_notes/3.6.0.txt
|
269
271
|
- doc/release_notes/3.7.0.txt
|
@@ -333,6 +335,7 @@ files:
|
|
333
335
|
- lib/roda/plugins/named_templates.rb
|
334
336
|
- lib/roda/plugins/not_allowed.rb
|
335
337
|
- lib/roda/plugins/not_found.rb
|
338
|
+
- lib/roda/plugins/optimized_segment_matchers.rb
|
336
339
|
- lib/roda/plugins/optimized_string_matchers.rb
|
337
340
|
- lib/roda/plugins/padrino_render.rb
|
338
341
|
- lib/roda/plugins/param_matchers.rb
|