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.
Files changed (187) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +129 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +57 -0
  5. data/lib/abstract_controller/asset_paths.rb +14 -0
  6. data/lib/abstract_controller/base.rb +299 -0
  7. data/lib/abstract_controller/caching/fragments.rb +149 -0
  8. data/lib/abstract_controller/caching.rb +68 -0
  9. data/lib/abstract_controller/callbacks.rb +265 -0
  10. data/lib/abstract_controller/collector.rb +44 -0
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +8 -0
  13. data/lib/abstract_controller/helpers.rb +243 -0
  14. data/lib/abstract_controller/logger.rb +16 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +25 -0
  16. data/lib/abstract_controller/rendering.rb +126 -0
  17. data/lib/abstract_controller/translation.rb +42 -0
  18. data/lib/abstract_controller/url_for.rb +37 -0
  19. data/lib/abstract_controller.rb +36 -0
  20. data/lib/action_controller/api/api_rendering.rb +18 -0
  21. data/lib/action_controller/api.rb +155 -0
  22. data/lib/action_controller/base.rb +332 -0
  23. data/lib/action_controller/caching.rb +49 -0
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +55 -0
  26. data/lib/action_controller/log_subscriber.rb +96 -0
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
  29. data/lib/action_controller/metal/conditional_get.rb +341 -0
  30. data/lib/action_controller/metal/content_security_policy.rb +86 -0
  31. data/lib/action_controller/metal/cookies.rb +20 -0
  32. data/lib/action_controller/metal/data_streaming.rb +154 -0
  33. data/lib/action_controller/metal/default_headers.rb +21 -0
  34. data/lib/action_controller/metal/etag_with_flash.rb +22 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +59 -0
  36. data/lib/action_controller/metal/exceptions.rb +106 -0
  37. data/lib/action_controller/metal/flash.rb +67 -0
  38. data/lib/action_controller/metal/head.rb +67 -0
  39. data/lib/action_controller/metal/helpers.rb +129 -0
  40. data/lib/action_controller/metal/http_authentication.rb +565 -0
  41. data/lib/action_controller/metal/implicit_render.rb +67 -0
  42. data/lib/action_controller/metal/instrumentation.rb +120 -0
  43. data/lib/action_controller/metal/live.rb +398 -0
  44. data/lib/action_controller/metal/logging.rb +22 -0
  45. data/lib/action_controller/metal/mime_responds.rb +337 -0
  46. data/lib/action_controller/metal/parameter_encoding.rb +84 -0
  47. data/lib/action_controller/metal/params_wrapper.rb +312 -0
  48. data/lib/action_controller/metal/permissions_policy.rb +38 -0
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +251 -0
  51. data/lib/action_controller/metal/renderers.rb +181 -0
  52. data/lib/action_controller/metal/rendering.rb +260 -0
  53. data/lib/action_controller/metal/request_forgery_protection.rb +667 -0
  54. data/lib/action_controller/metal/rescue.rb +33 -0
  55. data/lib/action_controller/metal/streaming.rb +183 -0
  56. data/lib/action_controller/metal/strong_parameters.rb +1546 -0
  57. data/lib/action_controller/metal/testing.rb +25 -0
  58. data/lib/action_controller/metal/url_for.rb +65 -0
  59. data/lib/action_controller/metal.rb +339 -0
  60. data/lib/action_controller/railtie.rb +149 -0
  61. data/lib/action_controller/railties/helpers.rb +26 -0
  62. data/lib/action_controller/renderer.rb +161 -0
  63. data/lib/action_controller/template_assertions.rb +13 -0
  64. data/lib/action_controller/test_case.rb +691 -0
  65. data/lib/action_controller.rb +80 -0
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +249 -0
  69. data/lib/action_dispatch/http/content_disposition.rb +47 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +365 -0
  71. data/lib/action_dispatch/http/filter_parameters.rb +80 -0
  72. data/lib/action_dispatch/http/filter_redirect.rb +50 -0
  73. data/lib/action_dispatch/http/headers.rb +134 -0
  74. data/lib/action_dispatch/http/mime_negotiation.rb +187 -0
  75. data/lib/action_dispatch/http/mime_type.rb +389 -0
  76. data/lib/action_dispatch/http/mime_types.rb +54 -0
  77. data/lib/action_dispatch/http/parameters.rb +119 -0
  78. data/lib/action_dispatch/http/permissions_policy.rb +189 -0
  79. data/lib/action_dispatch/http/rack_cache.rb +67 -0
  80. data/lib/action_dispatch/http/request.rb +498 -0
  81. data/lib/action_dispatch/http/response.rb +556 -0
  82. data/lib/action_dispatch/http/upload.rb +107 -0
  83. data/lib/action_dispatch/http/url.rb +344 -0
  84. data/lib/action_dispatch/journey/formatter.rb +226 -0
  85. data/lib/action_dispatch/journey/gtg/builder.rb +149 -0
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +50 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +217 -0
  88. data/lib/action_dispatch/journey/nfa/dot.rb +27 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +208 -0
  90. data/lib/action_dispatch/journey/parser.rb +103 -0
  91. data/lib/action_dispatch/journey/path/pattern.rb +209 -0
  92. data/lib/action_dispatch/journey/route.rb +189 -0
  93. data/lib/action_dispatch/journey/router/utils.rb +105 -0
  94. data/lib/action_dispatch/journey/router.rb +151 -0
  95. data/lib/action_dispatch/journey/routes.rb +82 -0
  96. data/lib/action_dispatch/journey/scanner.rb +70 -0
  97. data/lib/action_dispatch/journey/visitors.rb +267 -0
  98. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  99. data/lib/action_dispatch/journey/visualizer/fsm.js +159 -0
  100. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  101. data/lib/action_dispatch/journey.rb +7 -0
  102. data/lib/action_dispatch/log_subscriber.rb +25 -0
  103. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  104. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  105. data/lib/action_dispatch/middleware/callbacks.rb +38 -0
  106. data/lib/action_dispatch/middleware/cookies.rb +719 -0
  107. data/lib/action_dispatch/middleware/debug_exceptions.rb +206 -0
  108. data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
  109. data/lib/action_dispatch/middleware/debug_view.rb +73 -0
  110. data/lib/action_dispatch/middleware/exception_wrapper.rb +350 -0
  111. data/lib/action_dispatch/middleware/executor.rb +32 -0
  112. data/lib/action_dispatch/middleware/flash.rb +318 -0
  113. data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
  114. data/lib/action_dispatch/middleware/public_exceptions.rb +64 -0
  115. data/lib/action_dispatch/middleware/reloader.rb +16 -0
  116. data/lib/action_dispatch/middleware/remote_ip.rb +199 -0
  117. data/lib/action_dispatch/middleware/request_id.rb +50 -0
  118. data/lib/action_dispatch/middleware/server_timing.rb +78 -0
  119. data/lib/action_dispatch/middleware/session/abstract_store.rb +112 -0
  120. data/lib/action_dispatch/middleware/session/cache_store.rb +66 -0
  121. data/lib/action_dispatch/middleware/session/cookie_store.rb +129 -0
  122. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +34 -0
  123. data/lib/action_dispatch/middleware/show_exceptions.rb +88 -0
  124. data/lib/action_dispatch/middleware/ssl.rb +180 -0
  125. data/lib/action_dispatch/middleware/stack.rb +194 -0
  126. data/lib/action_dispatch/middleware/static.rb +192 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +62 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +35 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  141. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
  142. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +284 -0
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
  144. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  145. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  146. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  147. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  148. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  149. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  150. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  151. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  152. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  153. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +19 -0
  154. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +232 -0
  155. data/lib/action_dispatch/railtie.rb +77 -0
  156. data/lib/action_dispatch/request/session.rb +283 -0
  157. data/lib/action_dispatch/request/utils.rb +109 -0
  158. data/lib/action_dispatch/routing/endpoint.rb +19 -0
  159. data/lib/action_dispatch/routing/inspector.rb +323 -0
  160. data/lib/action_dispatch/routing/mapper.rb +2372 -0
  161. data/lib/action_dispatch/routing/polymorphic_routes.rb +363 -0
  162. data/lib/action_dispatch/routing/redirection.rb +218 -0
  163. data/lib/action_dispatch/routing/route_set.rb +958 -0
  164. data/lib/action_dispatch/routing/routes_proxy.rb +66 -0
  165. data/lib/action_dispatch/routing/url_for.rb +244 -0
  166. data/lib/action_dispatch/routing.rb +262 -0
  167. data/lib/action_dispatch/system_test_case.rb +206 -0
  168. data/lib/action_dispatch/system_testing/browser.rb +75 -0
  169. data/lib/action_dispatch/system_testing/driver.rb +85 -0
  170. data/lib/action_dispatch/system_testing/server.rb +33 -0
  171. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
  172. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
  173. data/lib/action_dispatch/testing/assertion_response.rb +48 -0
  174. data/lib/action_dispatch/testing/assertions/response.rb +114 -0
  175. data/lib/action_dispatch/testing/assertions/routing.rb +343 -0
  176. data/lib/action_dispatch/testing/assertions.rb +25 -0
  177. data/lib/action_dispatch/testing/integration.rb +694 -0
  178. data/lib/action_dispatch/testing/request_encoder.rb +60 -0
  179. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  180. data/lib/action_dispatch/testing/test_process.rb +57 -0
  181. data/lib/action_dispatch/testing/test_request.rb +73 -0
  182. data/lib/action_dispatch/testing/test_response.rb +58 -0
  183. data/lib/action_dispatch.rb +147 -0
  184. data/lib/action_pack/gem_version.rb +19 -0
  185. data/lib/action_pack/version.rb +12 -0
  186. data/lib/action_pack.rb +27 -0
  187. 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