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.

Files changed (202) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +86 -600
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -14
  5. data/lib/abstract_controller/asset_paths.rb +5 -1
  6. data/lib/abstract_controller/base.rb +166 -136
  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 +126 -57
  10. data/lib/abstract_controller/collector.rb +13 -15
  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 +181 -132
  14. data/lib/abstract_controller/logger.rb +5 -1
  15. data/lib/abstract_controller/railties/routes_helpers.rb +10 -3
  16. data/lib/abstract_controller/rendering.rb +56 -56
  17. data/lib/abstract_controller/translation.rb +29 -15
  18. data/lib/abstract_controller/url_for.rb +15 -11
  19. data/lib/abstract_controller.rb +21 -5
  20. data/lib/action_controller/api/api_rendering.rb +18 -0
  21. data/lib/action_controller/api.rb +154 -0
  22. data/lib/action_controller/base.rb +219 -155
  23. data/lib/action_controller/caching.rb +28 -68
  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 +35 -22
  27. data/lib/action_controller/metal/allow_browser.rb +119 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
  29. data/lib/action_controller/metal/conditional_get.rb +259 -122
  30. data/lib/action_controller/metal/content_security_policy.rb +86 -0
  31. data/lib/action_controller/metal/cookies.rb +9 -5
  32. data/lib/action_controller/metal/data_streaming.rb +87 -104
  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 +35 -26
  36. data/lib/action_controller/metal/exceptions.rb +71 -24
  37. data/lib/action_controller/metal/flash.rb +26 -19
  38. data/lib/action_controller/metal/head.rb +45 -36
  39. data/lib/action_controller/metal/helpers.rb +80 -64
  40. data/lib/action_controller/metal/http_authentication.rb +297 -244
  41. data/lib/action_controller/metal/implicit_render.rb +57 -9
  42. data/lib/action_controller/metal/instrumentation.rb +76 -64
  43. data/lib/action_controller/metal/live.rb +238 -176
  44. data/lib/action_controller/metal/logging.rb +22 -0
  45. data/lib/action_controller/metal/mime_responds.rb +177 -166
  46. data/lib/action_controller/metal/parameter_encoding.rb +84 -0
  47. data/lib/action_controller/metal/params_wrapper.rb +145 -118
  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 +203 -64
  51. data/lib/action_controller/metal/renderers.rb +108 -65
  52. data/lib/action_controller/metal/rendering.rb +216 -56
  53. data/lib/action_controller/metal/request_forgery_protection.rb +496 -163
  54. data/lib/action_controller/metal/rescue.rb +19 -21
  55. data/lib/action_controller/metal/streaming.rb +179 -138
  56. data/lib/action_controller/metal/strong_parameters.rb +1058 -382
  57. data/lib/action_controller/metal/testing.rb +11 -17
  58. data/lib/action_controller/metal/url_for.rb +37 -21
  59. data/lib/action_controller/metal.rb +236 -138
  60. data/lib/action_controller/railtie.rb +89 -11
  61. data/lib/action_controller/railties/helpers.rb +5 -1
  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 +425 -497
  65. data/lib/action_controller.rb +44 -22
  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 +119 -63
  69. data/lib/action_dispatch/http/content_disposition.rb +47 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +364 -0
  71. data/lib/action_dispatch/http/filter_parameters.rb +36 -34
  72. data/lib/action_dispatch/http/filter_redirect.rb +24 -12
  73. data/lib/action_dispatch/http/headers.rb +66 -31
  74. data/lib/action_dispatch/http/mime_negotiation.rb +106 -75
  75. data/lib/action_dispatch/http/mime_type.rb +196 -136
  76. data/lib/action_dispatch/http/mime_types.rb +25 -7
  77. data/lib/action_dispatch/http/parameters.rb +97 -45
  78. data/lib/action_dispatch/http/permissions_policy.rb +187 -0
  79. data/lib/action_dispatch/http/rack_cache.rb +6 -0
  80. data/lib/action_dispatch/http/request.rb +299 -170
  81. data/lib/action_dispatch/http/response.rb +311 -160
  82. data/lib/action_dispatch/http/upload.rb +52 -23
  83. data/lib/action_dispatch/http/url.rb +201 -125
  84. data/lib/action_dispatch/journey/formatter.rb +110 -50
  85. data/lib/action_dispatch/journey/gtg/builder.rb +37 -50
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +20 -17
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +96 -36
  88. data/lib/action_dispatch/journey/nfa/dot.rb +5 -14
  89. data/lib/action_dispatch/journey/nodes/node.rb +100 -20
  90. data/lib/action_dispatch/journey/parser.rb +19 -17
  91. data/lib/action_dispatch/journey/parser.y +4 -3
  92. data/lib/action_dispatch/journey/parser_extras.rb +14 -4
  93. data/lib/action_dispatch/journey/path/pattern.rb +79 -63
  94. data/lib/action_dispatch/journey/route.rb +108 -44
  95. data/lib/action_dispatch/journey/router/utils.rb +41 -29
  96. data/lib/action_dispatch/journey/router.rb +64 -57
  97. data/lib/action_dispatch/journey/routes.rb +23 -21
  98. data/lib/action_dispatch/journey/scanner.rb +28 -17
  99. data/lib/action_dispatch/journey/visitors.rb +100 -54
  100. data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
  101. data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
  102. data/lib/action_dispatch/journey.rb +7 -5
  103. data/lib/action_dispatch/log_subscriber.rb +25 -0
  104. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  105. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  106. data/lib/action_dispatch/middleware/callbacks.rb +7 -6
  107. data/lib/action_dispatch/middleware/cookies.rb +471 -328
  108. data/lib/action_dispatch/middleware/debug_exceptions.rb +149 -66
  109. data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
  110. data/lib/action_dispatch/middleware/debug_view.rb +73 -0
  111. data/lib/action_dispatch/middleware/exception_wrapper.rb +275 -73
  112. data/lib/action_dispatch/middleware/executor.rb +32 -0
  113. data/lib/action_dispatch/middleware/flash.rb +143 -101
  114. data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
  115. data/lib/action_dispatch/middleware/public_exceptions.rb +36 -27
  116. data/lib/action_dispatch/middleware/reloader.rb +10 -92
  117. data/lib/action_dispatch/middleware/remote_ip.rb +133 -107
  118. data/lib/action_dispatch/middleware/request_id.rb +29 -15
  119. data/lib/action_dispatch/middleware/server_timing.rb +78 -0
  120. data/lib/action_dispatch/middleware/session/abstract_store.rb +49 -27
  121. data/lib/action_dispatch/middleware/session/cache_store.rb +33 -16
  122. data/lib/action_dispatch/middleware/session/cookie_store.rb +86 -80
  123. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -3
  124. data/lib/action_dispatch/middleware/show_exceptions.rb +66 -36
  125. data/lib/action_dispatch/middleware/ssl.rb +134 -36
  126. data/lib/action_dispatch/middleware/stack.rb +109 -44
  127. data/lib/action_dispatch/middleware/static.rb +159 -90
  128. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +7 -24
  132. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +46 -36
  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 +26 -7
  139. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +3 -3
  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 +139 -15
  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 +6 -6
  146. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +7 -7
  147. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +9 -9
  148. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  149. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
  150. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  151. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +7 -4
  152. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +125 -93
  153. data/lib/action_dispatch/railtie.rb +44 -16
  154. data/lib/action_dispatch/request/session.rb +159 -69
  155. data/lib/action_dispatch/request/utils.rb +97 -23
  156. data/lib/action_dispatch/routing/endpoint.rb +11 -2
  157. data/lib/action_dispatch/routing/inspector.rb +195 -106
  158. data/lib/action_dispatch/routing/mapper.rb +1338 -955
  159. data/lib/action_dispatch/routing/polymorphic_routes.rb +234 -201
  160. data/lib/action_dispatch/routing/redirection.rb +78 -51
  161. data/lib/action_dispatch/routing/route_set.rb +460 -374
  162. data/lib/action_dispatch/routing/routes_proxy.rb +36 -12
  163. data/lib/action_dispatch/routing/url_for.rb +172 -124
  164. data/lib/action_dispatch/routing.rb +159 -158
  165. data/lib/action_dispatch/system_test_case.rb +206 -0
  166. data/lib/action_dispatch/system_testing/browser.rb +84 -0
  167. data/lib/action_dispatch/system_testing/driver.rb +85 -0
  168. data/lib/action_dispatch/system_testing/server.rb +33 -0
  169. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
  170. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
  171. data/lib/action_dispatch/testing/assertion_response.rb +48 -0
  172. data/lib/action_dispatch/testing/assertions/response.rb +71 -39
  173. data/lib/action_dispatch/testing/assertions/routing.rb +228 -103
  174. data/lib/action_dispatch/testing/assertions.rb +9 -6
  175. data/lib/action_dispatch/testing/integration.rb +486 -306
  176. data/lib/action_dispatch/testing/request_encoder.rb +60 -0
  177. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  178. data/lib/action_dispatch/testing/test_process.rb +35 -22
  179. data/lib/action_dispatch/testing/test_request.rb +29 -34
  180. data/lib/action_dispatch/testing/test_response.rb +48 -15
  181. data/lib/action_dispatch.rb +82 -40
  182. data/lib/action_pack/gem_version.rb +8 -4
  183. data/lib/action_pack/version.rb +6 -2
  184. data/lib/action_pack.rb +21 -18
  185. metadata +146 -56
  186. data/lib/action_controller/caching/fragments.rb +0 -103
  187. data/lib/action_controller/metal/force_ssl.rb +0 -97
  188. data/lib/action_controller/metal/hide_actions.rb +0 -40
  189. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  190. data/lib/action_controller/middleware.rb +0 -39
  191. data/lib/action_controller/model_naming.rb +0 -12
  192. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  193. data/lib/action_dispatch/journey/backwards.rb +0 -5
  194. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  195. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  196. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  197. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  199. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +0 -27
  200. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  201. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  202. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,9 +1,11 @@
