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