roda 3.35.0 → 3.36.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 370e18bb1d1cfb9fb8b0c10fda1a4f57161a39c6d733b628ddd60058d231f896
4
- data.tar.gz: fe0c8ddb499cdbafb0f047d9445fca726f742e38674f90731f3421132c373365
3
+ metadata.gz: abd198c51a38d272c8601fb367c12b9ad244f8383bcfb2f0583e7c7e23744eca
4
+ data.tar.gz: 75cee1c957032abd4144f01fbd720794d2f66e7422514fa6e58b8bd5f8087b6e
5
5
  SHA512:
6
- metadata.gz: 60db0b47d97ae40437e0396bc795ac360194bd88067e6611cf277888d054e3c41786eb062f4ab31d6683cb4755a3a27d148a576236c77a4d46db67fc2accc7e1
7
- data.tar.gz: 44745afaa29ccee2d51a132f7b7be4da6818191814a9ff8a2afd52f34636789cb0e4d22eb63ade49ea0411470a73b05a1996c7bb70cc7edf04264fb2fddadb83
6
+ metadata.gz: e3b7fed2ed29b869b205114d3bf644bb81f1f8d3a267682976aa4eef019e9ca015ade6526d75a99d5f6f1128991f70ba692e1c527acdc62874fbd39e49c24dba
7
+ data.tar.gz: 341da7749e2432b1a3139f29b09f6a219480bb6984a74e121fc2b30bc4f7c4f7c6e51b1be01fb836ef85399cef1cfd15249495d335c80b44eed75a1a657960c7
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ = 3.36.0 (2020-09-14)
2
+
3
+ * Add multi_public plugin, for serving files from multiple public directories (jeremyevans)
4
+
5
+ * Support report-to directive in the content_security_policy plugin (jeremyevans)
6
+
7
+ * Add Vary response header when using type_routing plugin with Accept request header to prevent caching issues (jeremyevans)
8
+
1
9
  = 3.35.0 (2020-08-14)
2
10
 
3
11
  * Add r plugin for r method for accessing request, useful when r local variable is not in scope (jeremyevans)
@@ -0,0 +1,17 @@
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.
@@ -56,6 +56,7 @@ class Roda
56
56
  # * media_src
57
57
  # * object_src
58
58
  # * plugin_types
59
+ # * report_to
59
60
  # * report_uri
60
61
  # * require_sri_for
61
62
  # * sandbox
@@ -123,6 +124,7 @@ class Roda
123
124
  media-src
124
125
  object-src
125
126
  plugin-types
127
+ report-to
126
128
  report-uri
127
129
  require-sri-for
128
130
  sandbox
@@ -145,9 +147,7 @@ class Roda
145
147
  # add_* method name adds to the setting value, or clears setting if no values
146
148
  # are given.
147
149
  define_method("add_#{meth}") do |*args|
148
- if args.empty?
149
- @opts[setting]
150
- else
150
+ unless args.empty?
151
151
  @opts[setting] ||= EMPTY_ARRAY
152
152
  @opts[setting] += args
153
153
  @opts[setting].freeze
@@ -0,0 +1,87 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The multi_public plugin adds an +r.multi_public+ method that accepts an argument specifying
7
+ # a directory from which to serve static files. It is similar to the public plugin, but
8
+ # allows for multiple separate directories.
9
+ #
10
+ # Here's an example of using the multi_public plugin to serve 3 different types of files
11
+ # from 3 different directories:
12
+ #
13
+ # plugin :multi_public,
14
+ # img: 'static/images',
15
+ # font: 'assets/fonts',
16
+ # form: 'static/forms/pdfs'
17
+ #
18
+ # r.route do
19
+ # r.on "images" do
20
+ # r.multi_public(:img)
21
+ # end
22
+ #
23
+ # r.on "fonts" do
24
+ # r.multi_public(:font)
25
+ # end
26
+ #
27
+ # r.on "forms" do
28
+ # r.multi_public(:form)
29
+ # end
30
+ # end
31
+ #
32
+ # It is possible to simplify the routing tree for this using string keys and an array
33
+ # matcher:
34
+ #
35
+ # plugin :multi_public,
36
+ # 'images' => 'static/images',
37
+ # 'fonts' => 'assets/fonts',
38
+ # 'forms' => 'static/forms/pdfs'
39
+ #
40
+ # r.route do
41
+ # r.on %w"images fonts forms" do |dir|
42
+ # r.multi_public(dir)
43
+ # end
44
+ # end
45
+ #
46
+ # You can provide custom headers and default mime type for each directory using an array
47
+ # of three elements as the value, with the first element being the path, the second
48
+ # being the custom headers, and the third being the default mime type:
49
+ #
50
+ # plugin :multi_public,
51
+ # 'images' => ['static/images', {'Cache-Control'=>'max-age=86400'}, nil],
52
+ # 'fonts' => ['assets/fonts', {'Cache-Control'=>'max-age=31536000'}, 'font/ttf'],
53
+ # 'forms' => ['static/forms/pdfs', nil, 'application/pdf']
54
+ #
55
+ # r.route do
56
+ # r.on %w"images fonts forms" do |dir|
57
+ # r.multi_public(dir)
58
+ # end
59
+ # end
60
+ module MultiPublic
61
+ def self.load_dependencies(app, _, opts=OPTS)
62
+ app.plugin(:public, opts)
63
+ end
64
+
65
+ # Use the given directories to setup servers. Any opts are passed to the public plugin.
66
+ def self.configure(app, directories, _=OPTS)
67
+ roots = app.opts[:multi_public_servers] = (app.opts[:multi_public_servers] || {}).dup
68
+ directories.each do |key, path|
69
+ path, headers, mime = path
70
+ roots[key] = ::Rack::File.new(app.expand_path(path), headers||{}, mime||'text/plain')
71
+ end
72
+ roots.freeze
73
+ end
74
+
75
+ module RequestMethods
76
+ # Serve files from the directory corresponding to the given key if the file exists and
77
+ # this is a GET request.
78
+ def multi_public(key)
79
+ public_serve_with(roda_class.opts[:multi_public_servers].fetch(key))
80
+ end
81
+ end
82
+ end
83
+
84
+ register_plugin(:multi_public, MultiPublic)
85
+ end
86
+ end
87
+
@@ -60,21 +60,7 @@ class Roda
60
60
  module RequestMethods
