actionpack 6.0.4.7 → 6.1.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +235 -331
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/abstract_controller/base.rb +35 -2
  6. data/lib/abstract_controller/callbacks.rb +2 -2
  7. data/lib/abstract_controller/helpers.rb +105 -90
  8. data/lib/abstract_controller/rendering.rb +9 -9
  9. data/lib/abstract_controller/translation.rb +8 -2
  10. data/lib/abstract_controller.rb +1 -0
  11. data/lib/action_controller/api.rb +2 -2
  12. data/lib/action_controller/base.rb +4 -2
  13. data/lib/action_controller/caching.rb +0 -1
  14. data/lib/action_controller/log_subscriber.rb +3 -3
  15. data/lib/action_controller/metal/conditional_get.rb +10 -2
  16. data/lib/action_controller/metal/content_security_policy.rb +1 -1
  17. data/lib/action_controller/metal/data_streaming.rb +1 -1
  18. data/lib/action_controller/metal/etag_with_template_digest.rb +2 -4
  19. data/lib/action_controller/metal/exceptions.rb +33 -0
  20. data/lib/action_controller/metal/feature_policy.rb +46 -0
  21. data/lib/action_controller/metal/head.rb +7 -4
  22. data/lib/action_controller/metal/helpers.rb +11 -1
  23. data/lib/action_controller/metal/http_authentication.rb +5 -3
  24. data/lib/action_controller/metal/implicit_render.rb +1 -1
  25. data/lib/action_controller/metal/instrumentation.rb +11 -9
  26. data/lib/action_controller/metal/live.rb +1 -1
  27. data/lib/action_controller/metal/logging.rb +20 -0
  28. data/lib/action_controller/metal/mime_responds.rb +6 -2
  29. data/lib/action_controller/metal/parameter_encoding.rb +35 -4
  30. data/lib/action_controller/metal/params_wrapper.rb +16 -11
  31. data/lib/action_controller/metal/redirecting.rb +1 -1
  32. data/lib/action_controller/metal/rendering.rb +6 -0
  33. data/lib/action_controller/metal/request_forgery_protection.rb +1 -1
  34. data/lib/action_controller/metal/rescue.rb +1 -1
  35. data/lib/action_controller/metal/strong_parameters.rb +103 -15
  36. data/lib/action_controller/metal.rb +2 -2
  37. data/lib/action_controller/renderer.rb +24 -13
  38. data/lib/action_controller/test_case.rb +62 -56
  39. data/lib/action_controller.rb +2 -3
  40. data/lib/action_dispatch/http/cache.rb +12 -10
  41. data/lib/action_dispatch/http/content_security_policy.rb +5 -1
  42. data/lib/action_dispatch/http/feature_policy.rb +168 -0
  43. data/lib/action_dispatch/http/filter_parameters.rb +1 -1
  44. data/lib/action_dispatch/http/filter_redirect.rb +1 -1
  45. data/lib/action_dispatch/http/headers.rb +3 -2
  46. data/lib/action_dispatch/http/mime_negotiation.rb +14 -8
  47. data/lib/action_dispatch/http/mime_type.rb +29 -16
  48. data/lib/action_dispatch/http/parameters.rb +1 -19
  49. data/lib/action_dispatch/http/request.rb +24 -8
  50. data/lib/action_dispatch/http/response.rb +17 -16
  51. data/lib/action_dispatch/http/url.rb +3 -2
  52. data/lib/action_dispatch/journey/formatter.rb +53 -28
  53. data/lib/action_dispatch/journey/gtg/builder.rb +22 -36
  54. data/lib/action_dispatch/journey/gtg/simulator.rb +8 -7
  55. data/lib/action_dispatch/journey/gtg/transition_table.rb +6 -4
  56. data/lib/action_dispatch/journey/nfa/dot.rb +0 -11
  57. data/lib/action_dispatch/journey/nodes/node.rb +4 -3
  58. data/lib/action_dispatch/journey/parser.rb +13 -13
  59. data/lib/action_dispatch/journey/parser.y +1 -1
  60. data/lib/action_dispatch/journey/path/pattern.rb +13 -18
  61. data/lib/action_dispatch/journey/route.rb +7 -18
  62. data/lib/action_dispatch/journey/router/utils.rb +6 -4
  63. data/lib/action_dispatch/journey/router.rb +26 -30
  64. data/lib/action_dispatch/journey.rb +0 -2
  65. data/lib/action_dispatch/middleware/actionable_exceptions.rb +1 -1
  66. data/lib/action_dispatch/middleware/cookies.rb +67 -32
  67. data/lib/action_dispatch/middleware/debug_exceptions.rb +8 -15
  68. data/lib/action_dispatch/middleware/debug_view.rb +1 -1
  69. data/lib/action_dispatch/middleware/exception_wrapper.rb +28 -16
  70. data/lib/action_dispatch/middleware/executor.rb +1 -1
  71. data/lib/action_dispatch/middleware/host_authorization.rb +35 -35
  72. data/lib/action_dispatch/middleware/remote_ip.rb +5 -4
  73. data/lib/action_dispatch/middleware/request_id.rb +4 -5
  74. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -2
  75. data/lib/action_dispatch/middleware/session/cookie_store.rb +2 -2
  76. data/lib/action_dispatch/middleware/ssl.rb +9 -6
  77. data/lib/action_dispatch/middleware/stack.rb +18 -0
  78. data/lib/action_dispatch/middleware/static.rb +154 -93
  79. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +18 -0
  80. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +2 -5
  81. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +2 -2
  82. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +2 -3
  83. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +88 -8
  84. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  85. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +12 -1
  86. data/lib/action_dispatch/railtie.rb +3 -2
  87. data/lib/action_dispatch/request/session.rb +2 -8
  88. data/lib/action_dispatch/request/utils.rb +26 -2
  89. data/lib/action_dispatch/routing/inspector.rb +8 -7
  90. data/lib/action_dispatch/routing/mapper.rb +102 -71
  91. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -19
  92. data/lib/action_dispatch/routing/redirection.rb +3 -3
  93. data/lib/action_dispatch/routing/route_set.rb +49 -41
  94. data/lib/action_dispatch/system_test_case.rb +29 -24
  95. data/lib/action_dispatch/system_testing/browser.rb +33 -27
  96. data/lib/action_dispatch/system_testing/driver.rb +6 -7
  97. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +47 -6
  98. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +4 -7
  99. data/lib/action_dispatch/testing/assertions/response.rb +2 -4
  100. data/lib/action_dispatch/testing/assertions/routing.rb +5 -5
  101. data/lib/action_dispatch/testing/assertions.rb +1 -1
  102. data/lib/action_dispatch/testing/integration.rb +38 -27
  103. data/lib/action_dispatch/testing/test_process.rb +29 -4
  104. data/lib/action_dispatch/testing/test_request.rb +3 -3
  105. data/lib/action_dispatch.rb +3 -2
  106. data/lib/action_pack/gem_version.rb +3 -3
  107. data/lib/action_pack.rb +1 -1
  108. metadata +23 -24
  109. data/lib/action_controller/metal/force_ssl.rb +0 -58
  110. data/lib/action_dispatch/http/parameter_filter.rb +0 -12
  111. data/lib/action_dispatch/journey/nfa/builder.rb +0 -78
  112. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  113. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -119
