actionpack 7.1.5.1 → 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 +76 -604
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +102 -98
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +66 -64
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +72 -85
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -12
- data/lib/abstract_controller/translation.rb +12 -13
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +75 -72
- data/lib/action_controller/base.rb +198 -126
- data/lib/action_controller/caching.rb +15 -12
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +20 -17
- data/lib/action_controller/log_subscriber.rb +3 -1
- 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 +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +64 -55
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +11 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +12 -10
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +209 -201
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +15 -12
- data/lib/action_controller/metal/live.rb +116 -107
- 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 +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +13 -12
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +108 -82
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -75
- data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
- data/lib/action_controller/metal/rescue.rb +11 -9
- data/lib/action_controller/metal/streaming.rb +138 -136
- data/lib/action_controller/metal/strong_parameters.rb +483 -478
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +86 -60
- data/lib/action_controller/railtie.rb +3 -0
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +42 -36
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +148 -129
- data/lib/action_controller.rb +5 -1
- data/lib/action_dispatch/constants.rb +2 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +27 -26
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +40 -38
- data/lib/action_dispatch/http/filter_parameters.rb +9 -5
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
- data/lib/action_dispatch/http/mime_type.rb +25 -21
- data/lib/action_dispatch/http/mime_types.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +11 -9
- data/lib/action_dispatch/http/permissions_policy.rb +19 -36
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +70 -71
- data/lib/action_dispatch/http/response.rb +73 -61
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +13 -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 +4 -1
- data/lib/action_dispatch/journey/route.rb +9 -7
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +4 -2
- data/lib/action_dispatch/journey/routes.rb +4 -2
- 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 +2 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +119 -104
- data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +2 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
- data/lib/action_dispatch/middleware/executor.rb +2 -0
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +76 -72
- data/lib/action_dispatch/middleware/request_id.rb +14 -9
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
- data/lib/action_dispatch/middleware/ssl.rb +43 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -3
- data/lib/action_dispatch/request/session.rb +23 -21
- data/lib/action_dispatch/request/utils.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +5 -3
- data/lib/action_dispatch/routing/mapper.rb +622 -623
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +37 -32
- data/lib/action_dispatch/routing/route_set.rb +59 -45
- data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +4 -2
- data/lib/action_dispatch/system_testing/driver.rb +2 -0
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +8 -6
- data/lib/action_dispatch/testing/assertions/response.rb +26 -23
- data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +223 -222
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +12 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +22 -28
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +34 -11
@@ -1,28 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/object/deep_dup"
|
4
6
|
require "active_support/core_ext/array/wrap"
|
5
7
|
|
6
8
|
module ActionDispatch # :nodoc:
|
7
|
-
#
|
9
|
+
# # Action Dispatch Content Security Policy
|
8
10
|
#
|
9
|
-
# Configures the HTTP
|
10
|
-
#
|
11
|
-
#
|
11
|
+
# Configures the HTTP [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
|
12
|
+
# response header to help protect against XSS and
|
13
|
+
# injection attacks.
|
12
14
|
#
|
13
15
|
# Example global policy:
|
14
16
|
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
17
|
+
# Rails.application.config.content_security_policy do |policy|
|
18
|
+
# policy.default_src :self, :https
|
19
|
+
# policy.font_src :self, :https, :data
|
20
|
+
# policy.img_src :self, :https, :data
|
21
|
+
# policy.object_src :none
|
22
|
+
# policy.script_src :self, :https
|
23
|
+
# policy.style_src :self, :https
|
22
24
|
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
25
|
+
# # Specify URI for violation reports
|
26
|
+
# policy.report_uri "/csp-violation-report-endpoint"
|
27
|
+
# end
|
26
28
|
class ContentSecurityPolicy
|
27
29
|
class InvalidDirectiveError < StandardError
|
28
30
|
end
|
@@ -35,8 +37,8 @@ module ActionDispatch # :nodoc:
|
|
35
37
|
def call(env)
|
36
38
|
status, headers, _ = response = @app.call(env)
|
37
39
|
|
38
|
-
# Returning CSP headers with a 304 Not Modified is harmful, since nonces in the
|
39
|
-
# CSP headers might not match nonces in the cached HTML.
|
40
|
+
# Returning CSP headers with a 304 Not Modified is harmful, since nonces in the
|
41
|
+
# new CSP headers might not match nonces in the cached HTML.
|
40
42
|
return response if status == 304
|
41
43
|
|
42
44
|
return response if policy_present?(headers)
|
@@ -193,14 +195,14 @@ module ActionDispatch # :nodoc:
|
|
193
195
|
end
|
194
196
|
end
|
195
197
|
|
196
|
-
# Specify whether to prevent the user agent from loading any assets over
|
197
|
-
#
|
198
|
+
# Specify whether to prevent the user agent from loading any assets over HTTP
|
199
|
+
# when the page uses HTTPS:
|
198
200
|
#
|
199
|
-
#
|
201
|
+
# policy.block_all_mixed_content
|
200
202
|
#
|
201
|
-
# Pass
|
203
|
+
# Pass `false` to allow it again:
|
202
204
|
#
|
203
|
-
#
|
205
|
+
# policy.block_all_mixed_content false
|
204
206
|
#
|
205
207
|
def block_all_mixed_content(enabled = true)
|
206
208
|
if enabled
|
@@ -212,11 +214,11 @@ module ActionDispatch # :nodoc:
|
|
212
214
|
|
213
215
|
# Restricts the set of plugins that can be embedded:
|
214
216
|
#
|
215
|
-
#
|
217
|
+
# policy.plugin_types "application/x-shockwave-flash"
|
216
218
|
#
|
217
219
|
# Leave empty to allow all plugins:
|
218
220
|
#
|
219
|
-
#
|
221
|
+
# policy.plugin_types
|
220
222
|
#
|
221
223
|
def plugin_types(*types)
|
222
224
|
if types.first
|
@@ -226,23 +228,23 @@ module ActionDispatch # :nodoc:
|
|
226
228
|
end
|
227
229
|
end
|
228
230
|
|
229
|
-
# Enable the
|
230
|
-
# directive. Violation reports will be sent to the
|
231
|
+
# Enable the [report-uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri)
|
232
|
+
# directive. Violation reports will be sent to the
|
233
|
+
# specified URI:
|
231
234
|
#
|
232
|
-
#
|
235
|
+
# policy.report_uri "/csp-violation-report-endpoint"
|
233
236
|
#
|
234
237
|
def report_uri(uri)
|
235
238
|
@directives["report-uri"] = [uri]
|
236
239
|
end
|
237
240
|
|
238
|
-
# Specify asset types for which
|
239
|
-
# is required:
|
241
|
+
# Specify asset types for which [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) is required:
|
240
242
|
#
|
241
|
-
#
|
243
|
+
# policy.require_sri_for :script, :style
|
242
244
|
#
|
243
245
|
# Leave empty to not require Subresource Integrity:
|
244
246
|
#
|
245
|
-
#
|
247
|
+
# policy.require_sri_for
|
246
248
|
#
|
247
249
|
def require_sri_for(*types)
|
248
250
|
if types.first
|
@@ -252,18 +254,18 @@ module ActionDispatch # :nodoc:
|
|
252
254
|
end
|
253
255
|
end
|
254
256
|
|
255
|
-
# Specify whether a
|
257
|
+
# Specify whether a [sandbox](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox)
|
256
258
|
# should be enabled for the requested resource:
|
257
259
|
#
|
258
|
-
#
|
260
|
+
# policy.sandbox
|
259
261
|
#
|
260
262
|
# Values can be passed as arguments:
|
261
263
|
#
|
262
|
-
#
|
264
|
+
# policy.sandbox "allow-scripts", "allow-modals"
|
263
265
|
#
|
264
|
-
# Pass
|
266
|
+
# Pass `false` to disable the sandbox:
|
265
267
|
#
|
266
|
-
#
|
268
|
+
# policy.sandbox false
|
267
269
|
#
|
268
270
|
def sandbox(*values)
|
269
271
|
if values.empty?
|
@@ -277,11 +279,11 @@ module ActionDispatch # :nodoc:
|
|
277
279
|
|
278
280
|
# Specify whether user agents should treat any assets over HTTP as HTTPS:
|
279
281
|
#
|
280
|
-
#
|
282
|
+
# policy.upgrade_insecure_requests
|
281
283
|
#
|
282
|
-
# Pass
|
284
|
+
# Pass `false` to disable it:
|
283
285
|
#
|
284
|
-
#
|
286
|
+
# policy.upgrade_insecure_requests false
|
285
287
|
#
|
286
288
|
def upgrade_insecure_requests(enabled = true)
|
287
289
|
if enabled
|
@@ -1,18 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/parameter_filter"
|
4
6
|
|
5
7
|
module ActionDispatch
|
6
8
|
module Http
|
7
|
-
#
|
9
|
+
# # Action Dispatch HTTP Filter Parameters
|
8
10
|
#
|
9
11
|
# Allows you to specify sensitive query string and POST parameters to filter
|
10
12
|
# from the request log.
|
11
13
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
+
# # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
|
15
|
+
# env["action_dispatch.parameter_filter"] = [:foo, "bar"]
|
14
16
|
#
|
15
|
-
# For more information about filter behavior, see
|
17
|
+
# For more information about filter behavior, see
|
18
|
+
# ActiveSupport::ParameterFilter.
|
16
19
|
module FilterParameters
|
17
20
|
ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
|
18
21
|
NULL_PARAM_FILTER = ActiveSupport::ParameterFilter.new # :nodoc:
|
@@ -43,7 +46,8 @@ module ActionDispatch
|
|
43
46
|
@filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}"
|
44
47
|
end
|
45
48
|
|
46
|
-
# Returns the
|
49
|
+
# Returns the `ActiveSupport::ParameterFilter` object used to filter in this
|
50
|
+
# request.
|
47
51
|
def parameter_filter
|
48
52
|
@parameter_filter ||= if has_header?("action_dispatch.parameter_filter")
|
49
53
|
parameter_filter_for get_header("action_dispatch.parameter_filter")
|
@@ -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 FilterRedirect
|
@@ -9,7 +11,7 @@ module ActionDispatch
|
|
9
11
|
if location_filter_match?
|
10
12
|
FILTERED
|
11
13
|
else
|
12
|
-
|
14
|
+
parameter_filtered_location
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
@@ -31,6 +33,25 @@ module ActionDispatch
|
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
36
|
+
|
37
|
+
def parameter_filtered_location
|
38
|
+
uri = URI.parse(location)
|
39
|
+
unless uri.query.nil? || uri.query.empty?
|
40
|
+
parts = uri.query.split(/([&;])/)
|
41
|
+
filtered_parts = parts.map do |part|
|
42
|
+
if part.include?("=")
|
43
|
+
key, value = part.split("=", 2)
|
44
|
+
request.parameter_filter.filter(key => value).first.join("=")
|
45
|
+
else
|
46
|
+
part
|
47
|
+
end
|
48
|
+
end
|
49
|
+
uri.query = filtered_parts.join("")
|
50
|
+
end
|
51
|
+
uri.to_s
|
52
|
+
rescue URI::Error
|
53
|
+
FILTERED
|
54
|
+
end
|
34
55
|
end
|
35
56
|
end
|
36
57
|
end
|
@@ -1,28 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module Http
|
5
|
-
#
|
7
|
+
# # Action Dispatch HTTP Headers
|
6
8
|
#
|
7
9
|
# Provides access to the request's HTTP headers from the environment.
|
8
10
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# env = { "CONTENT_TYPE" => "text/plain", "HTTP_USER_AGENT" => "curl/7.43.0" }
|
12
|
+
# headers = ActionDispatch::Http::Headers.from_hash(env)
|
13
|
+
# headers["Content-Type"] # => "text/plain"
|
14
|
+
# headers["User-Agent"] # => "curl/7.43.0"
|
13
15
|
#
|
14
16
|
# Also note that when headers are mapped to CGI-like variables by the Rack
|
15
17
|
# server, both dashes and underscores are converted to underscores. This
|
16
18
|
# ambiguity cannot be resolved at this stage anymore. Both underscores and
|
17
19
|
# dashes have to be interpreted as if they were originally sent as dashes.
|
18
20
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# # GET / HTTP/1.1
|
22
|
+
# # ...
|
23
|
+
# # User-Agent: curl/7.43.0
|
24
|
+
# # X_Custom_Header: token
|
23
25
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
+
# headers["X_Custom_Header"] # => nil
|
27
|
+
# headers["X-Custom-Header"] # => "token"
|
26
28
|
class Headers
|
27
29
|
CGI_VARIABLES = Set.new(%W[
|
28
30
|
AUTH_TYPE
|
@@ -67,7 +69,7 @@ module ActionDispatch
|
|
67
69
|
@req.set_header env_name(key), value
|
68
70
|
end
|
69
71
|
|
70
|
-
# Add a value to a multivalued header like
|
72
|
+
# Add a value to a multivalued header like `Vary` or `Accept-Encoding`.
|
71
73
|
def add(key, value)
|
72
74
|
@req.add_header env_name(key), value
|
73
75
|
end
|
@@ -81,11 +83,10 @@ module ActionDispatch
|
|
81
83
|
|
82
84
|
# Returns the value for the given key mapped to @env.
|
83
85
|
#
|
84
|
-
# If the key is not found and an optional code block is not provided,
|
85
|
-
#
|
86
|
+
# If the key is not found and an optional code block is not provided, raises a
|
87
|
+
# `KeyError` exception.
|
86
88
|
#
|
87
|
-
# If the code block is provided, then it will be run and
|
88
|
-
# its result returned.
|
89
|
+
# If the code block is provided, then it will be run and its result returned.
|
89
90
|
def fetch(key, default = DEFAULT)
|
90
91
|
@req.fetch_header(env_name(key)) do
|
91
92
|
return default unless default == DEFAULT
|
@@ -99,16 +100,15 @@ module ActionDispatch
|
|
99
100
|
end
|
100
101
|
|
101
102
|
# Returns a new Http::Headers instance containing the contents of
|
102
|
-
#
|
103
|
+
# `headers_or_env` and the original instance.
|
103
104
|
def merge(headers_or_env)
|
104
105
|
headers = @req.dup.headers
|
105
106
|
headers.merge!(headers_or_env)
|
106
107
|
headers
|
107
108
|
end
|
108
109
|
|
109
|
-
# Adds the contents of
|
110
|
-
#
|
111
|
-
# <tt>headers_or_env</tt>.
|
110
|
+
# Adds the contents of `headers_or_env` to original instance entries; duplicate
|
111
|
+
# keys are overwritten with the values from `headers_or_env`.
|
112
112
|
def merge!(headers_or_env)
|
113
113
|
headers_or_env.each do |key, value|
|
114
114
|
@req.set_header env_name(key), value
|
@@ -118,8 +118,8 @@ module ActionDispatch
|
|
118
118
|
def env; @req.env.dup; end
|
119
119
|
|
120
120
|
private
|
121
|
-
# Converts an HTTP header name to an environment variable name if it is
|
122
|
-
#
|
121
|
+
# Converts an HTTP header name to an environment variable name if it is not
|
122
|
+
# contained within the headers hash.
|
123
123
|
def env_name(key)
|
124
124
|
key = key.to_s
|
125
125
|
if HTTP_HEADER.match?(key)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/core_ext/module/attribute_accessors"
|
4
6
|
|
5
7
|
module ActionDispatch
|
@@ -16,23 +18,9 @@ module ActionDispatch
|
|
16
18
|
|
17
19
|
included do
|
18
20
|
mattr_accessor :ignore_accept_header, default: false
|
19
|
-
|
20
|
-
def return_only_media_type_on_content_type=(value)
|
21
|
-
ActionDispatch.deprecator.warn(
|
22
|
-
"`config.action_dispatch.return_only_request_media_type_on_content_type` is deprecated and will" \
|
23
|
-
" be removed in Rails 7.2."
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
def return_only_media_type_on_content_type
|
28
|
-
ActionDispatch.deprecator.warn(
|
29
|
-
"`config.action_dispatch.return_only_request_media_type_on_content_type` is deprecated and will" \
|
30
|
-
" be removed in Rails 7.2."
|
31
|
-
)
|
32
|
-
end
|
33
21
|
end
|
34
22
|
|
35
|
-
# The MIME type of the HTTP request, such as Mime
|
23
|
+
# The MIME type of the HTTP request, such as [Mime](:xml).
|
36
24
|
def content_mime_type
|
37
25
|
fetch_header("action_dispatch.request.content_type") do |k|
|
38
26
|
v = if get_header("CONTENT_TYPE") =~ /^([^,;]*)/
|
@@ -66,11 +54,11 @@ module ActionDispatch
|
|
66
54
|
end
|
67
55
|
end
|
68
56
|
|
69
|
-
# Returns the MIME type for the
|
57
|
+
# Returns the MIME type for the format used in the request.
|
70
58
|
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
59
|
+
# GET /posts/5.xml | request.format => Mime[:xml]
|
60
|
+
# GET /posts/5.xhtml | request.format => Mime[:html]
|
61
|
+
# GET /posts/5 | request.format => Mime[:html] or Mime[:js], or request.accepts.first
|
74
62
|
#
|
75
63
|
def format(_view_path = nil)
|
76
64
|
formats.first || Mime::NullType.instance
|
@@ -98,7 +86,7 @@ module ActionDispatch
|
|
98
86
|
end
|
99
87
|
end
|
100
88
|
|
101
|
-
# Sets the
|
89
|
+
# Sets the variant for template.
|
102
90
|
def variant=(variant)
|
103
91
|
variant = Array(variant)
|
104
92
|
|
@@ -113,36 +101,37 @@ module ActionDispatch
|
|
113
101
|
@variant ||= ActiveSupport::ArrayInquirer.new
|
114
102
|
end
|
115
103
|
|
116
|
-
# Sets the
|
104
|
+
# Sets the format by string extension, which can be used to force custom formats
|
117
105
|
# that are not controlled by the extension.
|
118
106
|
#
|
119
|
-
#
|
120
|
-
#
|
107
|
+
# class ApplicationController < ActionController::Base
|
108
|
+
# before_action :adjust_format_for_iphone
|
121
109
|
#
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
110
|
+
# private
|
111
|
+
# def adjust_format_for_iphone
|
112
|
+
# request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
|
113
|
+
# end
|
114
|
+
# end
|
127
115
|
def format=(extension)
|
128
116
|
parameters[:format] = extension.to_s
|
129
117
|
set_header "action_dispatch.request.formats", [Mime::Type.lookup_by_extension(parameters[:format])]
|
130
118
|
end
|
131
119
|
|
132
|
-
# Sets the
|
133
|
-
# to set multiple, ordered formats, which is useful when you want to have a
|
120
|
+
# Sets the formats by string extensions. This differs from #format= by allowing
|
121
|
+
# you to set multiple, ordered formats, which is useful when you want to have a
|
122
|
+
# fallback.
|
134
123
|
#
|
135
|
-
# In this example, the
|
136
|
-
# to the
|
124
|
+
# In this example, the `:iphone` format will be used if it's available,
|
125
|
+
# otherwise it'll fall back to the `:html` format.
|
137
126
|
#
|
138
|
-
#
|
139
|
-
#
|
127
|
+
# class ApplicationController < ActionController::Base
|
128
|
+
# before_action :adjust_format_for_iphone_with_html_fallback
|
140
129
|
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
#
|
130
|
+
# private
|
131
|
+
# def adjust_format_for_iphone_with_html_fallback
|
132
|
+
# request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
|
133
|
+
# end
|
134
|
+
# end
|
146
135
|
def formats=(extensions)
|
147
136
|
parameters[:format] = extensions.first.to_s
|
148
137
|
set_header "action_dispatch.request.formats", extensions.collect { |extension|
|
@@ -168,8 +157,8 @@ module ActionDispatch
|
|
168
157
|
end
|
169
158
|
|
170
159
|
private
|
171
|
-
# We use normal content negotiation unless you include
|
172
|
-
#
|
160
|
+
# We use normal content negotiation unless you include **/** in your list, in
|
161
|
+
# which case we assume you're a browser and send HTML.
|
173
162
|
BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
|
174
163
|
|
175
164
|
def params_readable?
|
@@ -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
|
@@ -65,19 +67,20 @@ module Mime
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
|
-
# 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:
|
69
72
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
+
# class PostsController < ActionController::Base
|
74
|
+
# def show
|
75
|
+
# @post = Post.find(params[:id])
|
73
76
|
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
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
|
78
82
|
# end
|
79
83
|
# end
|
80
|
-
# end
|
81
84
|
class Type
|
82
85
|
attr_reader :symbol
|
83
86
|
|
@@ -173,8 +176,9 @@ module Mime
|
|
173
176
|
EXTENSION_LOOKUP[extension.to_s]
|
174
177
|
end
|
175
178
|
|
176
|
-
# Registers an alias that's not used on MIME type lookup, but can be referenced
|
177
|
-
# 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.
|
178
182
|
def register_alias(string, symbol, extension_synonyms = [])
|
179
183
|
register(string, symbol, [], extension_synonyms, true)
|
180
184
|
end
|
@@ -224,11 +228,11 @@ module Mime
|
|
224
228
|
parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
|
225
229
|
end
|
226
230
|
|
227
|
-
# For an input of
|
228
|
-
# 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]]`.
|
229
233
|
#
|
230
|
-
# For an input of
|
231
|
-
# 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]]`.
|
232
236
|
def parse_data_with_trailing_star(type)
|
233
237
|
Mime::SET.select { |m| m.match?(type) }
|
234
238
|
end
|
@@ -237,7 +241,7 @@ module Mime
|
|
237
241
|
#
|
238
242
|
# To unregister a MIME type:
|
239
243
|
#
|
240
|
-
#
|
244
|
+
# Mime::Type.unregister(:mobile)
|
241
245
|
def unregister(symbol)
|
242
246
|
symbol = symbol.downcase
|
243
247
|
if mime = Mime[symbol]
|
@@ -329,7 +333,7 @@ module Mime
|
|
329
333
|
def to_ary; end
|
330
334
|
def to_a; end
|
331
335
|
|
332
|
-
def method_missing(method,
|
336
|
+
def method_missing(method, ...)
|
333
337
|
if method.end_with?("?")
|
334
338
|
method[0..-2].downcase.to_sym == to_sym
|
335
339
|
else
|
@@ -353,9 +357,9 @@ module Mime
|
|
353
357
|
def html?; true; end
|
354
358
|
end
|
355
359
|
|
356
|
-
# ALL isn't a real MIME type, so we don't register it for lookup with the
|
357
|
-
#
|
358
|
-
#
|
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.
|
359
363
|
ALL = AllType.instance
|
360
364
|
|
361
365
|
class NullType
|
@@ -376,7 +380,7 @@ module Mime
|
|
376
380
|
method.end_with?("?")
|
377
381
|
end
|
378
382
|
|
379
|
-
def method_missing(method,
|
383
|
+
def method_missing(method, ...)
|
380
384
|
false if method.end_with?("?")
|
381
385
|
end
|
382
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 )
|
@@ -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
|
80
|
+
# Returns a hash with the parameters used to form the path of the request.
|
79
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
|