actionpack 4.2.10 → 7.2.0.rc1
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 +5 -5
- data/CHANGELOG.md +86 -600
- data/MIT-LICENSE +1 -1
- data/README.rdoc +13 -14
- data/lib/abstract_controller/asset_paths.rb +5 -1
- data/lib/abstract_controller/base.rb +166 -136
- data/lib/abstract_controller/caching/fragments.rb +149 -0
- data/lib/abstract_controller/caching.rb +68 -0
- data/lib/abstract_controller/callbacks.rb +126 -57
- data/lib/abstract_controller/collector.rb +13 -15
- data/lib/abstract_controller/deprecator.rb +9 -0
- data/lib/abstract_controller/error.rb +8 -0
- data/lib/abstract_controller/helpers.rb +181 -132
- data/lib/abstract_controller/logger.rb +5 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +10 -3
- data/lib/abstract_controller/rendering.rb +56 -56
- data/lib/abstract_controller/translation.rb +29 -15
- data/lib/abstract_controller/url_for.rb +15 -11
- data/lib/abstract_controller.rb +21 -5
- data/lib/action_controller/api/api_rendering.rb +18 -0
- data/lib/action_controller/api.rb +154 -0
- data/lib/action_controller/base.rb +219 -155
- data/lib/action_controller/caching.rb +28 -68
- data/lib/action_controller/deprecator.rb +9 -0
- data/lib/action_controller/form_builder.rb +55 -0
- data/lib/action_controller/log_subscriber.rb +35 -22
- data/lib/action_controller/metal/allow_browser.rb +119 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
- data/lib/action_controller/metal/conditional_get.rb +259 -122
- data/lib/action_controller/metal/content_security_policy.rb +86 -0
- data/lib/action_controller/metal/cookies.rb +9 -5
- data/lib/action_controller/metal/data_streaming.rb +87 -104
- data/lib/action_controller/metal/default_headers.rb +21 -0
- data/lib/action_controller/metal/etag_with_flash.rb +22 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +35 -26
- data/lib/action_controller/metal/exceptions.rb +71 -24
- data/lib/action_controller/metal/flash.rb +26 -19
- data/lib/action_controller/metal/head.rb +45 -36
- data/lib/action_controller/metal/helpers.rb +80 -64
- data/lib/action_controller/metal/http_authentication.rb +297 -244
- data/lib/action_controller/metal/implicit_render.rb +57 -9
- data/lib/action_controller/metal/instrumentation.rb +76 -64
- data/lib/action_controller/metal/live.rb +238 -176
- data/lib/action_controller/metal/logging.rb +22 -0
- data/lib/action_controller/metal/mime_responds.rb +177 -166
- data/lib/action_controller/metal/parameter_encoding.rb +84 -0
- data/lib/action_controller/metal/params_wrapper.rb +145 -118
- data/lib/action_controller/metal/permissions_policy.rb +38 -0
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +203 -64
- data/lib/action_controller/metal/renderers.rb +108 -65
- data/lib/action_controller/metal/rendering.rb +216 -56
- data/lib/action_controller/metal/request_forgery_protection.rb +496 -163
- data/lib/action_controller/metal/rescue.rb +19 -21
- data/lib/action_controller/metal/streaming.rb +179 -138
- data/lib/action_controller/metal/strong_parameters.rb +1058 -382
- data/lib/action_controller/metal/testing.rb +11 -17
- data/lib/action_controller/metal/url_for.rb +37 -21
- data/lib/action_controller/metal.rb +236 -138
- data/lib/action_controller/railtie.rb +89 -11
- data/lib/action_controller/railties/helpers.rb +5 -1
- data/lib/action_controller/renderer.rb +161 -0
- data/lib/action_controller/template_assertions.rb +13 -0
- data/lib/action_controller/test_case.rb +425 -497
- data/lib/action_controller.rb +44 -22
- data/lib/action_dispatch/constants.rb +34 -0
- data/lib/action_dispatch/deprecator.rb +9 -0
- data/lib/action_dispatch/http/cache.rb +119 -63
- data/lib/action_dispatch/http/content_disposition.rb +47 -0
- data/lib/action_dispatch/http/content_security_policy.rb +364 -0
- data/lib/action_dispatch/http/filter_parameters.rb +36 -34
- data/lib/action_dispatch/http/filter_redirect.rb +24 -12
- data/lib/action_dispatch/http/headers.rb +66 -31
- data/lib/action_dispatch/http/mime_negotiation.rb +106 -75
- data/lib/action_dispatch/http/mime_type.rb +196 -136
- data/lib/action_dispatch/http/mime_types.rb +25 -7
- data/lib/action_dispatch/http/parameters.rb +97 -45
- data/lib/action_dispatch/http/permissions_policy.rb +187 -0
- data/lib/action_dispatch/http/rack_cache.rb +6 -0
- data/lib/action_dispatch/http/request.rb +299 -170
- data/lib/action_dispatch/http/response.rb +311 -160
- data/lib/action_dispatch/http/upload.rb +52 -23
- data/lib/action_dispatch/http/url.rb +201 -125
- data/lib/action_dispatch/journey/formatter.rb +110 -50
- data/lib/action_dispatch/journey/gtg/builder.rb +37 -50
- data/lib/action_dispatch/journey/gtg/simulator.rb +20 -17
- data/lib/action_dispatch/journey/gtg/transition_table.rb +96 -36
- data/lib/action_dispatch/journey/nfa/dot.rb +5 -14
- data/lib/action_dispatch/journey/nodes/node.rb +100 -20
- data/lib/action_dispatch/journey/parser.rb +19 -17
- data/lib/action_dispatch/journey/parser.y +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +14 -4
- data/lib/action_dispatch/journey/path/pattern.rb +79 -63
- data/lib/action_dispatch/journey/route.rb +108 -44
- data/lib/action_dispatch/journey/router/utils.rb +41 -29
- data/lib/action_dispatch/journey/router.rb +64 -57
- data/lib/action_dispatch/journey/routes.rb +23 -21
- data/lib/action_dispatch/journey/scanner.rb +28 -17
- data/lib/action_dispatch/journey/visitors.rb +100 -54
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/journey.rb +7 -5
- data/lib/action_dispatch/log_subscriber.rb +25 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
- data/lib/action_dispatch/middleware/callbacks.rb +7 -6
- data/lib/action_dispatch/middleware/cookies.rb +471 -328
- data/lib/action_dispatch/middleware/debug_exceptions.rb +149 -66
- data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
- data/lib/action_dispatch/middleware/debug_view.rb +73 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +275 -73
- data/lib/action_dispatch/middleware/executor.rb +32 -0
- data/lib/action_dispatch/middleware/flash.rb +143 -101
- data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +36 -27
- data/lib/action_dispatch/middleware/reloader.rb +10 -92
- data/lib/action_dispatch/middleware/remote_ip.rb +133 -107
- data/lib/action_dispatch/middleware/request_id.rb +29 -15
- data/lib/action_dispatch/middleware/server_timing.rb +78 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +49 -27
- data/lib/action_dispatch/middleware/session/cache_store.rb +33 -16
- data/lib/action_dispatch/middleware/session/cookie_store.rb +86 -80
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +66 -36
- data/lib/action_dispatch/middleware/ssl.rb +134 -36
- data/lib/action_dispatch/middleware/stack.rb +109 -44
- data/lib/action_dispatch/middleware/static.rb +159 -90
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +7 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +46 -36
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +139 -15
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +6 -6
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +9 -9
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +7 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +125 -93
- data/lib/action_dispatch/railtie.rb +44 -16
- data/lib/action_dispatch/request/session.rb +159 -69
- data/lib/action_dispatch/request/utils.rb +97 -23
- data/lib/action_dispatch/routing/endpoint.rb +11 -2
- data/lib/action_dispatch/routing/inspector.rb +195 -106
- data/lib/action_dispatch/routing/mapper.rb +1338 -955
- data/lib/action_dispatch/routing/polymorphic_routes.rb +234 -201
- data/lib/action_dispatch/routing/redirection.rb +78 -51
- data/lib/action_dispatch/routing/route_set.rb +460 -374
- data/lib/action_dispatch/routing/routes_proxy.rb +36 -12
- data/lib/action_dispatch/routing/url_for.rb +172 -124
- data/lib/action_dispatch/routing.rb +159 -158
- data/lib/action_dispatch/system_test_case.rb +206 -0
- data/lib/action_dispatch/system_testing/browser.rb +84 -0
- data/lib/action_dispatch/system_testing/driver.rb +85 -0
- data/lib/action_dispatch/system_testing/server.rb +33 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
- data/lib/action_dispatch/testing/assertion_response.rb +48 -0
- data/lib/action_dispatch/testing/assertions/response.rb +71 -39
- data/lib/action_dispatch/testing/assertions/routing.rb +228 -103
- data/lib/action_dispatch/testing/assertions.rb +9 -6
- data/lib/action_dispatch/testing/integration.rb +486 -306
- data/lib/action_dispatch/testing/request_encoder.rb +60 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +35 -22
- data/lib/action_dispatch/testing/test_request.rb +29 -34
- data/lib/action_dispatch/testing/test_response.rb +48 -15
- data/lib/action_dispatch.rb +82 -40
- data/lib/action_pack/gem_version.rb +8 -4
- data/lib/action_pack/version.rb +6 -2
- data/lib/action_pack.rb +21 -18
- metadata +146 -56
- data/lib/action_controller/caching/fragments.rb +0 -103
- data/lib/action_controller/metal/force_ssl.rb +0 -97
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/http/parameter_filter.rb +0 -72
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +0 -27
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,27 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require
|
6
|
-
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :markup: markdown
|
4
|
+
|
5
|
+
require "stringio"
|
6
|
+
|
7
|
+
require "active_support/inflector"
|
8
|
+
require "action_dispatch/http/headers"
|
9
|
+
require "action_controller/metal/exceptions"
|
10
|
+
require "rack/request"
|
11
|
+
require "action_dispatch/http/cache"
|
12
|
+
require "action_dispatch/http/mime_negotiation"
|
13
|
+
require "action_dispatch/http/parameters"
|
14
|
+
require "action_dispatch/http/filter_parameters"
|
15
|
+
require "action_dispatch/http/upload"
|
16
|
+
require "action_dispatch/http/url"
|
17
|
+
require "active_support/core_ext/array/conversions"
|
14
18
|
|
15
19
|
module ActionDispatch
|
16
|
-
class Request
|
20
|
+
class Request
|
21
|
+
include Rack::Request::Helpers
|
17
22
|
include ActionDispatch::Http::Cache::Request
|
18
23
|
include ActionDispatch::Http::MimeNegotiation
|
19
24
|
include ActionDispatch::Http::Parameters
|
20
25
|
include ActionDispatch::Http::FilterParameters
|
21
26
|
include ActionDispatch::Http::URL
|
27
|
+
include ActionDispatch::ContentSecurityPolicy::Request
|
28
|
+
include ActionDispatch::PermissionsPolicy::Request
|
29
|
+
include Rack::Request::Env
|
22
30
|
|
23
|
-
autoload :Session,
|
24
|
-
autoload :Utils,
|
31
|
+
autoload :Session, "action_dispatch/request/session"
|
32
|
+
autoload :Utils, "action_dispatch/request/utils"
|
25
33
|
|
26
34
|
LOCALHOST = Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
|
27
35
|
|
@@ -29,19 +37,28 @@ module ActionDispatch
|
|
29
37
|
PATH_TRANSLATED REMOTE_HOST
|
30
38
|
REMOTE_IDENT REMOTE_USER REMOTE_ADDR
|
31
39
|
SERVER_NAME SERVER_PROTOCOL
|
40
|
+
ORIGINAL_SCRIPT_NAME
|
32
41
|
|
33
42
|
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
|
34
43
|
HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM
|
35
|
-
HTTP_NEGOTIATE HTTP_PRAGMA
|
44
|
+
HTTP_NEGOTIATE HTTP_PRAGMA HTTP_CLIENT_IP
|
45
|
+
HTTP_X_FORWARDED_FOR HTTP_ORIGIN HTTP_VERSION
|
46
|
+
HTTP_X_CSRF_TOKEN HTTP_X_REQUEST_ID HTTP_X_FORWARDED_HOST
|
47
|
+
].freeze
|
36
48
|
|
37
49
|
ENV_METHODS.each do |env|
|
38
50
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
39
|
-
|
40
|
-
|
41
|
-
|
51
|
+
# frozen_string_literal: true
|
52
|
+
def #{env.delete_prefix("HTTP_").downcase} # def accept_charset
|
53
|
+
get_header "#{env}" # get_header "HTTP_ACCEPT_CHARSET"
|
54
|
+
end # end
|
42
55
|
METHOD
|
43
56
|
end
|
44
57
|
|
58
|
+
def self.empty
|
59
|
+
new({})
|
60
|
+
end
|
61
|
+
|
45
62
|
def initialize(env)
|
46
63
|
super
|
47
64
|
@method = nil
|
@@ -50,299 +67,411 @@ module ActionDispatch
|
|
50
67
|
@original_fullpath = nil
|
51
68
|
@fullpath = nil
|
52
69
|
@ip = nil
|
53
|
-
@uuid = nil
|
54
70
|
end
|
55
71
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
72
|
+
def commit_cookie_jar! # :nodoc:
|
73
|
+
end
|
74
|
+
|
75
|
+
PASS_NOT_FOUND = Class.new { # :nodoc:
|
76
|
+
def self.action(_); self; end
|
77
|
+
def self.call(_); [404, { Constants::X_CASCADE => "pass" }, []]; end
|
78
|
+
def self.action_encoding_template(action); false; end
|
79
|
+
}
|
80
|
+
|
81
|
+
def controller_class
|
82
|
+
params = path_parameters
|
83
|
+
params[:action] ||= "index"
|
84
|
+
controller_class_for(params[:controller])
|
85
|
+
end
|
86
|
+
|
87
|
+
def controller_class_for(name)
|
88
|
+
if name
|
89
|
+
controller_param = name.underscore
|
90
|
+
const_name = controller_param.camelize << "Controller"
|
91
|
+
begin
|
92
|
+
const_name.constantize
|
93
|
+
rescue NameError => error
|
94
|
+
if error.missing_name == const_name || const_name.start_with?("#{error.missing_name}::")
|
95
|
+
raise MissingController.new(error.message, error.name)
|
96
|
+
else
|
97
|
+
raise
|
98
|
+
end
|
63
99
|
end
|
100
|
+
else
|
101
|
+
PASS_NOT_FOUND
|
64
102
|
end
|
65
103
|
end
|
66
104
|
|
105
|
+
# Returns true if the request has a header matching the given key parameter.
|
106
|
+
#
|
107
|
+
# request.key? :ip_spoofing_check # => true
|
67
108
|
def key?(key)
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
# Hypertext Transfer Protocol -- HTTP/1.1 (http://www.ietf.org/rfc/rfc2616.txt)
|
73
|
-
# HTTP Extensions for Distributed Authoring -- WEBDAV (http://www.ietf.org/rfc/rfc2518.txt)
|
74
|
-
# Versioning Extensions to WebDAV (http://www.ietf.org/rfc/rfc3253.txt)
|
75
|
-
# Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt)
|
76
|
-
# Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt)
|
77
|
-
# Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt)
|
78
|
-
# Calendar Extensions to WebDAV (http://www.ietf.org/rfc/rfc4791.txt)
|
79
|
-
# PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt)
|
109
|
+
has_header? key
|
110
|
+
end
|
111
|
+
|
112
|
+
# HTTP methods from [RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1](https://www.ietf.org/rfc/rfc2616.txt)
|
80
113
|
RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
|
114
|
+
# HTTP methods from [RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV](https://www.ietf.org/rfc/rfc2518.txt)
|
81
115
|
RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
|
116
|
+
# HTTP methods from [RFC 3253: Versioning Extensions to WebDAV](https://www.ietf.org/rfc/rfc3253.txt)
|
82
117
|
RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
|
118
|
+
# HTTP methods from [RFC 3648: WebDAV Ordered Collections Protocol](https://www.ietf.org/rfc/rfc3648.txt)
|
83
119
|
RFC3648 = %w(ORDERPATCH)
|
120
|
+
# HTTP methods from [RFC 3744: WebDAV Access Control Protocol](https://www.ietf.org/rfc/rfc3744.txt)
|
84
121
|
RFC3744 = %w(ACL)
|
122
|
+
# HTTP methods from [RFC 5323: WebDAV SEARCH](https://www.ietf.org/rfc/rfc5323.txt)
|
85
123
|
RFC5323 = %w(SEARCH)
|
124
|
+
# HTTP methods from [RFC 4791: Calendaring Extensions to WebDAV](https://www.ietf.org/rfc/rfc4791.txt)
|
86
125
|
RFC4791 = %w(MKCALENDAR)
|
126
|
+
# HTTP methods from [RFC 5789: PATCH Method for HTTP](https://www.ietf.org/rfc/rfc5789.txt)
|
87
127
|
RFC5789 = %w(PATCH)
|
88
128
|
|
89
129
|
HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789
|
90
130
|
|
91
131
|
HTTP_METHOD_LOOKUP = {}
|
92
132
|
|
93
|
-
# Populate the HTTP method lookup cache
|
133
|
+
# Populate the HTTP method lookup cache.
|
94
134
|
HTTP_METHODS.each { |method|
|
95
135
|
HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym
|
96
136
|
}
|
97
137
|
|
98
|
-
|
99
|
-
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
# value, not the
|
138
|
+
alias raw_request_method request_method # :nodoc:
|
139
|
+
|
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.
|
104
145
|
def request_method
|
105
|
-
@request_method ||= check_method(
|
146
|
+
@request_method ||= check_method(super)
|
106
147
|
end
|
107
148
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
149
|
+
# Returns the URI pattern of the matched route for the request, using the same
|
150
|
+
# format as `bin/rails routes`:
|
151
|
+
#
|
152
|
+
# request.route_uri_pattern # => "/:controller(/:action(/:id))(.:format)"
|
153
|
+
def route_uri_pattern
|
154
|
+
get_header("action_dispatch.route_uri_pattern")
|
112
155
|
end
|
113
156
|
|
114
|
-
|
115
|
-
|
116
|
-
HTTP_METHOD_LOOKUP[request_method]
|
157
|
+
def route_uri_pattern=(pattern) # :nodoc:
|
158
|
+
set_header("action_dispatch.route_uri_pattern", pattern)
|
117
159
|
end
|
118
160
|
|
119
|
-
|
120
|
-
|
121
|
-
# more information.
|
122
|
-
def method
|
123
|
-
@method ||= check_method(env["rack.methodoverride.original_method"] || env['REQUEST_METHOD'])
|
161
|
+
def routes # :nodoc:
|
162
|
+
get_header("action_dispatch.routes")
|
124
163
|
end
|
125
164
|
|
126
|
-
|
127
|
-
|
128
|
-
HTTP_METHOD_LOOKUP[method]
|
165
|
+
def routes=(routes) # :nodoc:
|
166
|
+
set_header("action_dispatch.routes", routes)
|
129
167
|
end
|
130
168
|
|
131
|
-
|
132
|
-
|
133
|
-
def get?
|
134
|
-
HTTP_METHOD_LOOKUP[request_method] == :get
|
169
|
+
def engine_script_name(_routes) # :nodoc:
|
170
|
+
get_header(_routes.env_key)
|
135
171
|
end
|
136
172
|
|
137
|
-
|
138
|
-
|
139
|
-
def post?
|
140
|
-
HTTP_METHOD_LOOKUP[request_method] == :post
|
173
|
+
def engine_script_name=(name) # :nodoc:
|
174
|
+
set_header(routes.env_key, name.dup)
|
141
175
|
end
|
142
176
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
177
|
+
def request_method=(request_method) # :nodoc:
|
178
|
+
if check_method(request_method)
|
179
|
+
@request_method = set_header("REQUEST_METHOD", request_method)
|
180
|
+
end
|
147
181
|
end
|
148
182
|
|
149
|
-
|
150
|
-
|
151
|
-
def put?
|
152
|
-
HTTP_METHOD_LOOKUP[request_method] == :put
|
183
|
+
def controller_instance # :nodoc:
|
184
|
+
get_header("action_controller.instance")
|
153
185
|
end
|
154
186
|
|
155
|
-
|
156
|
-
|
157
|
-
def delete?
|
158
|
-
HTTP_METHOD_LOOKUP[request_method] == :delete
|
187
|
+
def controller_instance=(controller) # :nodoc:
|
188
|
+
set_header("action_controller.instance", controller)
|
159
189
|
end
|
160
190
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
191
|
+
def http_auth_salt
|
192
|
+
get_header "action_dispatch.http_auth_salt"
|
193
|
+
end
|
194
|
+
|
195
|
+
# Returns a symbol form of the #request_method.
|
196
|
+
def request_method_symbol
|
197
|
+
HTTP_METHOD_LOOKUP[request_method]
|
198
|
+
end
|
199
|
+
|
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
|
+
#
|
203
|
+
# For debugging purposes, when called with arguments this method will fall back
|
204
|
+
# to Object#method
|
205
|
+
def method(*args)
|
206
|
+
if args.empty?
|
207
|
+
@method ||= check_method(
|
208
|
+
get_header("rack.methodoverride.original_method") ||
|
209
|
+
get_header("REQUEST_METHOD")
|
210
|
+
)
|
211
|
+
else
|
212
|
+
super
|
213
|
+
end
|
214
|
+
end
|
215
|
+
ruby2_keywords(:method)
|
216
|
+
|
217
|
+
# Returns a symbol form of the #method.
|
218
|
+
def method_symbol
|
219
|
+
HTTP_METHOD_LOOKUP[method]
|
165
220
|
end
|
166
221
|
|
167
222
|
# Provides access to the request's HTTP headers, for example:
|
168
223
|
#
|
169
|
-
#
|
224
|
+
# request.headers["Content-Type"] # => "text/plain"
|
170
225
|
def headers
|
171
|
-
Http::Headers.new(
|
226
|
+
@headers ||= Http::Headers.new(self)
|
172
227
|
end
|
173
228
|
|
174
|
-
#
|
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
|
+
#
|
232
|
+
# If the env contains `rack.early_hints` then the server accepts HTTP2 push for
|
233
|
+
# link headers.
|
234
|
+
#
|
235
|
+
# The `send_early_hints` method accepts a hash of links as follows:
|
175
236
|
#
|
176
|
-
#
|
177
|
-
# request.original_fullpath # => '/foo'
|
237
|
+
# send_early_hints("link" => "</style.css>; rel=preload; as=style,</script.js>; rel=preload")
|
178
238
|
#
|
179
|
-
#
|
180
|
-
#
|
239
|
+
# If you are using `javascript_include_tag` or `stylesheet_link_tag` the Early
|
240
|
+
# Hints headers are included by default if supported.
|
241
|
+
def send_early_hints(links)
|
242
|
+
env["rack.early_hints"]&.call(links)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Returns a `String` with the last requested path including their params.
|
246
|
+
#
|
247
|
+
# # get '/foo'
|
248
|
+
# request.original_fullpath # => '/foo'
|
249
|
+
#
|
250
|
+
# # get '/foo?bar'
|
251
|
+
# request.original_fullpath # => '/foo?bar'
|
181
252
|
def original_fullpath
|
182
|
-
@original_fullpath ||= (
|
253
|
+
@original_fullpath ||= (get_header("ORIGINAL_FULLPATH") || fullpath)
|
183
254
|
end
|
184
255
|
|
185
|
-
# Returns the
|
256
|
+
# Returns the `String` full path including params of the last URL requested.
|
186
257
|
#
|
187
|
-
#
|
188
|
-
#
|
258
|
+
# # get "/articles"
|
259
|
+
# request.fullpath # => "/articles"
|
189
260
|
#
|
190
|
-
#
|
191
|
-
#
|
261
|
+
# # get "/articles?page=2"
|
262
|
+
# request.fullpath # => "/articles?page=2"
|
192
263
|
def fullpath
|
193
264
|
@fullpath ||= super
|
194
265
|
end
|
195
266
|
|
196
|
-
# Returns the original request URL as a
|
267
|
+
# Returns the original request URL as a `String`.
|
197
268
|
#
|
198
|
-
#
|
199
|
-
#
|
269
|
+
# # get "/articles?page=2"
|
270
|
+
# request.original_url # => "http://www.example.com/articles?page=2"
|
200
271
|
def original_url
|
201
272
|
base_url + original_fullpath
|
202
273
|
end
|
203
274
|
|
204
|
-
# The
|
275
|
+
# The `String` MIME type of the request.
|
205
276
|
#
|
206
|
-
#
|
207
|
-
#
|
277
|
+
# # get "/articles"
|
278
|
+
# request.media_type # => "application/x-www-form-urlencoded"
|
208
279
|
def media_type
|
209
|
-
content_mime_type
|
280
|
+
content_mime_type&.to_s
|
210
281
|
end
|
211
282
|
|
212
283
|
# Returns the content length of the request as an integer.
|
213
284
|
def content_length
|
285
|
+
return raw_post.bytesize if headers.key?("Transfer-Encoding")
|
214
286
|
super.to_i
|
215
287
|
end
|
216
288
|
|
217
|
-
# Returns true if the
|
289
|
+
# Returns true if the `X-Requested-With` header contains "XMLHttpRequest"
|
218
290
|
# (case-insensitive), which may need to be manually added depending on the
|
219
291
|
# choice of JavaScript libraries and frameworks.
|
220
292
|
def xml_http_request?
|
221
|
-
|
293
|
+
/XMLHttpRequest/i.match?(get_header("HTTP_X_REQUESTED_WITH"))
|
222
294
|
end
|
223
295
|
alias :xhr? :xml_http_request?
|
224
296
|
|
297
|
+
# Returns the IP address of client as a `String`.
|
225
298
|
def ip
|
226
299
|
@ip ||= super
|
227
300
|
end
|
228
301
|
|
229
|
-
#
|
302
|
+
# Returns the IP address of client as a `String`, usually set by the RemoteIp
|
303
|
+
# middleware.
|
230
304
|
def remote_ip
|
231
|
-
@remote_ip ||= (
|
305
|
+
@remote_ip ||= (get_header("action_dispatch.remote_ip") || ip).to_s
|
306
|
+
end
|
307
|
+
|
308
|
+
def remote_ip=(remote_ip)
|
309
|
+
@remote_ip = nil
|
310
|
+
set_header "action_dispatch.remote_ip", remote_ip
|
232
311
|
end
|
233
312
|
|
234
|
-
|
235
|
-
|
236
|
-
#
|
313
|
+
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id" # :nodoc:
|
314
|
+
|
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).
|
237
319
|
#
|
238
|
-
# This unique ID is useful for tracing a request from end-to-end as part of
|
239
|
-
# This relies on the
|
240
|
-
|
241
|
-
|
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
|
+
def request_id
|
324
|
+
get_header ACTION_DISPATCH_REQUEST_ID
|
325
|
+
end
|
326
|
+
|
327
|
+
def request_id=(id) # :nodoc:
|
328
|
+
set_header ACTION_DISPATCH_REQUEST_ID, id
|
242
329
|
end
|
243
330
|
|
331
|
+
alias_method :uuid, :request_id
|
332
|
+
|
244
333
|
# Returns the lowercase name of the HTTP server software.
|
245
334
|
def server_software
|
246
|
-
(
|
335
|
+
(get_header("SERVER_SOFTWARE") && /^([a-zA-Z]+)/ =~ get_header("SERVER_SOFTWARE")) ? $1.downcase : nil
|
247
336
|
end
|
248
337
|
|
249
|
-
# Read the request
|
250
|
-
#
|
338
|
+
# Read the request body. This is useful for web services that need to work with
|
339
|
+
# raw requests directly.
|
251
340
|
def raw_post
|
252
|
-
unless
|
253
|
-
|
254
|
-
|
255
|
-
raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
|
341
|
+
unless has_header? "RAW_POST_DATA"
|
342
|
+
set_header("RAW_POST_DATA", read_body_stream)
|
343
|
+
body_stream.rewind if body_stream.respond_to?(:rewind)
|
256
344
|
end
|
257
|
-
|
345
|
+
get_header "RAW_POST_DATA"
|
258
346
|
end
|
259
347
|
|
260
348
|
# The request body is an IO input stream. If the RAW_POST_DATA environment
|
261
349
|
# variable is already set, wrap it in a StringIO.
|
262
350
|
def body
|
263
|
-
if raw_post =
|
264
|
-
raw_post.force_encoding(Encoding::BINARY)
|
351
|
+
if raw_post = get_header("RAW_POST_DATA")
|
352
|
+
raw_post = (+raw_post).force_encoding(Encoding::BINARY)
|
265
353
|
StringIO.new(raw_post)
|
266
354
|
else
|
267
|
-
|
355
|
+
body_stream
|
268
356
|
end
|
269
357
|
end
|
270
358
|
|
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
|
+
#
|
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.
|
271
366
|
def form_data?
|
272
|
-
FORM_DATA_MEDIA_TYPES.include?(
|
367
|
+
FORM_DATA_MEDIA_TYPES.include?(media_type)
|
273
368
|
end
|
274
369
|
|
275
|
-
def body_stream
|
276
|
-
|
370
|
+
def body_stream # :nodoc:
|
371
|
+
get_header("rack.input")
|
277
372
|
end
|
278
373
|
|
279
|
-
# TODO This should be broken apart into AD::Request::Session and probably
|
280
|
-
# be included by the session middleware.
|
281
374
|
def reset_session
|
282
|
-
|
283
|
-
|
284
|
-
else
|
285
|
-
self.session = {}
|
286
|
-
end
|
287
|
-
@env['action_dispatch.request.flash_hash'] = nil
|
375
|
+
session.destroy
|
376
|
+
reset_csrf_token
|
288
377
|
end
|
289
378
|
|
290
|
-
def session=(session)
|
291
|
-
Session.set
|
379
|
+
def session=(session) # :nodoc:
|
380
|
+
Session.set self, session
|
292
381
|
end
|
293
382
|
|
294
383
|
def session_options=(options)
|
295
|
-
Session::Options.set
|
384
|
+
Session::Options.set self, options
|
296
385
|
end
|
297
386
|
|
298
|
-
# Override Rack's GET method to support indifferent access
|
387
|
+
# Override Rack's GET method to support indifferent access.
|
299
388
|
def GET
|
300
|
-
|
301
|
-
|
302
|
-
|
389
|
+
fetch_header("action_dispatch.request.query_parameters") do |k|
|
390
|
+
rack_query_params = super || {}
|
391
|
+
controller = path_parameters[:controller]
|
392
|
+
action = path_parameters[:action]
|
393
|
+
rack_query_params = Request::Utils.set_binary_encoding(self, rack_query_params, controller, action)
|
394
|
+
# Check for non UTF-8 parameter values, which would cause errors later
|
395
|
+
Request::Utils.check_param_encoding(rack_query_params)
|
396
|
+
set_header k, Request::Utils.normalize_encode_params(rack_query_params)
|
397
|
+
end
|
398
|
+
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError, Rack::QueryParser::ParamsTooDeepError => e
|
399
|
+
raise ActionController::BadRequest.new("Invalid query parameters: #{e.message}")
|
303
400
|
end
|
304
401
|
alias :query_parameters :GET
|
305
402
|
|
306
|
-
# Override Rack's POST method to support indifferent access
|
403
|
+
# Override Rack's POST method to support indifferent access.
|
307
404
|
def POST
|
308
|
-
|
309
|
-
|
310
|
-
|
405
|
+
fetch_header("action_dispatch.request.request_parameters") do
|
406
|
+
pr = parse_formatted_parameters(params_parsers) do |params|
|
407
|
+
super || {}
|
408
|
+
end
|
409
|
+
pr = Request::Utils.set_binary_encoding(self, pr, path_parameters[:controller], path_parameters[:action])
|
410
|
+
Request::Utils.check_param_encoding(pr)
|
411
|
+
self.request_parameters = Request::Utils.normalize_encode_params(pr)
|
412
|
+
end
|
413
|
+
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError, Rack::QueryParser::ParamsTooDeepError, EOFError => e
|
414
|
+
raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
|
311
415
|
end
|
312
416
|
alias :request_parameters :POST
|
313
417
|
|
314
|
-
# Returns the authorization header regardless of whether it was specified
|
315
|
-
# proxy alternatives.
|
418
|
+
# Returns the authorization header regardless of whether it was specified
|
419
|
+
# directly or through one of the proxy alternatives.
|
316
420
|
def authorization
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
421
|
+
get_header("HTTP_AUTHORIZATION") ||
|
422
|
+
get_header("X-HTTP_AUTHORIZATION") ||
|
423
|
+
get_header("X_HTTP_AUTHORIZATION") ||
|
424
|
+
get_header("REDIRECT_X_HTTP_AUTHORIZATION")
|
321
425
|
end
|
322
426
|
|
323
|
-
# True if the request came from localhost, 127.0.0.1.
|
427
|
+
# True if the request came from localhost, 127.0.0.1, or ::1.
|
324
428
|
def local?
|
325
|
-
LOCALHOST
|
429
|
+
LOCALHOST.match?(remote_addr) && LOCALHOST.match?(remote_ip)
|
326
430
|
end
|
327
431
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
)
|
432
|
+
def request_parameters=(params)
|
433
|
+
raise if params.nil?
|
434
|
+
set_header("action_dispatch.request.request_parameters", params)
|
435
|
+
end
|
333
436
|
|
334
|
-
|
437
|
+
def logger
|
438
|
+
get_header("action_dispatch.logger")
|
335
439
|
end
|
336
440
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
441
|
+
def commit_flash
|
442
|
+
end
|
443
|
+
|
444
|
+
def inspect # :nodoc:
|
445
|
+
"#<#{self.class.name} #{method} #{original_url.dump} for #{remote_ip}>"
|
446
|
+
end
|
447
|
+
|
448
|
+
def reset_csrf_token
|
449
|
+
controller_instance.reset_csrf_token(self) if controller_instance.respond_to?(:reset_csrf_token)
|
450
|
+
end
|
451
|
+
|
452
|
+
def commit_csrf_token
|
453
|
+
controller_instance.commit_csrf_token(self) if controller_instance.respond_to?(:commit_csrf_token)
|
454
|
+
end
|
341
455
|
|
342
456
|
private
|
343
457
|
def check_method(name)
|
344
|
-
|
458
|
+
if name
|
459
|
+
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(locale: false)}")
|
460
|
+
end
|
461
|
+
|
345
462
|
name
|
346
463
|
end
|
464
|
+
|
465
|
+
def default_session
|
466
|
+
Session.disabled(self)
|
467
|
+
end
|
468
|
+
|
469
|
+
def read_body_stream
|
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)
|
473
|
+
end
|
347
474
|
end
|
348
475
|
end
|
476
|
+
|
477
|
+
ActiveSupport.run_load_hooks :action_dispatch_request, ActionDispatch::Request
|