roda 3.81.0 → 3.82.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +8 -0
- data/doc/release_notes/3.82.0.txt +43 -0
- data/lib/roda/plugins/capture_erb.rb +17 -5
- data/lib/roda/plugins/plain_hash_response_headers.rb +1 -1
- data/lib/roda/plugins/public.rb +49 -19
- data/lib/roda/plugins/render.rb +13 -0
- data/lib/roda/version.rb +1 -1
- metadata +5 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdf5797c96af1d28dc4d13f0c95ac0468d60eb30b6a128b2cee2c26a08eb0a7f
|
4
|
+
data.tar.gz: d687b3cd03657bdcfda6f87a7a7a2a3b55e9a0c4f856cabd3d080865cc7d9ad2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e518b9638e98713ed54fd4c609069edf81a81987adf53ce2b7a09fa7110244f67b109cbe91c9c03d713f824900649d1c4b2ad435823852dcdfd01094f506afae
|
7
|
+
data.tar.gz: '00877a1338b70a5b96dab7fb946e21c7c916c776666286f80251b362e29ca6e040ffeb9b7a7258cf3af4c9246de5a6c35c5332385bd3cb926505776102c9112c'
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
= 3.82.0 (2024-07-12)
|
2
|
+
|
3
|
+
* Add :encodings option to public plugin to support configurable encoding order (jeremyevans)
|
4
|
+
|
5
|
+
* Add :zstd option to public plugin to supplement it to serve zstd-compressed files with .zst extension (jeremyevans)
|
6
|
+
|
7
|
+
* Make capture_erb plugin call integrate better with erubi/capture_block (jeremyevans)
|
8
|
+
|
1
9
|
= 3.81.0 (2024-06-12)
|
2
10
|
|
3
11
|
* Make assets plugin :early_hints option follow Rack 3 SPEC if using Rack 3 (jeremyevans)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A :zstd option has been added to the public and multi_public
|
4
|
+
plugins to support serving zstd-compressed files with a .zst
|
5
|
+
extension. This option is similar to the existing :gzip and
|
6
|
+
:brotli plugin options. Chrome started supporting zstd encoding
|
7
|
+
in March.
|
8
|
+
|
9
|
+
* An :encodings option has been added to the public and multi_public
|
10
|
+
plugins, for more control over how encodings are handled. This
|
11
|
+
allows for changing the order in which encodings are attempted, the
|
12
|
+
use of custom encodings, and the use of different file extensions
|
13
|
+
for encodings. Example:
|
14
|
+
|
15
|
+
plugin :public, encodings: {'zstd'=>'.zst', 'deflate'=>'.deflate'}
|
16
|
+
|
17
|
+
If the :encodings option is not provided, the :zstd, :brotli, and
|
18
|
+
:gzip options are used to build an equivalent :encodings option.
|
19
|
+
|
20
|
+
= Other Improvements
|
21
|
+
|
22
|
+
* The capture_erb plugin now integrates better when using
|
23
|
+
erubi/capture_block for <%= method do %> support in ERB templates,
|
24
|
+
using the native capture method provided by the buffer object.
|
25
|
+
|
26
|
+
* Encoding handling has been more optimized in the public plugin.
|
27
|
+
Regexps for the encodings are precomputed, avoiding a regexp
|
28
|
+
allocation per request per encoding attempted. On Ruby 2.4+
|
29
|
+
Regexp#match? is used for better performance. If the
|
30
|
+
Accept-Encoding header is not present, no encoding matching
|
31
|
+
is attemped.
|
32
|
+
|
33
|
+
= Backwards Compatibility
|
34
|
+
|
35
|
+
* The private public_serve_compressed request method in the public
|
36
|
+
plugin now assumes it is called after the encoding is already
|
37
|
+
valid. If you are calling this method in your own code, you now
|
38
|
+
need to perform checks to make sure the client can accept the
|
39
|
+
encoding before calling this method.
|
40
|
+
|
41
|
+
* The :public_gzip and :public_brotli application options are no
|
42
|
+
longer set by the public plugin. The :public_encodings option
|
43
|
+
is now set.
|
@@ -15,6 +15,11 @@ class Roda
|
|
15
15
|
# inside templates. It can be combined with the inject_erb plugin
|
16
16
|
# to wrap template blocks with arbitrary output and then inject the
|
17
17
|
# wrapped output into the template.
|
18
|
+
#
|
19
|
+
# If the output buffer object responds to +capture+ (e.g. when
|
20
|
+
# +erubi/capture_block+ is being used as the template engine),
|
21
|
+
# this will call +capture+ on the output buffer object, instead
|
22
|
+
# of setting the output buffer object temporarily to a new object.
|
18
23
|
module CaptureERB
|
19
24
|
def self.load_dependencies(app)
|
20
25
|
app.plugin :render
|
@@ -25,13 +30,20 @@ class Roda
|
|
25
30
|
# with an empty string, and then yield to the block.
|
26
31
|
# Return the value of the block, converted to a string.
|
27
32
|
# Restore the previous ERB output buffer before returning.
|
28
|
-
def capture_erb
|
33
|
+
def capture_erb(&block)
|
29
34
|
outvar = render_opts[:template_opts][:outvar]
|
30
35
|
buf_was = instance_variable_get(outvar)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
|
37
|
+
if buf_was.respond_to?(:capture)
|
38
|
+
buf_was.capture(&block)
|
39
|
+
else
|
40
|
+
begin
|
41
|
+
instance_variable_set(outvar, String.new)
|
42
|
+
yield.to_s
|
43
|
+
ensure
|
44
|
+
instance_variable_set(outvar, buf_was) if outvar && buf_was
|
45
|
+
end
|
46
|
+
end
|
35
47
|
end
|
36
48
|
end
|
37
49
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
class Roda
|
5
5
|
module RodaPlugins
|
6
|
-
# The
|
6
|
+
# The plain_hash_response_headers plugin will change Roda to
|
7
7
|
# use a plain hash for response headers. This is Roda's
|
8
8
|
# default behavior on Rack 2, but on Rack 3+, Roda defaults
|
9
9
|
# to using Rack::Headers for response headers for backwards
|
data/lib/roda/plugins/public.rb
CHANGED
@@ -44,15 +44,30 @@ class Roda
|
|
44
44
|
SPLIT = Regexp.union(*[File::SEPARATOR, File::ALT_SEPARATOR].compact)
|
45
45
|
PARSER = URI::DEFAULT_PARSER
|
46
46
|
RACK_FILES = defined?(Rack::Files) ? Rack::Files : Rack::File
|
47
|
+
ENCODING_MAP = {:zstd=>'zstd', :brotli=>'br', :gzip=>'gzip'}.freeze
|
48
|
+
ENCODING_EXTENSIONS = {'br'=>'.br', 'gzip'=>'.gz', 'zstd'=>'.zst'}.freeze
|
49
|
+
|
50
|
+
# :nocov:
|
51
|
+
MATCH_METHOD = RUBY_VERSION >= '2.4' ? :match? : :match
|
52
|
+
# :nocov:
|
47
53
|
|
48
54
|
# Use options given to setup a Rack::File instance for serving files. Options:
|
55
|
+
# :brotli :: Whether to serve already brotli-compressed files with a .br extension
|
56
|
+
# for clients supporting "br" transfer encoding.
|
49
57
|
# :default_mime :: The default mime type to use if the mime type is not recognized.
|
58
|
+
# :encodings :: An enumerable of pairs to handle accepted encodings. The first
|
59
|
+
# element of the pair is the accepted encoding name (e.g. 'gzip'),
|
60
|
+
# and the second element of the pair is the file extension (e.g.
|
61
|
+
# '.gz'). This allows configuration of the order in which encodings
|
62
|
+
# are tried, to prefer brotli to zstd for example, or to support
|
63
|
+
# encodings other than zstd, brotli, and gzip. This takes
|
64
|
+
# precedence over the :brotli, :gzip, and :zstd options if given.
|
50
65
|
# :gzip :: Whether to serve already gzipped files with a .gz extension for clients
|
51
|
-
# supporting
|
52
|
-
# :brotli :: Whether to serve already brotli-compressed files with a .br extension
|
53
|
-
# for clients supporting brotli transfer encoding.
|
66
|
+
# supporting "gzip" transfer encoding.
|
54
67
|
# :headers :: A hash of headers to use for statically served files
|
55
68
|
# :root :: Use this option for the root of the public directory (default: "public")
|
69
|
+
# :zstd :: Whether to serve already zstd-compressed files with a .zst extension
|
70
|
+
# for clients supporting "zstd" transfer encoding.
|
56
71
|
def self.configure(app, opts={})
|
57
72
|
if opts[:root]
|
58
73
|
app.opts[:public_root] = app.expand_path(opts[:root])
|
@@ -60,8 +75,18 @@ class Roda
|
|
60
75
|
app.opts[:public_root] = app.expand_path("public")
|
61
76
|
end
|
62
77
|
app.opts[:public_server] = RACK_FILES.new(app.opts[:public_root], opts[:headers]||{}, opts[:default_mime] || 'text/plain')
|
63
|
-
|
64
|
-
|
78
|
+
|
79
|
+
unless encodings = opts[:encodings]
|
80
|
+
if ENCODING_MAP.any?{|k,| opts.has_key?(k)}
|
81
|
+
encodings = ENCODING_MAP.map{|k, v| [v, ENCODING_EXTENSIONS[v]] if opts[k]}.compact
|
82
|
+
end
|
83
|
+
end
|
84
|
+
encodings = (encodings || app.opts[:public_encodings] || EMPTY_ARRAY).map(&:dup).freeze
|
85
|
+
encodings.each do |a|
|
86
|
+
a << /\b#{a[0]}\b/
|
87
|
+
end
|
88
|
+
encodings.each(&:freeze)
|
89
|
+
app.opts[:public_encodings] = encodings
|
65
90
|
end
|
66
91
|
|
67
92
|
module RequestMethods
|
@@ -102,8 +127,13 @@ class Roda
|
|
102
127
|
roda_opts = roda_class.opts
|
103
128
|
path = ::File.join(server.root, *public_path_segments(path))
|
104
129
|
|
105
|
-
|
106
|
-
|
130
|
+
if accept_encoding = env['HTTP_ACCEPT_ENCODING']
|
131
|
+
roda_opts[:public_encodings].each do |enc, ext, regexp|
|
132
|
+
if regexp.send(MATCH_METHOD, accept_encoding)
|
133
|
+
public_serve_compressed(server, path, ext, enc)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
107
137
|
|
108
138
|
if public_file_readable?(path)
|
109
139
|
s, h, b = public_serve(server, path)
|
@@ -113,22 +143,22 @@ class Roda
|
|
113
143
|
end
|
114
144
|
end
|
115
145
|
|
146
|
+
# Serve the compressed file if it exists. This should only
|
147
|
+
# be called if the client will accept the related encoding.
|
116
148
|
def public_serve_compressed(server, path, suffix, encoding)
|
117
|
-
|
118
|
-
compressed_path = path + suffix
|
149
|
+
compressed_path = path + suffix
|
119
150
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
unless s == 304
|
126
|
-
headers[RodaResponseHeaders::CONTENT_TYPE] = ::Rack::Mime.mime_type(::File.extname(path), 'text/plain')
|
127
|
-
headers[RodaResponseHeaders::CONTENT_ENCODING] = encoding
|
128
|
-
end
|
151
|
+
if public_file_readable?(compressed_path)
|
152
|
+
s, h, b = public_serve(server, compressed_path)
|
153
|
+
headers = response.headers
|
154
|
+
headers.replace(h)
|
129
155
|
|
130
|
-
|
156
|
+
unless s == 304
|
157
|
+
headers[RodaResponseHeaders::CONTENT_TYPE] = ::Rack::Mime.mime_type(::File.extname(path), 'text/plain')
|
158
|
+
headers[RodaResponseHeaders::CONTENT_ENCODING] = encoding
|
131
159
|
end
|
160
|
+
|
161
|
+
halt [s, headers, b]
|
132
162
|
end
|
133
163
|
end
|
134
164
|
|
data/lib/roda/plugins/render.rb
CHANGED
@@ -148,6 +148,19 @@ class Roda
|
|
148
148
|
# inject the content into the output. To get similar behavior with Roda, you have
|
149
149
|
# a few different options you can use.
|
150
150
|
#
|
151
|
+
# == Use Erubi::CaptureBlockEngine
|
152
|
+
#
|
153
|
+
# Roda defaults to using Erubi for erb template rendering. Erubi 1.13.0+ includes
|
154
|
+
# support for an erb variant that supports blocks in <tt><%=</tt> and <tt><%==</tt>
|
155
|
+
# tags. To use it:
|
156
|
+
#
|
157
|
+
# require 'erubi/capture_block'
|
158
|
+
# plugin :render, template_opts: {engine_class: Erubi::CaptureBlockEngine}
|
159
|
+
#
|
160
|
+
# See the Erubi documentation for how to capture data inside the block. Make sure
|
161
|
+
# the method call (+some_method+ in the example) returns the output you want added
|
162
|
+
# to the rendered body.
|
163
|
+
#
|
151
164
|
# == Directly Inject Template Output
|
152
165
|
#
|
153
166
|
# You can switch from a <tt><%=</tt> tag to using a <tt><%</tt> tag:
|
data/lib/roda/version.rb
CHANGED
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.82.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: 2024-
|
11
|
+
date: 2024-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -122,20 +122,6 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: sassc
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: json
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -256,6 +242,7 @@ extra_rdoc_files:
|
|
256
242
|
- doc/release_notes/3.8.0.txt
|
257
243
|
- doc/release_notes/3.80.0.txt
|
258
244
|
- doc/release_notes/3.81.0.txt
|
245
|
+
- doc/release_notes/3.82.0.txt
|
259
246
|
- doc/release_notes/3.9.0.txt
|
260
247
|
files:
|
261
248
|
- CHANGELOG
|
@@ -344,6 +331,7 @@ files:
|
|
344
331
|
- doc/release_notes/3.8.0.txt
|
345
332
|
- doc/release_notes/3.80.0.txt
|
346
333
|
- doc/release_notes/3.81.0.txt
|
334
|
+
- doc/release_notes/3.82.0.txt
|
347
335
|
- doc/release_notes/3.9.0.txt
|
348
336
|
- lib/roda.rb
|
349
337
|
- lib/roda/cache.rb
|
@@ -509,7 +497,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
509
497
|
- !ruby/object:Gem::Version
|
510
498
|
version: '0'
|
511
499
|
requirements: []
|
512
|
-
rubygems_version: 3.5.
|
500
|
+
rubygems_version: 3.5.11
|
513
501
|
signing_key:
|
514
502
|
specification_version: 4
|
515
503
|
summary: Routing tree web toolkit
|