@@ -0,0 +1,18 @@
1
+ <% if exception.respond_to?(:original_message) && exception.respond_to?(:corrections) %>
2
+ <h2><%= h exception.original_message %></h2>
3
+ <%
4
+ # The 'did_you_mean' gem can raise exceptions when calling #corrections on
5
+ # the exception. If it does there are no corrections to show.
6
+ corrections = exception.corrections rescue []
7
+ %>
8
+ <% if corrections.any? %>
9
+ <b>Did you mean?</b>
10
+ <ul>
11
+ <% corrections.each do |correction| %>
12
+ <li style="list-style-type: none"><%= h correction %></li>
13
+ <% end %>
14
+ </ul>
15
+ <% end %>
16
+ <% else %>
17
+ <h2><%= h exception.message %></h2>
18
+ <% end %>
@@ -8,11 +8,8 @@
8
8
  </header>
9
9
 
10
10
  <div id="container">
11
- <h2>
12
- <%= h @exception.message %>
13
-
14
- <%= render "rescues/actions", exception: @exception, request: @request %>
15
- </h2>
11
+ <%= render "rescues/message_and_suggestions", exception: @exception %>
12
+ <%= render "rescues/actions", exception: @exception, request: @request %>
16
13
 
17
14
  <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx, error_index: 0 %>