1
- require 'action_dispatch/http/request'
2
- require 'active_support/core_ext/uri'
3
- require 'active_support/core_ext/array/extract_options'
4
- require 'rack/utils'
5
- require 'action_controller/metal/exceptions'
6
- require 'action_dispatch/routing/endpoint'
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "active_support/core_ext/array/extract_options"
6
+ require "rack/utils"
7
+ require "action_controller/metal/exceptions"
8
+ require "action_dispatch/routing/endpoint"
7
9
 
8
10
  module ActionDispatch
9
11
  module Routing
@@ -18,13 +20,21 @@ module ActionDispatch
18
20
  def redirect?; true; end
19
21
 
20
22
  def call(env)
21
- serve Request.new env
23
+ ActiveSupport::Notifications.instrument("redirect.action_dispatch") do |payload|
24
+ request = Request.new(env)
25
+ response = build_response(request)
26
+
27
+ payload[:status] = @status
28
+ payload[:location] = response.headers["Location"]
29
+ payload[:request] = request
30
+
31
+ response.to_a
32
+ end
22
33
  end
23
34
 
24
- def serve(req)
25
- req.check_path_parameters!
35
+ def build_response(req)
26
36
  uri = URI.parse(path(req.path_parameters, req))
27
-
37
+
28
38
  unless uri.host
