actionpack 7.0.8.7 → 7.2.2.1
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.md +90 -537
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +119 -106
- data/lib/abstract_controller/caching/fragments.rb +51 -52
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +94 -67
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +9 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +121 -91
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
- data/lib/abstract_controller/rendering.rb +14 -13
- data/lib/abstract_controller/translation.rb +12 -30
- data/lib/abstract_controller/url_for.rb +9 -5
- data/lib/abstract_controller.rb +8 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +78 -73
- data/lib/action_controller/base.rb +199 -141
- data/lib/action_controller/caching.rb +16 -11
- data/lib/action_controller/deprecator.rb +9 -0
- data/lib/action_controller/form_builder.rb +21 -16
- data/lib/action_controller/log_subscriber.rb +19 -5
- data/lib/action_controller/metal/allow_browser.rb +123 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +187 -174
- data/lib/action_controller/metal/content_security_policy.rb +26 -25
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +65 -54
- data/lib/action_controller/metal/default_headers.rb +6 -2
- data/lib/action_controller/metal/etag_with_flash.rb +4 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
- data/lib/action_controller/metal/exceptions.rb +19 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +20 -16
- data/lib/action_controller/metal/helpers.rb +64 -67
- data/lib/action_controller/metal/http_authentication.rb +212 -199
- data/lib/action_controller/metal/implicit_render.rb +21 -17
- data/lib/action_controller/metal/instrumentation.rb +22 -12
- data/lib/action_controller/metal/live.rb +125 -92
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +58 -58
- data/lib/action_controller/metal/permissions_policy.rb +14 -13
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +110 -84
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -82
- data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
- data/lib/action_controller/metal/rescue.rb +12 -8
- data/lib/action_controller/metal/streaming.rb +174 -132
- data/lib/action_controller/metal/strong_parameters.rb +598 -473
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +23 -14
- data/lib/action_controller/metal.rb +145 -61
- data/lib/action_controller/railtie.rb +25 -9
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +105 -66
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +157 -128
- data/lib/action_controller.rb +17 -3
- data/lib/action_dispatch/constants.rb +34 -0
- data/lib/action_dispatch/deprecator.rb +9 -0
- data/lib/action_dispatch/http/cache.rb +28 -29
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +48 -45
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +23 -21
- data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
- data/lib/action_dispatch/http/mime_type.rb +60 -30
- data/lib/action_dispatch/http/mime_types.rb +5 -1
- data/lib/action_dispatch/http/parameters.rb +12 -10
- data/lib/action_dispatch/http/permissions_policy.rb +32 -27
- data/lib/action_dispatch/http/rack_cache.rb +4 -0
- data/lib/action_dispatch/http/request.rb +132 -79
- data/lib/action_dispatch/http/response.rb +136 -103
- data/lib/action_dispatch/http/upload.rb +19 -15
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +19 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +18 -15
- data/lib/action_dispatch/journey/route.rb +12 -9
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +13 -10
- data/lib/action_dispatch/journey/routes.rb +6 -4
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +25 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
- data/lib/action_dispatch/middleware/callbacks.rb +4 -0
- data/lib/action_dispatch/middleware/cookies.rb +192 -194
- data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
- data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
- data/lib/action_dispatch/middleware/debug_view.rb +9 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
- data/lib/action_dispatch/middleware/executor.rb +9 -1
- data/lib/action_dispatch/middleware/flash.rb +65 -46
- data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
- data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
- data/lib/action_dispatch/middleware/reloader.rb +9 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
- data/lib/action_dispatch/middleware/request_id.rb +15 -8
- data/lib/action_dispatch/middleware/server_timing.rb +8 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
- data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
- data/lib/action_dispatch/middleware/ssl.rb +60 -45
- data/lib/action_dispatch/middleware/stack.rb +15 -9
- data/lib/action_dispatch/middleware/static.rb +40 -34
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +47 -38
- data/lib/action_dispatch/railtie.rb +12 -4
- data/lib/action_dispatch/request/session.rb +39 -27
- data/lib/action_dispatch/request/utils.rb +10 -3
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +59 -9
- data/lib/action_dispatch/routing/mapper.rb +686 -639
- data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
- data/lib/action_dispatch/routing/redirection.rb +52 -38
- data/lib/action_dispatch/routing/route_set.rb +106 -62
- data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
- data/lib/action_dispatch/routing/url_for.rb +131 -122
- data/lib/action_dispatch/routing.rb +152 -150
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +27 -19
- data/lib/action_dispatch/system_testing/driver.rb +16 -22
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +9 -7
- data/lib/action_dispatch/testing/assertions/response.rb +36 -26
- data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
- data/lib/action_dispatch/testing/assertions.rb +5 -1
- data/lib/action_dispatch/testing/integration.rb +240 -229
- data/lib/action_dispatch/testing/request_encoder.rb +6 -1
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +14 -9
- data/lib/action_dispatch/testing/test_request.rb +4 -2
- data/lib/action_dispatch/testing/test_response.rb +34 -19
- data/lib/action_dispatch.rb +52 -21
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +18 -17
- metadata +86 -27
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "singleton"
|
4
6
|
|
5
7
|
module Mime
|
@@ -11,6 +13,7 @@ module Mime
|
|
11
13
|
def initialize
|
12
14
|
@mimes = []
|
13
15
|
@symbols = []
|
16
|
+
@symbols_set = Set.new
|
14
17
|
end
|
15
18
|
|
16
19
|
def each(&block)
|
@@ -19,17 +22,25 @@ module Mime
|
|
19
22
|
|
20
23
|
def <<(type)
|
21
24
|
@mimes << type
|
22
|
-
|
25
|
+
sym_type = type.to_sym
|
26
|
+
@symbols << sym_type
|
27
|
+
@symbols_set << sym_type
|
23
28
|
end
|
24
29
|
|
25
30
|
def delete_if
|
26
31
|
@mimes.delete_if do |x|
|
27
32
|
if yield x
|
28
|
-
|
33
|
+
sym_type = x.to_sym
|
34
|
+
@symbols.delete(sym_type)
|
35
|
+
@symbols_set.delete(sym_type)
|
29
36
|
true
|
30
37
|
end
|
31
38
|
end
|
32
39
|
end
|
40
|
+
|
41
|
+
def valid_symbols?(symbols) # :nodoc
|
42
|
+
symbols.all? { |s| @symbols_set.include?(s) }
|
43
|
+
end
|
33
44
|
end
|
34
45
|
|
35
46
|
SET = Mimes.new
|
@@ -42,25 +53,34 @@ module Mime
|
|
42
53
|
Type.lookup_by_extension(type)
|
43
54
|
end
|
44
55
|
|
56
|
+
def symbols
|
57
|
+
SET.symbols
|
58
|
+
end
|
59
|
+
|
60
|
+
def valid_symbols?(symbols) # :nodoc:
|
61
|
+
SET.valid_symbols?(symbols)
|
62
|
+
end
|
63
|
+
|
45
64
|
def fetch(type, &block)
|
46
65
|
return type if type.is_a?(Type)
|
47
66
|
EXTENSION_LOOKUP.fetch(type.to_s, &block)
|
48
67
|
end
|
49
68
|
end
|
50
69
|
|
51
|
-
# Encapsulates the notion of a MIME type. Can be used at render time, for
|
70
|
+
# Encapsulates the notion of a MIME type. Can be used at render time, for
|
71
|
+
# example, with:
|
52
72
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
73
|
+
# class PostsController < ActionController::Base
|
74
|
+
# def show
|
75
|
+
# @post = Post.find(params[:id])
|
56
76
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
77
|
+
# respond_to do |format|
|
78
|
+
# format.html
|
79
|
+
# format.ics { render body: @post.to_ics, mime_type: Mime::Type.lookup("text/calendar") }
|
80
|
+
# format.xml { render xml: @post }
|
81
|
+
# end
|
61
82
|
# end
|
62
83
|
# end
|
63
|
-
# end
|
64
84
|
class Type
|
65
85
|
attr_reader :symbol
|
66
86
|
|
@@ -135,13 +155,20 @@ module Mime
|
|
135
155
|
|
136
156
|
class << self
|
137
157
|
TRAILING_STAR_REGEXP = /^(text|application)\/\*/
|
138
|
-
|
158
|
+
# all media-type parameters need to be before the q-parameter
|
159
|
+
# https://www.rfc-editor.org/rfc/rfc7231#section-5.3.2
|
160
|
+
PARAMETER_SEPARATOR_REGEXP = /;\s*q="?/
|
161
|
+
ACCEPT_HEADER_REGEXP = /[^,\s"](?:[^,"]|"[^"]*")*/
|
139
162
|
|
140
163
|
def register_callback(&block)
|
141
164
|
@register_callbacks << block
|
142
165
|
end
|
143
166
|
|
144
167
|
def lookup(string)
|
168
|
+
return LOOKUP[string] if LOOKUP.key?(string)
|
169
|
+
|
170
|
+
# fallback to the media-type without parameters if it was not found
|
171
|
+
string = string.split(";", 2)[0]&.rstrip
|
145
172
|
LOOKUP[string] || Type.new(string)
|
146
173
|
end
|
147
174
|
|
@@ -149,8 +176,9 @@ module Mime
|
|
149
176
|
EXTENSION_LOOKUP[extension.to_s]
|
150
177
|
end
|
151
178
|
|
152
|
-
# Registers an alias that's not used on MIME type lookup, but can be referenced
|
153
|
-
# rendering different HTML versions depending on
|
179
|
+
# Registers an alias that's not used on MIME type lookup, but can be referenced
|
180
|
+
# directly. Especially useful for rendering different HTML versions depending on
|
181
|
+
# the user agent, like an iPhone.
|
154
182
|
def register_alias(string, symbol, extension_synonyms = [])
|
155
183
|
register(string, symbol, [], extension_synonyms, true)
|
156
184
|
end
|
@@ -171,12 +199,14 @@ module Mime
|
|
171
199
|
|
172
200
|
def parse(accept_header)
|
173
201
|
if !accept_header.include?(",")
|
174
|
-
|
175
|
-
|
176
|
-
|
202
|
+
if (index = accept_header.index(PARAMETER_SEPARATOR_REGEXP))
|
203
|
+
accept_header = accept_header[0, index].strip
|
204
|
+
end
|
205
|
+
return [] if accept_header.blank?
|
206
|
+
parse_trailing_star(accept_header) || Array(Mime::Type.lookup(accept_header))
|
177
207
|
else
|
178
208
|
list, index = [], 0
|
179
|
-
accept_header.
|
209
|
+
accept_header.scan(ACCEPT_HEADER_REGEXP).each do |header|
|
180
210
|
params, q = header.split(PARAMETER_SEPARATOR_REGEXP)
|
181
211
|
|
182
212
|
next unless params
|
@@ -198,11 +228,11 @@ module Mime
|
|
198
228
|
parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
|
199
229
|
end
|
200
230
|
|
201
|
-
# For an input of
|
202
|
-
# Mime[:html], Mime[:css], Mime[:csv], Mime[:js], Mime[:yaml], Mime[:text]
|
231
|
+
# For an input of `'text'`, returns `[Mime[:json], Mime[:xml], Mime[:ics],
|
232
|
+
# Mime[:html], Mime[:css], Mime[:csv], Mime[:js], Mime[:yaml], Mime[:text]]`.
|
203
233
|
#
|
204
|
-
# For an input of
|
205
|
-
# Mime[:
|
234
|
+
# For an input of `'application'`, returns `[Mime[:html], Mime[:js], Mime[:xml],
|
235
|
+
# Mime[:yaml], Mime[:atom], Mime[:json], Mime[:rss], Mime[:url_encoded_form]]`.
|
206
236
|
def parse_data_with_trailing_star(type)
|
207
237
|
Mime::SET.select { |m| m.match?(type) }
|
208
238
|
end
|
@@ -211,7 +241,7 @@ module Mime
|
|
211
241
|
#
|
212
242
|
# To unregister a MIME type:
|
213
243
|
#
|
214
|
-
#
|
244
|
+
# Mime::Type.unregister(:mobile)
|
215
245
|
def unregister(symbol)
|
216
246
|
symbol = symbol.downcase
|
217
247
|
if mime = Mime[symbol]
|
@@ -225,7 +255,7 @@ module Mime
|
|
225
255
|
attr_reader :hash
|
226
256
|
|
227
257
|
MIME_NAME = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}"
|
228
|
-
MIME_PARAMETER_VALUE = "
|
258
|
+
MIME_PARAMETER_VALUE = "(?:#{MIME_NAME}|\"[^\"\r\\\\]*\")"
|
229
259
|
MIME_PARAMETER = "\s*;\s*#{MIME_NAME}(?:=#{MIME_PARAMETER_VALUE})?"
|
230
260
|
MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>#{MIME_PARAMETER})*\s*)\z/
|
231
261
|
|
@@ -291,7 +321,7 @@ module Mime
|
|
291
321
|
end
|
292
322
|
|
293
323
|
def html?
|
294
|
-
(symbol == :html) ||
|
324
|
+
(symbol == :html) || @string.include?("html")
|
295
325
|
end
|
296
326
|
|
297
327
|
def all?; false; end
|
@@ -303,7 +333,7 @@ module Mime
|
|
303
333
|
def to_ary; end
|
304
334
|
def to_a; end
|
305
335
|
|
306
|
-
def method_missing(method,
|
336
|
+
def method_missing(method, ...)
|
307
337
|
if method.end_with?("?")
|
308
338
|
method[0..-2].downcase.to_sym == to_sym
|
309
339
|
else
|
@@ -327,9 +357,9 @@ module Mime
|
|
327
357
|
def html?; true; end
|
328
358
|
end
|
329
359
|
|
330
|
-
# ALL isn't a real MIME type, so we don't register it for lookup with the
|
331
|
-
#
|
332
|
-
#
|
360
|
+
# ALL isn't a real MIME type, so we don't register it for lookup with the other
|
361
|
+
# concrete types. It's a wildcard match that we use for `respond_to` negotiation
|
362
|
+
# internals.
|
333
363
|
ALL = AllType.instance
|
334
364
|
|
335
365
|
class NullType
|
@@ -350,7 +380,7 @@ module Mime
|
|
350
380
|
method.end_with?("?")
|
351
381
|
end
|
352
382
|
|
353
|
-
def method_missing(method,
|
383
|
+
def method_missing(method, ...)
|
354
384
|
false if method.end_with?("?")
|
355
385
|
end
|
356
386
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
# Build list of Mime types for HTTP responses
|
4
4
|
# https://www.iana.org/assignments/media-types/
|
5
5
|
|
6
|
+
# :markup: markdown
|
7
|
+
|
6
8
|
Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )
|
7
9
|
Mime::Type.register "text/plain", :text, [], %w(txt)
|
8
10
|
Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript )
|
@@ -18,6 +20,7 @@ Mime::Type.register "image/gif", :gif, [], %w(gif)
|
|
18
20
|
Mime::Type.register "image/bmp", :bmp, [], %w(bmp)
|
19
21
|
Mime::Type.register "image/tiff", :tiff, [], %w(tif tiff)
|
20
22
|
Mime::Type.register "image/svg+xml", :svg
|
23
|
+
Mime::Type.register "image/webp", :webp, [], %w(webp)
|
21
24
|
|
22
25
|
Mime::Type.register "video/mpeg", :mpeg, [], %w(mpg mpeg mpe)
|
23
26
|
|
@@ -43,7 +46,8 @@ Mime::Type.register "application/x-www-form-urlencoded", :url_encoded_form
|
|
43
46
|
|
44
47
|
# https://www.ietf.org/rfc/rfc4627.txt
|
45
48
|
# http://www.json.org/JSONRequest.html
|
46
|
-
|
49
|
+
# https://www.ietf.org/rfc/rfc7807.txt
|
50
|
+
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest application/problem+json )
|
47
51
|
|
48
52
|
Mime::Type.register "application/pdf", :pdf, [], %w(pdf)
|
49
53
|
Mime::Type.register "application/zip", :zip, [], %w(zip)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module Http
|
5
7
|
module Parameters
|
@@ -14,8 +16,8 @@ module ActionDispatch
|
|
14
16
|
}
|
15
17
|
}
|
16
18
|
|
17
|
-
# Raised when raw data from the request cannot be parsed by the parser
|
18
|
-
#
|
19
|
+
# Raised when raw data from the request cannot be parsed by the parser defined
|
20
|
+
# for request's content MIME type.
|
19
21
|
class ParseError < StandardError
|
20
22
|
def initialize(message = $!.message)
|
21
23
|
super(message)
|
@@ -34,8 +36,8 @@ module ActionDispatch
|
|
34
36
|
module ClassMethods
|
35
37
|
# Configure the parameter parser for a given MIME type.
|
36
38
|
#
|
37
|
-
# It accepts a hash where the key is the symbol of the MIME type
|
38
|
-
#
|
39
|
+
# It accepts a hash where the key is the symbol of the MIME type and the value
|
40
|
+
# is a proc.
|
39
41
|
#
|
40
42
|
# original_parsers = ActionDispatch::Request.parameter_parsers
|
41
43
|
# xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} }
|
@@ -46,7 +48,7 @@ module ActionDispatch
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
# Returns both GET and POST
|
51
|
+
# Returns both GET and POST parameters in a single hash.
|
50
52
|
def parameters
|
51
53
|
params = get_header("action_dispatch.request.parameters")
|
52
54
|
return params if params
|
@@ -66,8 +68,8 @@ module ActionDispatch
|
|
66
68
|
delete_header("action_dispatch.request.parameters")
|
67
69
|
|
68
70
|
parameters = Request::Utils.set_binary_encoding(self, parameters, parameters[:controller], parameters[:action])
|
69
|
-
# If any of the path parameters has an invalid encoding then
|
70
|
-
#
|
71
|
+
# If any of the path parameters has an invalid encoding then raise since it's
|
72
|
+
# likely to trigger errors further on.
|
71
73
|
Request::Utils.check_param_encoding(parameters)
|
72
74
|
|
73
75
|
set_header PARAMETERS_KEY, parameters
|
@@ -75,10 +77,10 @@ module ActionDispatch
|
|
75
77
|
raise ActionController::BadRequest.new("Invalid path parameters: #{e.message}")
|
76
78
|
end
|
77
79
|
|
78
|
-
# Returns a hash with the
|
79
|
-
# Returned hash keys are
|
80
|
+
# Returns a hash with the parameters used to form the path of the request.
|
81
|
+
# Returned hash keys are symbols:
|
80
82
|
#
|
81
|
-
#
|
83
|
+
# { action: "my_action", controller: "my_controller" }
|
82
84
|
def path_parameters
|
83
85
|
get_header(PARAMETERS_KEY) || set_header(PARAMETERS_KEY, {})
|
84
86
|
end
|
@@ -1,50 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/object/deep_dup"
|
4
6
|
|
5
7
|
module ActionDispatch # :nodoc:
|
8
|
+
# # Action Dispatch PermissionsPolicy
|
9
|
+
#
|
6
10
|
# Configures the HTTP
|
7
|
-
#
|
8
|
-
# response header to specify which browser features the current
|
9
|
-
# its iframes can use.
|
11
|
+
# [Feature-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy)
|
12
|
+
# response header to specify which browser features the current
|
13
|
+
# document and its iframes can use.
|
10
14
|
#
|
11
15
|
# Example global policy:
|
12
16
|
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
17
|
+
# Rails.application.config.permissions_policy do |policy|
|
18
|
+
# policy.camera :none
|
19
|
+
# policy.gyroscope :none
|
20
|
+
# policy.microphone :none
|
21
|
+
# policy.usb :none
|
22
|
+
# policy.fullscreen :self
|
23
|
+
# policy.payment :self, "https://secure.example.com"
|
24
|
+
# end
|
21
25
|
#
|
26
|
+
# The Feature-Policy header has been renamed to Permissions-Policy. The
|
27
|
+
# Permissions-Policy requires a different implementation and isn't yet supported
|
28
|
+
# by all browsers. To avoid having to rename this middleware in the future we
|
29
|
+
# use the new name for the middleware but keep the old header name and
|
30
|
+
# implementation for now.
|
22
31
|
class PermissionsPolicy
|
23
32
|
class Middleware
|
24
|
-
CONTENT_TYPE = "Content-Type"
|
25
|
-
# The Feature-Policy header has been renamed to Permissions-Policy.
|
26
|
-
# The Permissions-Policy requires a different implementation and isn't
|
27
|
-
# yet supported by all browsers. To avoid having to rename this
|
28
|
-
# middleware in the future we use the new name for the middleware but
|
29
|
-
# keep the old header name and implementation for now.
|
30
|
-
POLICY = "Feature-Policy"
|
31
|
-
|
32
33
|
def initialize(app)
|
33
34
|
@app = app
|
34
35
|
end
|
35
36
|
|
36
37
|
def call(env)
|
37
|
-
request = ActionDispatch::Request.new(env)
|
38
38
|
_, headers, _ = response = @app.call(env)
|
39
39
|
|
40
40
|
return response if policy_present?(headers)
|
41
41
|
|
42
|
+
request = ActionDispatch::Request.new(env)
|
43
|
+
|
42
44
|
if policy = request.permissions_policy
|
43
|
-
headers[
|
45
|
+
headers[ActionDispatch::Constants::FEATURE_POLICY] = policy.build(request.controller_instance)
|
44
46
|
end
|
45
47
|
|
46
48
|
if policy_empty?(policy)
|
47
|
-
headers.delete(
|
49
|
+
headers.delete(ActionDispatch::Constants::FEATURE_POLICY)
|
48
50
|
end
|
49
51
|
|
50
52
|
response
|
@@ -52,7 +54,7 @@ module ActionDispatch # :nodoc:
|
|
52
54
|
|
53
55
|
private
|
54
56
|
def policy_present?(headers)
|
55
|
-
headers[
|
57
|
+
headers[ActionDispatch::Constants::FEATURE_POLICY]
|
56
58
|
end
|
57
59
|
|
58
60
|
def policy_empty?(policy)
|
@@ -78,7 +80,7 @@ module ActionDispatch # :nodoc:
|
|
78
80
|
}.freeze
|
79
81
|
|
80
82
|
# List of available permissions can be found at
|
81
|
-
# https://github.com/w3c/webappsec-permissions-policy/blob/
|
83
|
+
# https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md#policy-controlled-features
|
82
84
|
DIRECTIVES = {
|
83
85
|
accelerometer: "accelerometer",
|
84
86
|
ambient_light_sensor: "ambient-light-sensor",
|
@@ -88,15 +90,18 @@ module ActionDispatch # :nodoc:
|
|
88
90
|
fullscreen: "fullscreen",
|
89
91
|
geolocation: "geolocation",
|
90
92
|
gyroscope: "gyroscope",
|
93
|
+
hid: "hid",
|
94
|
+
idle_detection: "idle-detection",
|
91
95
|
magnetometer: "magnetometer",
|
92
96
|
microphone: "microphone",
|
93
97
|
midi: "midi",
|
94
98
|
payment: "payment",
|
95
99
|
picture_in_picture: "picture-in-picture",
|
96
|
-
|
100
|
+
screen_wake_lock: "screen-wake-lock",
|
101
|
+
serial: "serial",
|
102
|
+
sync_xhr: "sync-xhr",
|
97
103
|
usb: "usb",
|
98
|
-
|
99
|
-
vr: "vr",
|
104
|
+
web_share: "web-share",
|
100
105
|
}.freeze
|
101
106
|
|
102
107
|
private_constant :MAPPINGS, :DIRECTIVES
|