18
15
  <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show, error_index: 0 %>
@@ -11,10 +11,10 @@
11
11
  <h2>
12
12
  <%= h @exception.message %>
13
13
  <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
14
- <br />To resolve this issue run: rails active_storage:install
14
+ <br />To resolve this issue run: bin/rails active_storage:install
15
15
  <% end %>
16
16
  <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
17
- <br />To resolve this issue run: rails action_mailbox:install
17
+ <br />To resolve this issue run: bin/rails action_mailbox:install
18
18
  <% end %>
19
19
  </h2>
20
20
 
@@ -5,10 +5,9 @@
5
5
 
6
6
  <%= @exception.message %>
7
7
  <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
8
- To resolve this issue run: rails active_storage:install
9
- <% end %>
8
+ To resolve this issue run: bin/rails active_storage:install
10
9
  <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
11
- To resolve this issue run: rails action_mailbox:install
10
+ To resolve this issue run: bin/rails action_mailbox:install
12
11
  <% end %>
13
12
 
14
13
  <%= render template: "rescues/_source" %>
@@ -2,11 +2,14 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
6
  <title>Action Controller: Exception caught</title>
6
7
  <style>
7
8
  body {
8
9
  background-color: #FAFAFA;
9
10
  color: #333;
11
+ color-scheme: light dark;
12
+ supported-color-schemes: light dark;
10
13
  margin: 0px;
11
14
  }
12
15
 
@@ -30,18 +33,19 @@
30
33
 
31
34
  header {
32
35
  color: #F0F0F0;
33
- background: #C52F24;
36
+ background: #C00;
34
37
  padding: 0.5em 1.5em;
35
38
  }
36
39
 
37
40
  h1 {
41
+ overflow-wrap: break-word;
38
42
  margin: 0.2em 0;
39
43
  line-height: 1.1em;
40
44
  font-size: 2em;
41
45
  }
42
46
 
43
47
  h2 {
44
- color: #C52F24;
48
+ color: #C00;
45
49
  line-height: 25px;
46
50
  }
47
51
 
@@ -50,7 +54,7 @@
50
54
  border-radius: 4px;
51
55
  margin: 1em 0px;
52
56
  display: block;
53
- width: 978px;
57
+ max-width: 978px;
54
58
  }
55
59
 