61
61
  # Serve files from the public directory if the file exists and this is a GET request.
62
62
  def public
63
- if is_get?
64
- path = PARSER.unescape(real_remaining_path)
65
- return if path.include?("\0")
66
-
67
- roda_opts = roda_class.opts
68
- server = roda_opts[:public_server]
69
- path = ::File.join(server.root, *public_path_segments(path))
70
-
71
- public_serve_compressed(server, path, '.br', 'br') if roda_opts[:public_brotli]
72
- public_serve_compressed(server, path, '.gz', 'gzip') if roda_opts[:public_gzip]
73
-
74
- if public_file_readable?(path)
75
- halt public_serve(server, path)
76
- end
77
- end
63
+ public_serve_with(roda_class.opts[:public_server])
78
64
  end
79
65
 
80
66
  private
@@ -101,6 +87,22 @@ class Roda
101
87
  # :nocov:
102
88
  end
103
89
 
90
+ def public_serve_with(server)
91
+ return unless is_get?
92
+ path = PARSER.unescape(real_remaining_path)
93
+ return if path.include?("\0")
94
+
95
+ roda_opts = roda_class.opts
96
+ path = ::File.join(server.root, *public_path_segments(path))
97
+
98
+ public_serve_compressed(server, path, '.br', 'br') if roda_opts[:public_brotli]
99
+ public_serve_compressed(server, path, '.gz', 'gzip') if roda_opts[:public_gzip]
100
+
101
+ if public_file_readable?(path)
102
+ halt public_serve(server, path)
103
+ end
104
+ end
105
+
104
106
  def public_serve_compressed(server, path, suffix, encoding)
105
107
  if env['HTTP_ACCEPT_ENCODING'] =~ /\b#{encoding}\b/
106
108
  compressed_path = path + suffix
@@ -4,7 +4,7 @@
4
4
  class Roda
5
5
  module RodaPlugins
6
6
  # This plugin makes it easier to to respond to specific request data types. User agents can request
7
- # specific data types by either supplying an appropriate +Accept+ header
7
+ # specific data types by either supplying an appropriate +Accept+ request header
8
8
  # or by appending it as file extension to the path.
9
9
  #
10
10
  # Example:
@@ -50,6 +50,10 @@ class Roda
50
50
  # Content-Type header will be set to Roda's default (which you can override via
51
51
  # the default_headers plugin).
52
52
  #
53
+ # If the type routing is based on the +Accept+ request header and not the file extension,
54
+ # then an appropriate +Vary+ header will be set or appended to, so that HTTP caches do
55
+ # not serve the same result for requests with different +Accept+ headers.
56
+ #
53
57
  # To match custom extensions, use the :types option:
54
58
  #
55
59
  # plugin :type_routing, types: {
@@ -195,6 +199,7 @@ class Roda
195
199
  @env['HTTP_ACCEPT'].to_s.split(/\s*,\s*/).map do |part|
196
200
  mime, _= part.split(/\s*;\s*/, 2)
197
201
  if sym = mimes[mime]
202
+ response['Vary'] = (vary = response['Vary']) ? "#{vary}, Accept" : 'Accept'
198
203
  return sym
199
204
  end
200
205
  end
@@ -4,7 +4,7 @@ class Roda
4
4
  RodaMajorVersion = 3
5
5
 
6
6
  # The minor version of Roda, updated for new feature releases of Roda.
7
- RodaMinorVersion = 35
7
+ RodaMinorVersion = 36
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
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.35.0
4
+ version: 3.36.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: 2020-08-14 00:00:00.000000000 Z
11
+ date: 2020-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -211,6 +211,7 @@ extra_rdoc_files:
211
211
  - doc/release_notes/3.33.0.txt
212
212
  - doc/release_notes/3.34.0.txt
213
213
  - doc/release_notes/3.35.0.txt
214
+ - doc/release_notes/3.36.0.txt
214
215
  files:
215
216
  - CHANGELOG
216
217
  - MIT-LICENSE
@@ -247,6 +248,7 @@ files:
247
248
  - doc/release_notes/3.33.0.txt
248
249
  - doc/release_notes/3.34.0.txt
249
250
  - doc/release_notes/3.35.0.txt
251
+ - doc/release_notes/3.36.0.txt
250
252
  - doc/release_notes/3.4.0.txt
251
253
  - doc/release_notes/3.5.0.txt
252
254
  - doc/release_notes/3.6.0.txt
@@ -307,6 +309,7 @@ files:
307
309
  - lib/roda/plugins/middleware.rb
308
310
  - lib/roda/plugins/middleware_stack.rb
309
311
  - lib/roda/plugins/module_include.rb
312
+ - lib/roda/plugins/multi_public.rb
310
313
  - lib/roda/plugins/multi_route.rb
311
314
  - lib/roda/plugins/multi_run.rb
312
315
  - lib/roda/plugins/multi_view.rb