29
39
  if relative_path?(uri.path)
30
40
  uri.path = "#{req.script_name}/#{uri.path}"
@@ -32,20 +42,22 @@ module ActionDispatch
32
42
  uri.path = req.script_name.empty? ? "/" : req.script_name
33
43
  end
34
44
  end
35
-
45
+
36
46
  uri.scheme ||= req.scheme
37
47
  uri.host ||= req.host
38
48
  uri.port ||= req.port unless req.standard_port?
39
49
 
40
- body = %(<html><body>You are being <a href="#{ERB::Util.unwrapped_html_escape(uri.to_s)}">redirected</a>.</body></html>)
50
+ req.commit_flash
51
+
52
+ body = ""
41
53
 
42
54
  headers = {
43
- 'Location' => uri.to_s,
44
- 'Content-Type' => 'text/html',
45
- 'Content-Length' => body.length.to_s
55
+ "Location" => uri.to_s,
56
+ "Content-Type" => "text/html; charset=#{ActionDispatch::Response.default_charset}",
57
+ "Content-Length" => body.length.to_s
46
58
  }
47
59
 
48
- [ status, headers, [body] ]
60
+ ActionDispatch::Response.new(status, headers, body)
49
61
  end
50
62
 
51
63
  def path(params, request)
@@ -58,19 +70,19 @@ module ActionDispatch
58
70
 
59
71
  private
60
72
  def relative_path?(path)
61
- path && !path.empty? && path[0] != '/'
73
+ path && !path.empty? && !path.start_with?("/")
62
74
  end
63
75
 
64
76
  def escape(params)
65
- Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }]
77
+ params.transform_values { |v| Rack::Utils.escape(v) }
66
78
  end
67
79
 
68
80
  def escape_fragment(params)
69
- Hash[params.map{ |k,v| [k, Journey::Router::Utils.escape_fragment(v)] }]
81
+ params.transform_values { |v| Journey::Router::Utils.escape_fragment(v) }
70
82
  end
71
83
 
72
84
  def escape_path(params)
73
- Hash[params.map{ |k,v| [k, Journey::Router::Utils.escape_path(v)] }]
85
+ params.transform_values { |v| Journey::Router::Utils.escape_path(v) }
74
86
  end
75
87
  end
76
88
 
@@ -104,11 +116,11 @@ module ActionDispatch
104
116
 
105
117
  def path(params, request)
106
118
  url_options = {
107
- :protocol => request.protocol,
108
- :host => request.host,
109
- :port => request.optional_port,
110
- :path => request.path,
111
- :params => request.query_parameters
119
+ protocol: request.protocol,
120
+ host: request.host,
121
+ port: request.optional_port,
122
+ path: request.path,
123
+ params: request.query_parameters
112
124
  }.merge! options
113
125
 
114
126
  if !params.empty? && url_options[:path].match(/%\{\w*\}/)
@@ -124,55 +136,70 @@ module ActionDispatch
124
136
  url_options[:script_name] = request.script_name
