actionpack 7.1.5.1 → 7.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -642
- 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 +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 +74 -72
- data/lib/action_controller/base.rb +155 -117
- 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 +119 -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 +214 -203
- 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 +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 +58 -57
- 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 +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 +48 -59
- data/lib/action_dispatch/http/filter_parameters.rb +13 -14
- data/lib/action_dispatch/http/filter_redirect.rb +15 -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 +26 -36
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +75 -95
- data/lib/action_dispatch/http/response.rb +61 -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 +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 +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 +6 -4
- data/lib/action_dispatch/routing/mapper.rb +623 -625
- 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 +60 -46
- 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 -32
- 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 +33 -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,6 +37,7 @@ module ActionDispatch # :nodoc:
|
|
35
37
|
def call(env)
|
36
38
|
_, headers, _ = response = @app.call(env)
|
37
39
|
|
40
|
+
return response unless html_response?(headers)
|
38
41
|
return response if policy_present?(headers)
|
39
42
|
|
40
43
|
request = ActionDispatch::Request.new(env)
|
@@ -51,6 +54,12 @@ module ActionDispatch # :nodoc:
|
|
51
54
|
end
|
52
55
|
|
53
56
|
private
|
57
|
+
def html_response?(headers)
|
58
|
+
if content_type = headers[Rack::CONTENT_TYPE]
|
59
|
+
content_type.include?("html")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
54
63
|
def policy_present?(headers)
|
55
64
|
headers[ActionDispatch::Constants::FEATURE_POLICY]
|
56
65
|
end
|
@@ -125,25 +134,6 @@ module ActionDispatch # :nodoc:
|
|
125
134
|
end
|
126
135
|
end
|
127
136
|
|
128
|
-
%w[speaker vibrate vr].each do |directive|
|
129
|
-
define_method(directive) do |*sources|
|
130
|
-
ActionDispatch.deprecator.warn(<<~MSG)
|
131
|
-
The `#{directive}` permissions policy directive is deprecated
|
132
|
-
and will be removed in Rails 7.2.
|
133
|
-
|
134
|
-
There is no browser support for this directive, and no plan
|
135
|
-
for browser support in the future. You can just remove this
|
136
|
-
directive from your application.
|
137
|
-
MSG
|
138
|
-
|
139
|
-
if sources.first
|
140
|
-
@directives[directive] = apply_mappings(sources)
|
141
|
-
else
|
142
|
-
@directives.delete(directive)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
137
|
def build(context = nil)
|
148
138
|
build_directives(context).compact.join("; ")
|
149
139
|
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,63 +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
|
233
|
-
#
|
232
|
+
# If the env contains `rack.early_hints` then the server accepts HTTP2 push for
|
233
|
+
# Link headers.
|
234
234
|
#
|
235
|
-
# The
|
235
|
+
# The `send_early_hints` method accepts a hash of links as follows:
|
236
236
|
#
|
237
|
-
#
|
237
|
+
# send_early_hints("Link" => "</style.css>; rel=preload; as=style\n</script.js>; rel=preload")
|
238
238
|
#
|
239
|
-
# If you are using
|
240
|
-
#
|
239
|
+
# If you are using `javascript_include_tag` or `stylesheet_link_tag` the Early
|
240
|
+
# Hints headers are included by default if supported.
|
241
241
|
def send_early_hints(links)
|
242
|
-
|
243
|
-
|
244
|
-
env["rack.early_hints"].call(links)
|
242
|
+
env["rack.early_hints"]&.call(links)
|
245
243
|
end
|
246
244
|
|
247
|
-
# Returns a
|
245
|
+
# Returns a `String` with the last requested path including their params.
|
248
246
|
#
|
249
|
-
#
|
250
|
-
#
|
247
|
+
# # get '/foo'
|
248
|
+
# request.original_fullpath # => '/foo'
|
251
249
|
#
|
252
|
-
#
|
253
|
-
#
|
250
|
+
# # get '/foo?bar'
|
251
|
+
# request.original_fullpath # => '/foo?bar'
|
254
252
|
def original_fullpath
|
255
253
|
@original_fullpath ||= (get_header("ORIGINAL_FULLPATH") || fullpath)
|
256
254
|
end
|
257
255
|
|
258
|
-
# Returns the
|
256
|
+
# Returns the `String` full path including params of the last URL requested.
|
259
257
|
#
|
260
|
-
#
|
261
|
-
#
|
258
|
+
# # get "/articles"
|
259
|
+
# request.fullpath # => "/articles"
|
262
260
|
#
|
263
|
-
#
|
264
|
-
#
|
261
|
+
# # get "/articles?page=2"
|
262
|
+
# request.fullpath # => "/articles?page=2"
|
265
263
|
def fullpath
|
266
264
|
@fullpath ||= super
|
267
265
|
end
|
268
266
|
|
269
|
-
# Returns the original request URL as a
|
267
|
+
# Returns the original request URL as a `String`.
|
270
268
|
#
|
271
|
-
#
|
272
|
-
#
|
269
|
+
# # get "/articles?page=2"
|
270
|
+
# request.original_url # => "http://www.example.com/articles?page=2"
|
273
271
|
def original_url
|
274
272
|
base_url + original_fullpath
|
275
273
|
end
|
276
274
|
|
277
|
-
# The
|
275
|
+
# The `String` MIME type of the request.
|
278
276
|
#
|
279
|
-
#
|
280
|
-
#
|
277
|
+
# # get "/articles"
|
278
|
+
# request.media_type # => "application/x-www-form-urlencoded"
|
281
279
|
def media_type
|
282
280
|
content_mime_type&.to_s
|
283
281
|
end
|
@@ -288,7 +286,7 @@ module ActionDispatch
|
|
288
286
|
super.to_i
|
289
287
|
end
|
290
288
|
|
291
|
-
# Returns true if the
|
289
|
+
# Returns true if the `X-Requested-With` header contains "XMLHttpRequest"
|
292
290
|
# (case-insensitive), which may need to be manually added depending on the
|
293
291
|
# choice of JavaScript libraries and frameworks.
|
294
292
|
def xml_http_request?
|
@@ -296,13 +294,13 @@ module ActionDispatch
|
|
296
294
|
end
|
297
295
|
alias :xhr? :xml_http_request?
|
298
296
|
|
299
|
-
# Returns the IP address of client as a
|
297
|
+
# Returns the IP address of client as a `String`.
|
300
298
|
def ip
|
301
299
|
@ip ||= super
|
302
300
|
end
|
303
301
|
|
304
|
-
# Returns the IP address of client as a
|
305
|
-
#
|
302
|
+
# Returns the IP address of client as a `String`, usually set by the RemoteIp
|
303
|
+
# middleware.
|
306
304
|
def remote_ip
|
307
305
|
@remote_ip ||= (get_header("action_dispatch.remote_ip") || ip).to_s
|
308
306
|
end
|
@@ -314,12 +312,14 @@ module ActionDispatch
|
|
314
312
|
|
315
313
|
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id" # :nodoc:
|
316
314
|
|
317
|
-
# Returns the unique request id, which is based on either the
|
318
|
-
# be generated by a firewall, load balancer, or web server, or
|
319
|
-
# (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).
|
320
319
|
#
|
321
|
-
# This unique ID is useful for tracing a request from end-to-end as part of
|
322
|
-
# 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.
|
323
323
|
def request_id
|
324
324
|
get_header ACTION_DISPATCH_REQUEST_ID
|
325
325
|
end
|
@@ -335,11 +335,12 @@ module ActionDispatch
|
|
335
335
|
(get_header("SERVER_SOFTWARE") && /^([a-zA-Z]+)/ =~ get_header("SERVER_SOFTWARE")) ? $1.downcase : nil
|
336
336
|
end
|
337
337
|
|
338
|
-
# Read the request
|
339
|
-
#
|
338
|
+
# Read the request body. This is useful for web services that need to work with
|
339
|
+
# raw requests directly.
|
340
340
|
def raw_post
|
341
341
|
unless has_header? "RAW_POST_DATA"
|
342
342
|
set_header("RAW_POST_DATA", read_body_stream)
|
343
|
+
body_stream.rewind if body_stream.respond_to?(:rewind)
|
343
344
|
end
|
344
345
|
get_header "RAW_POST_DATA"
|
345
346
|
end
|
@@ -355,14 +356,13 @@ module ActionDispatch
|
|
355
356
|
end
|
356
357
|
end
|
357
358
|
|
358
|
-
# Determine whether the request body contains form-data by checking
|
359
|
-
#
|
360
|
-
#
|
361
|
-
#
|
362
|
-
# +FORM_DATA_MEDIA_TYPES+ array.
|
359
|
+
# Determine whether the request body contains form-data by checking the request
|
360
|
+
# `Content-Type` for one of the media-types: `application/x-www-form-urlencoded`
|
361
|
+
# or `multipart/form-data`. The list of form-data media types can be modified
|
362
|
+
# through the `FORM_DATA_MEDIA_TYPES` array.
|
363
363
|
#
|
364
|
-
# A request body is not assumed to contain form-data when no
|
365
|
-
#
|
364
|
+
# A request body is not assumed to contain form-data when no `Content-Type`
|
365
|
+
# header is provided and the request_method is POST.
|
366
366
|
def form_data?
|
367
367
|
FORM_DATA_MEDIA_TYPES.include?(media_type)
|
368
368
|
end
|
@@ -415,8 +415,8 @@ module ActionDispatch
|
|
415
415
|
end
|
416
416
|
alias :request_parameters :POST
|
417
417
|
|
418
|
-
# Returns the authorization header regardless of whether it was specified
|
419
|
-
# proxy alternatives.
|
418
|
+
# Returns the authorization header regardless of whether it was specified
|
419
|
+
# directly or through one of the proxy alternatives.
|
420
420
|
def authorization
|
421
421
|
get_header("HTTP_AUTHORIZATION") ||
|
422
422
|
get_header("X-HTTP_AUTHORIZATION") ||
|
@@ -456,7 +456,7 @@ module ActionDispatch
|
|
456
456
|
private
|
457
457
|
def check_method(name)
|
458
458
|
if name
|
459
|
-
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS
|
459
|
+
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(locale: false)}")
|
460
460
|
end
|
461
461
|
|
462
462
|
name
|
@@ -467,29 +467,9 @@ module ActionDispatch
|
|
467
467
|
end
|
468
468
|
|
469
469
|
def read_body_stream
|
470
|
-
if body_stream
|
471
|
-
|
472
|
-
|
473
|
-
body_stream.read # Read body stream until EOF if "Transfer-Encoding" is present
|
474
|
-
else
|
475
|
-
body_stream.read(content_length)
|
476
|
-
end
|
477
|
-
end
|
478
|
-
end
|
479
|
-
end
|
480
|
-
|
481
|
-
def reset_stream(body_stream)
|
482
|
-
if body_stream.respond_to?(:rewind)
|
483
|
-
body_stream.rewind
|
484
|
-
|
485
|
-
content = yield
|
486
|
-
|
487
|
-
body_stream.rewind
|
488
|
-
|
489
|
-
content
|
490
|
-
else
|
491
|
-
yield
|
492
|
-
end
|
470
|
+
body_stream.rewind if body_stream.respond_to?(:rewind)
|
471
|
+
return body_stream.read if headers.key?("Transfer-Encoding") # Read body stream until EOF if "Transfer-Encoding" is present
|
472
|
+
body_stream.read(content_length)
|
493
473
|
end
|
494
474
|
end
|
495
475
|
end
|