56
60
  .summary {
@@ -78,7 +82,7 @@
78
82
  .source {
79
83
  border: 1px solid #D9D9D9;
80
84
  background: #ECECEC;
81
- width: 978px;
85
+ max-width: 978px;
82
86
  }
83
87
 
84
88
  .source pre {
@@ -114,22 +118,98 @@
114
118
  }
115
119
 
116
120
  .line.active {
117
- background-color: #FFCCCC;
121
+ background-color: #FCC;
118
122
  }
119
123
 
120
124
  .button_to {
121
125
  display: inline-block;
126
+ margin-top: 0.75em;
127
+ margin-bottom: 0.75em;
122
128
  }
123
129
 
124
130
  .hidden {
125
131
  display: none;
126
132
  }
127
133
 
134
+ input[type="submit"] {
135
+ color: white;
136
+ background-color: #C00;
137
+ border: none;
138
+ border-radius: 12px;
139
+ box-shadow: 0 3px #F99;
140
+ font-size: 13px;
141
+ font-weight: bold;
142
+ margin: 0;
143
+ padding: 10px 18px;
144
+ -webkit-appearance: none;
145
+ }
146
+ input[type="submit"]:focus,
147
+ input[type="submit"]:hover {
148
+ opacity: 0.8;
149
+ }
150
+ input[type="submit"]:active {
151
+ box-shadow: 0 2px #F99;
152
+ transform: translateY(1px)
153
+ }
154
+
155
+
128
156
  a { color: #980905; }
129
157
  a:visited { color: #666; }
130
- a.trace-frames { color: #666; }
131
- a:hover { color: #C52F24; }
132
- a.trace-frames.selected { color: #C52F24 }
158
+ a.trace-frames {
159
+ color: #666;
160
+ overflow-wrap: break-word;
161
+ }
162
+ a:hover { color: #C00; }
163
+ a.trace-frames.selected { color: #C00 }
164
+
165
+ @media (prefers-color-scheme: dark) {
166
+ body {
167
+ background-color: #222;
168
+ color: #ECECEC;
169
+ }
170
+
171
+ .details {
172
+ border-color: #666;
173
+ }
174
+
175
+ .summary {
176
+ border-color: #666;
177
+ }
178
+
179
+ .source {
180
+ border-color: #555;
181
+ background-color: #333;
182
+ }
183
+
184
+ .source .data {
185
+ background: #444;
186
+ }
187
+
188
+ .source .data .line_numbers {
189
+ background: #333;
190
+ border-color: #222;
191
+ }
192
+
193
+ .line:hover {
194
+ background: #666;
195
+ }
196
+
197
+ .line.active {
198
+ background-color: #900;
199
+ }
200
+
201
+ input[type="submit"] {
202
+ box-shadow: 0 3px #800;
203
+ }
204
+ input[type="submit"]:active {
205
+ box-shadow: 0 2px #800;
206
+ }
207
+
208
+ a { color: #C00; }
209
+ a.trace-frames { color: #999; }
210
+ a:hover { color: #E9382B; }
211
+ a.trace-frames.selected { color: #E9382B; }
212
+ }
133
213
 
134
214
  <%= yield :style %>
135
215
  </style>
@@ -2,5 +2,5 @@
2
2
  <h1>Unknown action</h1>
3
3
  </header>
4
4
  <div id="container">
5
- <h2><%= h @exception.message %></h2>
5
+ <%= render "rescues/message_and_suggestions", exception: @exception %>
6
6
  </div>
@@ -49,6 +49,17 @@
49
49
  width: 80%;
50
50
  font-size: inherit;
51
51
  }
52
+
53
+ @media (prefers-color-scheme: dark) {
54
+ #route_table tbody tr:nth-child(odd) {
55
+ background: #333;
56
+ }
57
+
58
+ #route_table tbody.exact_matches,
59
+ #route_table tbody.fuzzy_matches {
60
+ color: #333;
61
+ }
62
+ }
52
63
  <% end %>
53
64
 
54
65
  <table id='route_table' class='route_table'>
@@ -85,7 +96,7 @@
85
96
  </table>
86
97
 
87
98
  <script type='text/javascript'>
88
- // support forEarch iterator on NodeList
99
+ // support forEach iterator on NodeList
89
100
  NodeList.prototype.forEach = Array.prototype.forEach;
90
101
 
91
102
  // Enables path search functionality
@@ -23,7 +23,7 @@ module ActionDispatch
23
23
  config.action_dispatch.use_authenticated_cookie_encryption = false
24
24
  config.action_dispatch.use_cookies_with_metadata = false
25
25
  config.action_dispatch.perform_deep_munge = true
26
- config.action_dispatch.return_only_media_type_on_content_type = true
26
+ config.action_dispatch.request_id_header = "X-Request-Id"
27
27
 
28
28
  config.action_dispatch.default_headers = {
29
29
  "X-Frame-Options" => "SAMEORIGIN",
@@ -39,13 +39,14 @@ module ActionDispatch
39
39
  config.eager_load_namespaces << ActionDispatch
40
40
 
41
41
  initializer "action_dispatch.configure" do |app|
42
+ ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
42
43
  ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
43
44
  ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
44
45
  ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
46
+
45
47
  ActiveSupport.on_load(:action_dispatch_response) do
46
48
  self.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
47
49
  self.default_headers = app.config.action_dispatch.default_headers
48
- self.return_only_media_type_on_content_type = app.config.action_dispatch.return_only_media_type_on_content_type
49
50
  end
50
51
 
51
52
  ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
@@ -158,7 +158,7 @@ module ActionDispatch
158
158
  # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
159
159
  def update(hash)
160
160
  load_for_write!
161
- @delegate.update stringify_keys(hash)
161
+ @delegate.update hash.stringify_keys
162
162
  end
163
163
 
164
164
  # Deletes given key from the session.
@@ -233,15 +233,9 @@ module ActionDispatch
233
233
  def load!
234
234
  id, session = @by.load_session @req
235
235
  options[:id] = id
236
- @delegate.replace(stringify_keys(session))
236
+ @delegate.replace(session.stringify_keys)
237
237
  @loaded = true
238
238
  end
239
-
240
- def stringify_keys(other)
241
- other.each_with_object({}) { |(key, value), hash|
242
- hash[key.to_s] = value
243
- }
244
- end
245
239
  end
246
240
  end
247
241
  end
@@ -41,6 +41,10 @@ module ActionDispatch
41
41
  end
42
42
  end
43
43
 
44
+ def self.set_binary_encoding(request, params, controller, action)
45
+ CustomParamEncoder.encode(request, params, controller, action)
46
+ end
47
+
44
48
  class ParamEncoder # :nodoc:
45
49
  # Convert nested Hash to HashWithIndifferentAccess.
46
50
  def self.normalize_encode_params(params)
@@ -51,8 +55,8 @@ module ActionDispatch
51
55
  if params.has_key?(:tempfile)
52
56
  ActionDispatch::Http::UploadedFile.new(params)
53
57
  else
54
- params.each_with_object({}) do |(key, val), new_hash|
55
- new_hash[key] = normalize_encode_params(val)
58
+ params.transform_values do |val|
59
+ normalize_encode_params(val)
56
60
  end.with_indifferent_access
57
61
  end
58
62
  else
@@ -73,6 +77,26 @@ module ActionDispatch
73
77
  list
74
78
  end
75
79
  end
80
+
81
+ class CustomParamEncoder # :nodoc:
82
+ def self.encode(request, params, controller, action)
83
+ return params unless controller && controller.valid_encoding? && encoding_template = action_encoding_template(request, controller, action)
84
+ params.except(:controller, :action).each do |key, value|
85
+ ActionDispatch::Request::Utils.each_param_value(value) do |param|
86
+ if encoding_template[key.to_s]
87
+ param.force_encoding(encoding_template[key.to_s])
88
+ end
89
+ end
90
+ end
91
+ params
92
+ end
93
+
94
+ def self.action_encoding_template(request, controller, action) # :nodoc:
95
+ request.controller_class_for(controller).action_encoding_template(action)
96
+ rescue MissingController
97
+ nil
98
+ end
99
+ end
76
100
  end
77
101
  end
78
102
  end
@@ -53,7 +53,7 @@ module ActionDispatch
53
53
 
54
54
  ##
55
55
  # This class is just used for displaying route information when someone
56
- # executes `rails routes` or looks at the RoutingError page.
56
+ # executes `bin/rails routes` or looks at the RoutingError page.
57
57
  # People should not use this class.
58
58
  class RoutesInspector # :nodoc:
59
59
  def initialize(routes)
@@ -94,7 +94,7 @@ module ActionDispatch
94
94
  if filter
95
95
  @routes.select do |route|
96
96
  route_wrapper = RouteWrapper.new(route)
97
- filter.any? { |default, value| route_wrapper.send(default) =~ value }
97
+ filter.any? { |default, value| value.match?(route_wrapper.send(default)) }
98
98
  end
99
99
  else
100
100
  @routes
@@ -200,6 +200,11 @@ module ActionDispatch
200
200
  end
201
201
 
202
202
  class Expanded < Base
203
+ def initialize(width: IO.console_size[1])
204
+ @width = width
205
+ super()
206
+ end
207
+
203
208
  def section_title(title)
204
209
  @buffer << "\n#{"[ #{title} ]"}"
205
210
  end
@@ -222,11 +227,7 @@ module ActionDispatch
222
227
  end
223
228
 
224
229
  def route_header(index:)
225
- console_width = IO.console_size.second
226
- header_prefix = "--[ Route #{index} ]"
227
- dash_remainder = [console_width - header_prefix.size, 0].max
228
-
229
- "#{header_prefix}#{'-' * dash_remainder}"
230
+ "--[ Route #{index} ]".ljust(@width, "-")
230
231
  end
231
232
  end
232
233
  end