125
137
  end
126
138
  end
127
-
139
+
128
140
  ActionDispatch::Http::URL.url_for url_options
129
141
  end
130
142
 
131
143
  def inspect
132
- "redirect(#{status}, #{options.map{ |k,v| "#{k}: #{v}" }.join(', ')})"
144
+ "redirect(#{status}, #{options.map { |k, v| "#{k}: #{v}" }.join(', ')})"
133
145
  end
134
146
  end
135
147
 
136
148
  module Redirection
137
-
138
149
  # Redirect any path to another path:
139
150
  #
140
- # get "/stories" => redirect("/posts")
151
+ # get "/stories" => redirect("/posts")
152
+ #
153
+ # This will redirect the user, while ignoring certain parts of the request,
154
+ # including query string, etc. `/stories`, `/stories?foo=bar`, etc all redirect
155
+ # to `/posts`.
156
+ #
157
+ # The redirect will use a `301 Moved Permanently` status code by default. This
158
+ # can be overridden with the `:status` option:
159
+ #
160
+ # get "/stories" => redirect("/posts", status: 307)
141
161
  #
142
162
  # You can also use interpolation in the supplied redirect argument:
143
163
  #
144
- # get 'docs/:article', to: redirect('/wiki/%{article}')
164
+ # get 'docs/:article', to: redirect('/wiki/%{article}')
145
165
  #
146
- # Note that if you return a path without a leading slash then the url is prefixed with the
147
- # current SCRIPT_NAME environment variable. This is typically '/' but may be different in
148
- # a mounted engine or where the application is deployed to a subdirectory of a website.
166
+ # Note that if you return a path without a leading slash then the URL is
167
+ # prefixed with the current SCRIPT_NAME environment variable. This is typically
168
+ # '/' but may be different in a mounted engine or where the application is
169
+ # deployed to a subdirectory of a website.
149
170
  #
150
171
  # Alternatively you can use one of the other syntaxes:
151
172
  #
152
- # The block version of redirect allows for the easy encapsulation of any logic associated with
153
- # the redirect in question. Either the params and request are supplied as arguments, or just
154
- # params, depending of how many arguments your block accepts. A string is required as a
155
- # return value.
173
+ # The block version of redirect allows for the easy encapsulation of any logic
174
+ # associated with the redirect in question. Either the params and request are
175
+ # supplied as arguments, or just params, depending of how many arguments your
176
+ # block accepts. A string is required as a return value.
177
+ #
178
+ # get 'jokes/:number', to: redirect { |params, request|
179
+ # path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp")
180
+ # "http://#{request.host_with_port}/#{path}"
181
+ # }
156
182
  #
157
- # get 'jokes/:number', to: redirect { |params, request|
158
- # path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp")
159
- # "http://#{request.host_with_port}/#{path}"
160
- # }
183
+ # Note that the `do end` syntax for the redirect block wouldn't work, as Ruby
184
+ # would pass the block to `get` instead of `redirect`. Use `{ ... }` instead.
161
185
  #
162
- # Note that the +do end+ syntax for the redirect block wouldn't work, as Ruby would pass
163
- # the block to +get+ instead of +redirect+. Use <tt>{ ... }</tt> instead.
186
+ # The options version of redirect allows you to supply only the parts of the URL
187
+ # which need to change, it also supports interpolation of the path similar to
188
+ # the first example.
164
189
  #
165
- # The options version of redirect allows you to supply only the parts of the url which need
166
- # to change, it also supports interpolation of the path similar to the first example.
190
+ # get 'stores/:name', to: redirect(subdomain: 'stores', path: '/%{name}')
191
+ # get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}')
192
+ # get '/stories', to: redirect(path: '/posts')
167
193
  #
168
- # get 'stores/:name', to: redirect(subdomain: 'stores', path: '/%{name}')
169
- # get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}')
194
+ # This will redirect the user, while changing only the specified parts of the
195
+ # request, for example the `path` option in the last example. `/stories`,
196
+ # `/stories?foo=bar`, redirect to `/posts` and `/posts?foo=bar` respectively.
170
197
  #
171
- # Finally, an object which responds to call can be supplied to redirect, allowing you to reuse
172
- # common redirect routes. The call method must accept two arguments, params and request, and return
173
- # a string.
198
+ # Finally, an object which responds to call can be supplied to redirect,
199
+ # allowing you to reuse common redirect routes. The call method must accept two
200
+ # arguments, params and request, and return a string.
174
201
  #
175
- # get 'accounts/:name' => redirect(SubdomainRedirector.new('api'))
202
+ # get 'accounts/:name' => redirect(SubdomainRedirector.new('api'))
176
203
  #
177
204
  def redirect(*args, &block)
178
205
  options = args.extract_options!