actionpack 7.1.3 → 7.2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -501
- 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 +70 -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 +15 -7
- 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 +74 -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 +188 -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 +210 -205
- 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 +113 -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 +525 -480
- 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 +146 -126
- data/lib/action_controller.rb +10 -3
- 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 +44 -38
- data/lib/action_dispatch/http/filter_parameters.rb +18 -9
- 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 +31 -24
- 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 +20 -44
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +94 -75
- 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 +8 -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 +77 -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 +31 -21
- 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/rescues/missing_exact_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -4
- 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 +671 -636
- 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 +10 -3
- data/lib/action_dispatch/system_testing/driver.rb +3 -1
- 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 +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +39 -16
@@ -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
|
@@ -1,31 +1,33 @@
|
|
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:
|
6
|
-
#
|
8
|
+
# # Action Dispatch PermissionsPolicy
|
7
9
|
#
|
8
10
|
# Configures the HTTP
|
9
|
-
#
|
10
|
-
# response header to specify which browser features the current
|
11
|
-
# 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.
|
12
14
|
#
|
13
15
|
# Example global policy:
|
14
16
|
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
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
|
23
25
|
#
|
24
|
-
# The Feature-Policy header has been renamed to Permissions-Policy.
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
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.
|
29
31
|
class PermissionsPolicy
|
30
32
|
class Middleware
|
31
33
|
def initialize(app)
|
@@ -35,7 +37,6 @@ module ActionDispatch # :nodoc:
|
|
35
37
|
def call(env)
|
36
38
|
_, headers, _ = response = @app.call(env)
|
37
39
|
|
38
|
-
return response unless html_response?(headers)
|
39
40
|
return response if policy_present?(headers)
|
40
41
|
|
41
42
|
request = ActionDispatch::Request.new(env)
|
@@ -52,12 +53,6 @@ module ActionDispatch # :nodoc:
|
|
52
53
|
end
|
53
54
|
|
54
55
|
private
|
55
|
-
def html_response?(headers)
|
56
|
-
if content_type = headers[Rack::CONTENT_TYPE]
|
57
|
-
content_type.include?("html")
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
56
|
def policy_present?(headers)
|
62
57
|
headers[ActionDispatch::Constants::FEATURE_POLICY]
|
63
58
|
end
|
@@ -96,7 +91,7 @@ module ActionDispatch # :nodoc:
|
|
96
91
|
geolocation: "geolocation",
|
97
92
|
gyroscope: "gyroscope",
|
98
93
|
hid: "hid",
|
99
|
-
idle_detection: "
|
94
|
+
idle_detection: "idle-detection",
|
100
95
|
magnetometer: "magnetometer",
|
101
96
|
microphone: "microphone",
|
102
97
|
midi: "midi",
|
@@ -132,25 +127,6 @@ module ActionDispatch # :nodoc:
|
|
132
127
|
end
|
133
128
|
end
|
134
129
|
|
135
|
-
%w[speaker vibrate vr].each do |directive|
|
136
|
-
define_method(directive) do |*sources|
|
137
|
-
ActionDispatch.deprecator.warn(<<~MSG)
|
138
|
-
The `#{directive}` permissions policy directive is deprecated
|
139
|
-
and will be removed in Rails 7.2.
|
140
|
-
|
141
|
-
There is no browser support for this directive, and no plan
|
142
|
-
for browser support in the future. You can just remove this
|
143
|
-
directive from your application.
|
144
|
-
MSG
|
145
|
-
|
146
|
-
if sources.first
|
147
|
-
@directives[directive] = apply_mappings(sources)
|
148
|
-
else
|
149
|
-
@directives.delete(directive)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
130
|
def build(context = nil)
|
155
131
|
build_directives(context).compact.join("; ")
|
156
132
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "stringio"
|
4
6
|
|
5
7
|
require "active_support/inflector"
|
@@ -102,26 +104,26 @@ module ActionDispatch
|
|
102
104
|
|
103
105
|
# Returns true if the request has a header matching the given key parameter.
|
104
106
|
#
|
105
|
-
#
|
107
|
+
# request.key? :ip_spoofing_check # => true
|
106
108
|
def key?(key)
|
107
109
|
has_header? key
|
108
110
|
end
|
109
111
|
|
110
|
-
# HTTP methods from
|
112
|
+
# HTTP methods from [RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1](https://www.ietf.org/rfc/rfc2616.txt)
|
111
113
|
RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
|
112
|
-
# HTTP methods from
|
114
|
+
# HTTP methods from [RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV](https://www.ietf.org/rfc/rfc2518.txt)
|
113
115
|
RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
|
114
|
-
# HTTP methods from
|
116
|
+
# HTTP methods from [RFC 3253: Versioning Extensions to WebDAV](https://www.ietf.org/rfc/rfc3253.txt)
|
115
117
|
RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
|
116
|
-
# HTTP methods from
|
118
|
+
# HTTP methods from [RFC 3648: WebDAV Ordered Collections Protocol](https://www.ietf.org/rfc/rfc3648.txt)
|
117
119
|
RFC3648 = %w(ORDERPATCH)
|
118
|
-
# HTTP methods from
|
120
|
+
# HTTP methods from [RFC 3744: WebDAV Access Control Protocol](https://www.ietf.org/rfc/rfc3744.txt)
|
119
121
|
RFC3744 = %w(ACL)
|
120
|
-
# HTTP methods from
|
122
|
+
# HTTP methods from [RFC 5323: WebDAV SEARCH](https://www.ietf.org/rfc/rfc5323.txt)
|
121
123
|
RFC5323 = %w(SEARCH)
|
122
|
-
# HTTP methods from
|
124
|
+
# HTTP methods from [RFC 4791: Calendaring Extensions to WebDAV](https://www.ietf.org/rfc/rfc4791.txt)
|
123
125
|
RFC4791 = %w(MKCALENDAR)
|
124
|
-
# HTTP methods from
|
126
|
+
# HTTP methods from [RFC 5789: PATCH Method for HTTP](https://www.ietf.org/rfc/rfc5789.txt)
|
125
127
|
RFC5789 = %w(PATCH)
|
126
128
|
|
127
129
|
HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789
|
@@ -135,20 +137,19 @@ module ActionDispatch
|
|
135
137
|
|
136
138
|
alias raw_request_method request_method # :nodoc:
|
137
139
|
|
138
|
-
# Returns the HTTP
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
# value, not the original.
|
140
|
+
# Returns the HTTP method that the application should see. In the case where the
|
141
|
+
# method was overridden by a middleware (for instance, if a HEAD request was
|
142
|
+
# converted to a GET, or if a _method parameter was used to determine the method
|
143
|
+
# the application should use), this method returns the overridden value, not the
|
144
|
+
# original.
|
144
145
|
def request_method
|
145
146
|
@request_method ||= check_method(super)
|
146
147
|
end
|
147
148
|
|
148
|
-
# Returns the URI pattern of the matched route for the request,
|
149
|
-
#
|
149
|
+
# Returns the URI pattern of the matched route for the request, using the same
|
150
|
+
# format as `bin/rails routes`:
|
150
151
|
#
|
151
|
-
#
|
152
|
+
# request.route_uri_pattern # => "/:controller(/:action(/:id))(.:format)"
|
152
153
|
def route_uri_pattern
|
153
154
|
get_header("action_dispatch.route_uri_pattern")
|
154
155
|
end
|
@@ -196,12 +197,11 @@ module ActionDispatch
|
|
196
197
|
HTTP_METHOD_LOOKUP[request_method]
|
197
198
|
end
|
198
199
|
|
199
|
-
# Returns the original value of the environment's REQUEST_METHOD,
|
200
|
-
#
|
201
|
-
# more information.
|
200
|
+
# Returns the original value of the environment's REQUEST_METHOD, even if it was
|
201
|
+
# overridden by middleware. See #request_method for more information.
|
202
202
|
#
|
203
|
-
# For debugging purposes, when called with arguments this method will
|
204
|
-
#
|
203
|
+
# For debugging purposes, when called with arguments this method will fall back
|
204
|
+
# to Object#method
|
205
205
|
def method(*args)
|
206
206
|
if args.empty?
|
207
207
|
@method ||= check_method(
|
@@ -221,62 +221,61 @@ module ActionDispatch
|
|
221
221
|
|
222
222
|
# Provides access to the request's HTTP headers, for example:
|
223
223
|
#
|
224
|
-
#
|
224
|
+
# request.headers["Content-Type"] # => "text/plain"
|
225
225
|
def headers
|
226
226
|
@headers ||= Http::Headers.new(self)
|
227
227
|
end
|
228
228
|
|
229
|
-
# Early Hints is an HTTP/2 status code that indicates hints to help a client
|
230
|
-
# making preparations for processing the final response.
|
229
|
+
# Early Hints is an HTTP/2 status code that indicates hints to help a client
|
230
|
+
# start making preparations for processing the final response.
|
231
231
|
#
|
232
|
-
# If the env contains
|
232
|
+
# If the env contains `rack.early_hints` then the server accepts HTTP2 push for
|
233
|
+
# link headers.
|
233
234
|
#
|
234
|
-
# The
|
235
|
+
# The `send_early_hints` method accepts a hash of links as follows:
|
235
236
|
#
|
236
|
-
#
|
237
|
+
# send_early_hints("link" => "</style.css>; rel=preload; as=style,</script.js>; rel=preload")
|
237
238
|
#
|
238
|
-
# If you are using
|
239
|
-
#
|
239
|
+
# If you are using `javascript_include_tag` or `stylesheet_link_tag` the Early
|
240
|
+
# Hints headers are included by default if supported.
|
240
241
|
def send_early_hints(links)
|
241
|
-
|
242
|
-
|
243
|
-
env["rack.early_hints"].call(links)
|
242
|
+
env["rack.early_hints"]&.call(links)
|
244
243
|
end
|
245
244
|
|
246
|
-
# Returns a
|
245
|
+
# Returns a `String` with the last requested path including their params.
|
247
246
|
#
|
248
|
-
#
|
249
|
-
#
|
247
|
+
# # get '/foo'
|
248
|
+
# request.original_fullpath # => '/foo'
|
250
249
|
#
|
251
|
-
#
|
252
|
-
#
|
250
|
+
# # get '/foo?bar'
|
251
|
+
# request.original_fullpath # => '/foo?bar'
|
253
252
|
def original_fullpath
|
254
253
|
@original_fullpath ||= (get_header("ORIGINAL_FULLPATH") || fullpath)
|
255
254
|
end
|
256
255
|
|
257
|
-
# Returns the
|
256
|
+
# Returns the `String` full path including params of the last URL requested.
|
258
257
|
#
|
259
|
-
#
|
260
|
-
#
|
258
|
+
# # get "/articles"
|
259
|
+
# request.fullpath # => "/articles"
|
261
260
|
#
|
262
|
-
#
|
263
|
-
#
|
261
|
+
# # get "/articles?page=2"
|
262
|
+
# request.fullpath # => "/articles?page=2"
|
264
263
|
def fullpath
|
265
264
|
@fullpath ||= super
|
266
265
|
end
|
267
266
|
|
268
|
-
# Returns the original request URL as a
|
267
|
+
# Returns the original request URL as a `String`.
|
269
268
|
#
|
270
|
-
#
|
271
|
-
#
|
269
|
+
# # get "/articles?page=2"
|
270
|
+
# request.original_url # => "http://www.example.com/articles?page=2"
|
272
271
|
def original_url
|
273
272
|
base_url + original_fullpath
|
274
273
|
end
|
275
274
|
|
276
|
-
# The
|
275
|
+
# The `String` MIME type of the request.
|
277
276
|
#
|
278
|
-
#
|
279
|
-
#
|
277
|
+
# # get "/articles"
|
278
|
+
# request.media_type # => "application/x-www-form-urlencoded"
|
280
279
|
def media_type
|
281
280
|
content_mime_type&.to_s
|
282
281
|
end
|
@@ -287,7 +286,7 @@ module ActionDispatch
|
|
287
286
|
super.to_i
|
288
287
|
end
|
289
288
|
|
290
|
-
# Returns true if the
|
289
|
+
# Returns true if the `X-Requested-With` header contains "XMLHttpRequest"
|
291
290
|
# (case-insensitive), which may need to be manually added depending on the
|
292
291
|
# choice of JavaScript libraries and frameworks.
|
293
292
|
def xml_http_request?
|
@@ -295,13 +294,13 @@ module ActionDispatch
|
|
295
294
|
end
|
296
295
|
alias :xhr? :xml_http_request?
|
297
296
|
|
298
|
-
# Returns the IP address of client as a
|
297
|
+
# Returns the IP address of client as a `String`.
|
299
298
|
def ip
|
300
299
|
@ip ||= super
|
301
300
|
end
|
302
301
|
|
303
|
-
# Returns the IP address of client as a
|
304
|
-
#
|
302
|
+
# Returns the IP address of client as a `String`, usually set by the RemoteIp
|
303
|
+
# middleware.
|
305
304
|
def remote_ip
|
306
305
|
@remote_ip ||= (get_header("action_dispatch.remote_ip") || ip).to_s
|
307
306
|
end
|
@@ -313,12 +312,14 @@ module ActionDispatch
|
|
313
312
|
|
314
313
|
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id" # :nodoc:
|
315
314
|
|
316
|
-
# Returns the unique request id, which is based on either the
|
317
|
-
# be generated by a firewall, load balancer, or web server, or
|
318
|
-
# (which sets the
|
315
|
+
# Returns the unique request id, which is based on either the `X-Request-Id`
|
316
|
+
# header that can be generated by a firewall, load balancer, or web server, or
|
317
|
+
# by the RequestId middleware (which sets the `action_dispatch.request_id`
|
318
|
+
# environment variable).
|
319
319
|
#
|
320
|
-
# This unique ID is useful for tracing a request from end-to-end as part of
|
321
|
-
# This relies on the Rack variable set by the
|
320
|
+
# This unique ID is useful for tracing a request from end-to-end as part of
|
321
|
+
# logging or debugging. This relies on the Rack variable set by the
|
322
|
+
# ActionDispatch::RequestId middleware.
|
322
323
|
def request_id
|
323
324
|
get_header ACTION_DISPATCH_REQUEST_ID
|
324
325
|
end
|
@@ -334,12 +335,11 @@ module ActionDispatch
|
|
334
335
|
(get_header("SERVER_SOFTWARE") && /^([a-zA-Z]+)/ =~ get_header("SERVER_SOFTWARE")) ? $1.downcase : nil
|
335
336
|
end
|
336
337
|
|
337
|
-
# Read the request
|
338
|
-
#
|
338
|
+
# Read the request body. This is useful for web services that need to work with
|
339
|
+
# raw requests directly.
|
339
340
|
def raw_post
|
340
341
|
unless has_header? "RAW_POST_DATA"
|
341
342
|
set_header("RAW_POST_DATA", read_body_stream)
|
342
|
-
body_stream.rewind if body_stream.respond_to?(:rewind)
|
343
343
|
end
|
344
344
|
get_header "RAW_POST_DATA"
|
345
345
|
end
|
@@ -355,14 +355,13 @@ module ActionDispatch
|
|
355
355
|
end
|
356
356
|
end
|
357
357
|
|
358
|
-
# Determine whether the request body contains form-data by checking
|
359
|
-
#
|
360
|
-
#
|
361
|
-
#
|
362
|
-
# +FORM_DATA_MEDIA_TYPES+ array.
|
358
|
+
# Determine whether the request body contains form-data by checking the request
|
359
|
+
# `Content-Type` for one of the media-types: `application/x-www-form-urlencoded`
|
360
|
+
# or `multipart/form-data`. The list of form-data media types can be modified
|
361
|
+
# through the `FORM_DATA_MEDIA_TYPES` array.
|
363
362
|
#
|
364
|
-
# A request body is not assumed to contain form-data when no
|
365
|
-
#
|
363
|
+
# A request body is not assumed to contain form-data when no `Content-Type`
|
364
|
+
# header is provided and the request_method is POST.
|
366
365
|
def form_data?
|
367
366
|
FORM_DATA_MEDIA_TYPES.include?(media_type)
|
368
367
|
end
|
@@ -415,8 +414,8 @@ module ActionDispatch
|
|
415
414
|
end
|
416
415
|
alias :request_parameters :POST
|
417
416
|
|
418
|
-
# Returns the authorization header regardless of whether it was specified
|
419
|
-
# proxy alternatives.
|
417
|
+
# Returns the authorization header regardless of whether it was specified
|
418
|
+
# directly or through one of the proxy alternatives.
|
420
419
|
def authorization
|
421
420
|
get_header("HTTP_AUTHORIZATION") ||
|
422
421
|
get_header("X-HTTP_AUTHORIZATION") ||
|
@@ -456,7 +455,7 @@ module ActionDispatch
|
|
456
455
|
private
|
457
456
|
def check_method(name)
|
458
457
|
if name
|
459
|
-
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS
|
458
|
+
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(locale: false)}")
|
460
459
|
end
|
461
460
|
|
462
461
|
name
|
@@ -467,9 +466,29 @@ module ActionDispatch
|
|
467
466
|
end
|
468
467
|
|
469
468
|
def read_body_stream
|
470
|
-
|
471
|
-
|
472
|
-
|
469
|
+
if body_stream
|
470
|
+
reset_stream(body_stream) do
|
471
|
+
if headers.key?("Transfer-Encoding")
|
472
|
+
body_stream.read # Read body stream until EOF if "Transfer-Encoding" is present
|
473
|
+
else
|
474
|
+
body_stream.read(content_length)
|
475
|
+
end
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
def reset_stream(body_stream)
|
481
|
+
if body_stream.respond_to?(:rewind)
|
482
|
+
body_stream.rewind
|
483
|
+
|
484
|
+
content = yield
|
485
|
+
|
486
|
+
body_stream.rewind
|
487
|
+
|
488
|
+
content
|
489
|
+
else
|
490
|
+
yield
|
491
|
+
end
|
473
492
|
end
|
474
493
|
end
|
475
494
|
end
|