actionpack 5.2.0 → 6.1.4

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 (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +408 -190
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/abstract_controller/base.rb +38 -4
  6. data/lib/abstract_controller/caching/fragments.rb +6 -22
  7. data/lib/abstract_controller/caching.rb +1 -1
  8. data/lib/abstract_controller/callbacks.rb +14 -2
  9. data/lib/abstract_controller/collector.rb +1 -2
  10. data/lib/abstract_controller/helpers.rb +106 -90
  11. data/lib/abstract_controller/railties/routes_helpers.rb +17 -1
  12. data/lib/abstract_controller/rendering.rb +9 -9
  13. data/lib/abstract_controller/translation.rb +11 -5
  14. data/lib/abstract_controller.rb +2 -0
  15. data/lib/action_controller/api.rb +4 -3
  16. data/lib/action_controller/base.rb +6 -9
  17. data/lib/action_controller/caching.rb +1 -3
  18. data/lib/action_controller/log_subscriber.rb +10 -7
  19. data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
  20. data/lib/action_controller/metal/conditional_get.rb +19 -5
  21. data/lib/action_controller/metal/content_security_policy.rb +1 -2
  22. data/lib/action_controller/metal/cookies.rb +3 -1
  23. data/lib/action_controller/metal/data_streaming.rb +6 -7
  24. data/lib/action_controller/metal/default_headers.rb +17 -0
  25. data/lib/action_controller/metal/etag_with_template_digest.rb +4 -6
  26. data/lib/action_controller/metal/exceptions.rb +56 -2
  27. data/lib/action_controller/metal/flash.rb +5 -5
  28. data/lib/action_controller/metal/head.rb +7 -4
  29. data/lib/action_controller/metal/helpers.rb +14 -5
  30. data/lib/action_controller/metal/http_authentication.rb +25 -24
  31. data/lib/action_controller/metal/implicit_render.rb +5 -15
  32. data/lib/action_controller/metal/instrumentation.rb +13 -14
  33. data/lib/action_controller/metal/live.rb +39 -32
  34. data/lib/action_controller/metal/logging.rb +20 -0
  35. data/lib/action_controller/metal/mime_responds.rb +19 -4
  36. data/lib/action_controller/metal/parameter_encoding.rb +35 -4
  37. data/lib/action_controller/metal/params_wrapper.rb +33 -23
  38. data/lib/action_controller/metal/permissions_policy.rb +46 -0
  39. data/lib/action_controller/metal/redirecting.rb +7 -7
  40. data/lib/action_controller/metal/renderers.rb +4 -4
  41. data/lib/action_controller/metal/rendering.rb +8 -3
  42. data/lib/action_controller/metal/request_forgery_protection.rb +89 -36
  43. data/lib/action_controller/metal/rescue.rb +1 -1
  44. data/lib/action_controller/metal/streaming.rb +0 -1
  45. data/lib/action_controller/metal/strong_parameters.rb +181 -69
  46. data/lib/action_controller/metal/url_for.rb +1 -1
  47. data/lib/action_controller/metal.rb +12 -10
  48. data/lib/action_controller/railties/helpers.rb +1 -1
  49. data/lib/action_controller/renderer.rb +37 -13
  50. data/lib/action_controller/template_assertions.rb +1 -1
  51. data/lib/action_controller/test_case.rb +81 -70
  52. data/lib/action_controller.rb +7 -4
  53. data/lib/action_dispatch/http/cache.rb +34 -28
  54. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  55. data/lib/action_dispatch/http/content_security_policy.rb +47 -24
  56. data/lib/action_dispatch/http/filter_parameters.rb +9 -8
  57. data/lib/action_dispatch/http/filter_redirect.rb +2 -3
  58. data/lib/action_dispatch/http/headers.rb +4 -4
  59. data/lib/action_dispatch/http/mime_negotiation.rb +31 -13
  60. data/lib/action_dispatch/http/mime_type.rb +43 -24
  61. data/lib/action_dispatch/http/parameters.rb +14 -23
  62. data/lib/action_dispatch/http/permissions_policy.rb +173 -0
  63. data/lib/action_dispatch/http/request.rb +45 -22
  64. data/lib/action_dispatch/http/response.rb +45 -25
  65. data/lib/action_dispatch/http/upload.rb +9 -1
  66. data/lib/action_dispatch/http/url.rb +82 -82
  67. data/lib/action_dispatch/journey/formatter.rb +55 -31
  68. data/lib/action_dispatch/journey/gtg/builder.rb +22 -37
  69. data/lib/action_dispatch/journey/gtg/simulator.rb +8 -7
  70. data/lib/action_dispatch/journey/gtg/transition_table.rb +6 -5
  71. data/lib/action_dispatch/journey/nfa/dot.rb +0 -11
  72. data/lib/action_dispatch/journey/nodes/node.rb +13 -11
  73. data/lib/action_dispatch/journey/parser.rb +13 -13
  74. data/lib/action_dispatch/journey/parser.y +1 -1
  75. data/lib/action_dispatch/journey/path/pattern.rb +21 -22
  76. data/lib/action_dispatch/journey/route.rb +10 -20
  77. data/lib/action_dispatch/journey/router/utils.rb +14 -12
  78. data/lib/action_dispatch/journey/router.rb +26 -34
  79. data/lib/action_dispatch/journey/routes.rb +1 -2
  80. data/lib/action_dispatch/journey/scanner.rb +10 -4
  81. data/lib/action_dispatch/journey/visitors.rb +1 -4
  82. data/lib/action_dispatch/journey.rb +0 -2
  83. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  84. data/lib/action_dispatch/middleware/callbacks.rb +2 -4
  85. data/lib/action_dispatch/middleware/cookies.rb +128 -109
  86. data/lib/action_dispatch/middleware/debug_exceptions.rb +43 -66
  87. data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
  88. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  89. data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -30
  90. data/lib/action_dispatch/middleware/flash.rb +2 -2
  91. data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
  92. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
  93. data/lib/action_dispatch/middleware/remote_ip.rb +14 -16
  94. data/lib/action_dispatch/middleware/request_id.rb +5 -6
  95. data/lib/action_dispatch/middleware/session/abstract_store.rb +15 -2
  96. data/lib/action_dispatch/middleware/session/cache_store.rb +11 -6
  97. data/lib/action_dispatch/middleware/session/cookie_store.rb +24 -19
  98. data/lib/action_dispatch/middleware/show_exceptions.rb +3 -2
  99. data/lib/action_dispatch/middleware/ssl.rb +20 -15
  100. data/lib/action_dispatch/middleware/stack.rb +57 -3
  101. data/lib/action_dispatch/middleware/static.rb +153 -93
  102. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  103. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  104. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  105. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
  106. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  107. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
  108. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  109. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  110. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  111. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
  112. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  113. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +6 -3
  114. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +4 -1
  115. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +104 -8
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  119. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +24 -1
  123. data/lib/action_dispatch/railtie.rb +8 -2
  124. data/lib/action_dispatch/request/session.rb +17 -10
  125. data/lib/action_dispatch/request/utils.rb +28 -2
  126. data/lib/action_dispatch/routing/inspector.rb +101 -53
  127. data/lib/action_dispatch/routing/mapper.rb +156 -103
  128. data/lib/action_dispatch/routing/polymorphic_routes.rb +21 -19
  129. data/lib/action_dispatch/routing/redirection.rb +4 -4
  130. data/lib/action_dispatch/routing/route_set.rb +71 -69
  131. data/lib/action_dispatch/routing/url_for.rb +3 -3
  132. data/lib/action_dispatch/routing.rb +21 -20
  133. data/lib/action_dispatch/system_test_case.rb +54 -11
  134. data/lib/action_dispatch/system_testing/browser.rb +53 -16
  135. data/lib/action_dispatch/system_testing/driver.rb +11 -3
  136. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +49 -7
  137. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +8 -6
  138. data/lib/action_dispatch/testing/assertion_response.rb +0 -1
  139. data/lib/action_dispatch/testing/assertions/response.rb +4 -7
  140. data/lib/action_dispatch/testing/assertions/routing.rb +20 -8
  141. data/lib/action_dispatch/testing/assertions.rb +1 -1
  142. data/lib/action_dispatch/testing/integration.rb +61 -28
  143. data/lib/action_dispatch/testing/request_encoder.rb +3 -3
  144. data/lib/action_dispatch/testing/test_process.rb +29 -4
  145. data/lib/action_dispatch/testing/test_request.rb +3 -3
  146. data/lib/action_dispatch/testing/test_response.rb +4 -32
  147. data/lib/action_dispatch.rb +14 -7
  148. data/lib/action_pack/gem_version.rb +3 -3
  149. data/lib/action_pack.rb +1 -1
  150. metadata +39 -22
  151. data/lib/action_controller/metal/force_ssl.rb +0 -99
  152. data/lib/action_dispatch/http/parameter_filter.rb +0 -86
  153. data/lib/action_dispatch/journey/nfa/builder.rb +0 -78
  154. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -49
  155. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -120
  156. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -1,52 +1,62 @@
1
- <% names = @traces.keys %>
1
+ <% names = traces.keys %>
2
+ <% error_index = local_assigns[:error_index] || 0 %>
2
3
 
3
4
  <p><code>Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %></code></p>
4
5
 
5
- <div id="traces">
6
+ <div id="traces-<%= error_index %>">
6
7
  <% names.each do |name| %>
7
8
  <%
8
- show = "show('#{name.gsub(/\s/, '-')}');"
9
- hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}');"}
9
+ show = "show('#{name.gsub(/\s/, '-')}-#{error_index}');"
10
+ hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}-#{error_index}');"}
10
11
  %>
11
12
  <a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
12
13
  <% end %>
13
14
 
14
- <% @traces.each do |name, trace| %>
15
- <div id="<%= name.gsub(/\s/, '-') %>" style="display: <%= (name == @trace_to_show) ? 'block' : 'none' %>;">
16
- <pre><code><% trace.each do |frame| %><a class="trace-frames" data-frame-id="<%= frame[:id] %>" href="#"><%= frame[:trace] %></a><br><% end %></code></pre>
15
+ <% traces.each do |name, trace| %>
16
+ <div id="<%= "#{name.gsub(/\s/, '-')}-#{error_index}" %>" style="display: <%= (name == trace_to_show) ? 'block' : 'none' %>;">
17
+ <code style="font-size: 11px;">
18
+ <% trace.each do |frame| %>
19
+ <a class="trace-frames trace-frames-<%= error_index %>" data-exception-object-id="<%= frame[:exception_object_id] %>" data-frame-id="<%= frame[:id] %>" href="#">
20
+ <%= frame[:trace] %>
21
+ </a>
22
+ <br>
23
+ <% end %>
24
+ </code>
17
25
  </div>
18
26
  <% end %>
19
27
 
20
28
  <script type="text/javascript">
21
- var traceFrames = document.getElementsByClassName('trace-frames');
22
- var selectedFrame, currentSource = document.getElementById('frame-source-0');
23
-
24
- // Add click listeners for all stack frames
25
- for (var i = 0; i < traceFrames.length; i++) {
26
- traceFrames[i].addEventListener('click', function(e) {
27
- e.preventDefault();
28
- var target = e.target;
29
- var frame_id = target.dataset.frameId;
30
-
31
- if (selectedFrame) {
32
- selectedFrame.className = selectedFrame.className.replace("selected", "");
33
- }
34
-
35
- target.className += " selected";
36
- selectedFrame = target;
37
-
38
- // Change the extracted source code
39
- changeSourceExtract(frame_id);
40
- });
41
-
42
- function changeSourceExtract(frame_id) {
43
- var el = document.getElementById('frame-source-' + frame_id);
44
- if (currentSource && el) {
45
- currentSource.className += " hidden";
46
- el.className = el.className.replace(" hidden", "");
47
- currentSource = el;
29
+ (function() {
30
+ var traceFrames = document.getElementsByClassName('trace-frames-<%= error_index %>');
31
+ var selectedFrame, currentSource = document.getElementById('frame-source-<%= error_index %>-0');
32
+
33
+ // Add click listeners for all stack frames
34
+ for (var i = 0; i < traceFrames.length; i++) {
35
+ traceFrames[i].addEventListener('click', function(e) {
36
+ e.preventDefault();
37
+ var target = e.target;
38
+ var frame_id = target.dataset.frameId;
39
+
40
+ if (selectedFrame) {
41
+ selectedFrame.className = selectedFrame.className.replace("selected", "");
42
+ }
43
+
44
+ target.className += " selected";
45
+ selectedFrame = target;
46
+
47
+ // Change the extracted source code
48
+ changeSourceExtract(frame_id);
49
+ });
50
+
51
+ function changeSourceExtract(frame_id) {
52
+ var el = document.getElementById('frame-source-<%= error_index %>-' + frame_id);
53
+ if (currentSource && el) {
54
+ currentSource.className += " hidden";
55
+ el.className = el.className.replace(" hidden", "");
56
+ currentSource = el;
57
+ }
48
58
  }
49
59
  }
50
- }
60
+ })();
51
61
  </script>
52
62
  </div>
@@ -0,0 +1,7 @@
1
+ <header>
2
+ <h1>Blocked host: <%= @host %></h1>
3
+ </header>
4
+ <div id="container">
5
+ <h2>To allow requests to <%= @host %>, add the following to your environment configuration:</h2>
6
+ <pre>config.hosts &lt;&lt; "<%= @host %>"</pre>
7
+ </div>
@@ -0,0 +1,5 @@
1
+ Blocked host: <%= @host %>
2
+
3
+ To allow requests to <%= @host %>, add the following to your environment configuration:
4
+
5
+ config.hosts << "<%= @host %>"
@@ -1,16 +1,35 @@
1
1
  <header>
2
2
  <h1>
3
3
  <%= @exception.class.to_s %>
4
- <% if @request.parameters['controller'] %>
4
+ <% if params_valid? && @request.parameters['controller'] %>
5
5
  in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
6
6
  <% end %>
7
7
  </h1>
8
8
  </header>
9
9
 
10
10
  <div id="container">
11
- <h2><%= h @exception.message %></h2>
11
+ <%= render "rescues/message_and_suggestions", exception: @exception %>
12
+ <%= render "rescues/actions", exception: @exception, request: @request %>
13
+
14
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx, error_index: 0 %>
15
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show, error_index: 0 %>
16
+
17
+ <% if @exception.cause %>
18
+ <h2>Exception Causes</h2>
19
+ <% end %>
20
+
21
+ <% @exception_wrapper.wrapped_causes.each.with_index(1) do |wrapper, index| %>
22
+ <div class="details">
23
+ <a class="summary" href="#" style="color: #F0F0F0; text-decoration: none; background: #C52F24; border-bottom: none;" onclick="return toggle(<%= wrapper.exception.object_id %>)">
24
+ <%= wrapper.exception.class.name %>: <%= h wrapper.exception.message %>
25
+ </a>
26
+ </div>
27
+
28
+ <div id="<%= wrapper.exception.object_id %>" style="display: none;">
29
+ <%= render "rescues/source", source_extracts: wrapper.source_extracts, show_source_idx: wrapper.source_to_show_id, error_index: index %>
30
+ <%= render "rescues/trace", traces: wrapper.traces, trace_to_show: wrapper.trace_to_show, error_index: index %>
31
+ </div>
32
+ <% end %>
12
33
 
13
- <%= render template: "rescues/_source" %>
14
- <%= render template: "rescues/_trace" %>
15
34
  <%= render template: "rescues/_request_and_response" %>
16
35
  </div>
@@ -1,5 +1,5 @@
1
1
  <%= @exception.class.to_s %><%
2
- if @request.parameters['controller']
2
+ if params_valid? && @request.parameters['controller']
3
3
  %> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
4
4
  <% end %>
5
5
 
@@ -10,12 +10,15 @@
10
10
  <div id="container">
11
11
  <h2>
12
12
  <%= h @exception.message %>
13
- <% if @exception.message.match? %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}} %>
13
+ <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
14
14
  <br />To resolve this issue run: bin/rails active_storage:install
15
15
  <% end %>
16
+ <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
17
+ <br />To resolve this issue run: bin/rails action_mailbox:install
18
+ <% end %>
16
19
  </h2>
17
20
 
18
- <%= render template: "rescues/_source" %>
19
- <%= render template: "rescues/_trace" %>
21
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
22
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
20
23
  <%= render template: "rescues/_request_and_response" %>
21
24
  </div>
@@ -4,9 +4,12 @@
4
4
  <% end %>
5
5
 
6
6
  <%= @exception.message %>
7
- <% if @exception.message.match? %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}} %>
7
+ <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
8
8
  To resolve this issue run: bin/rails active_storage:install
9
9
  <% end %>
10
+ <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
11
+ To resolve this issue run: bin/rails action_mailbox:install
12
+ <% end %>
10
13
 
11
14
  <%= render template: "rescues/_source" %>
12
15
  <%= render template: "rescues/_trace" %>
@@ -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,27 +33,40 @@
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
 
52
+ .exception-message {
53
+ padding: 8px 0;
54
+ }
55
+
56
+ .exception-message .message{
57
+ margin-bottom: 8px;
58
+ line-height: 25px;
59
+ font-size: 1.5em;
60
+ font-weight: bold;
61
+ color: #C00;
62
+ }
63
+
48
64
  .details {
49
65
  border: 1px solid #D0D0D0;
50
66
  border-radius: 4px;
51
67
  margin: 1em 0px;
52
68
  display: block;
53
- width: 978px;
69
+ max-width: 978px;
54
70
  }
55
71
 
56
72
  .summary {
@@ -78,7 +94,7 @@
78
94
  .source {
79
95
  border: 1px solid #D9D9D9;
80
96
  background: #ECECEC;
81
- width: 978px;
97
+ max-width: 978px;
82
98
  }
83
99
 
84
100
  .source pre {
@@ -114,18 +130,98 @@
114
130
  }
115
131
 
116
132
  .line.active {
117
- background-color: #FFCCCC;
133
+ background-color: #FCC;
134
+ }
135
+
136
+ .button_to {
137
+ display: inline-block;
138
+ margin-top: 0.75em;
139
+ margin-bottom: 0.75em;
118
140
  }
119
141
 
120
142
  .hidden {
121
143
  display: none;
122
144
  }
123
145
 
146
+ input[type="submit"] {
147
+ color: white;
148
+ background-color: #C00;
149
+ border: none;
150
+ border-radius: 12px;
151
+ box-shadow: 0 3px #F99;
152
+ font-size: 13px;
153
+ font-weight: bold;
154
+ margin: 0;
155
+ padding: 10px 18px;
156
+ -webkit-appearance: none;
157
+ }
158
+ input[type="submit"]:focus,
159
+ input[type="submit"]:hover {
160
+ opacity: 0.8;
161
+ }
162
+ input[type="submit"]:active {
163
+ box-shadow: 0 2px #F99;
164
+ transform: translateY(1px)
165
+ }
166
+
167
+
124
168
  a { color: #980905; }
125
169
  a:visited { color: #666; }
126
- a.trace-frames { color: #666; }
127
- a:hover { color: #C52F24; }
128
- a.trace-frames.selected { color: #C52F24 }
170
+ a.trace-frames {
171
+ color: #666;
172
+ overflow-wrap: break-word;
173
+ }
174
+ a:hover { color: #C00; }
175
+ a.trace-frames.selected { color: #C00 }
176
+
177
+ @media (prefers-color-scheme: dark) {
178
+ body {
179
+ background-color: #222;
180
+ color: #ECECEC;
181
+ }
182
+
183
+ .details {
184
+ border-color: #666;
185
+ }
186
+
187
+ .summary {
188
+ border-color: #666;
189
+ }
190
+
191
+ .source {
192
+ border-color: #555;
193
+ background-color: #333;
194
+ }
195
+
196
+ .source .data {
197
+ background: #444;
198
+ }
199
+
200
+ .source .data .line_numbers {
201
+ background: #333;
202
+ border-color: #222;
203
+ }
204
+
205
+ .line:hover {
206
+ background: #666;
207
+ }
208
+
209
+ .line.active {
210
+ background-color: #900;
211
+ }
212
+
213
+ input[type="submit"] {
214
+ box-shadow: 0 3px #800;
215
+ }
216
+ input[type="submit"]:active {
217
+ box-shadow: 0 2px #800;
218
+ }
219
+
220
+ a { color: #C00; }
221
+ a.trace-frames { color: #999; }
222
+ a:hover { color: #E9382B; }
223
+ a.trace-frames.selected { color: #E9382B; }
224
+ }
129
225
 
130
226
  <%= yield :style %>
131
227
  </style>
@@ -0,0 +1,19 @@
1
+ <header>
2
+ <h1>No template for interactive request</h1>
3
+ </header>
4
+
5
+ <div id="container">
6
+ <h2><%= h @exception.message %></h2>
7
+
8
+ <p class="summary">
9
+ <strong>NOTE!</strong><br>
10
+ Unless told otherwise, Rails expects an action to render a template with the same name,<br>
11
+ contained in a folder named after its controller.
12
+
13
+ If this controller is an API responding with 204 (No Content), <br>
14
+ which does not require a template,
15
+ then this error will occur when trying to access it via browser,<br>
16
+ since we expect an HTML template
17
+ to be rendered for such requests. If that's the case, carry on.
18
+ </p>
19
+ </div>
@@ -0,0 +1,3 @@
1
+ Missing exact template
2
+
3
+ <%= @exception.message %>
@@ -5,7 +5,7 @@
5
5
  <div id="container">
6
6
  <h2><%= h @exception.message %></h2>
7
7
 
8
- <%= render template: "rescues/_source" %>
9
- <%= render template: "rescues/_trace" %>
8
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
9
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
10
10
  <%= render template: "rescues/_request_and_response" %>
11
11
  </div>
@@ -14,7 +14,7 @@
14
14
  </p>
15
15
  <% end %>
16
16
 
17
- <%= render template: "rescues/_trace" %>
17
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
18
18
 
19
19
  <% if @routes_inspector %>
20
20
  <h2>
@@ -11,10 +11,10 @@
11
11
  </p>
12
12
  <pre><code><%= h @exception.message %></code></pre>
13
13
 
14
- <%= render template: "rescues/_source" %>
14
+ <%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
15
15
 
16
16
  <p><%= @exception.sub_template_message %></p>
17
17
 
18
- <%= render template: "rescues/_trace" %>
18
+ <%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
19
19
  <%= render template: "rescues/_request_and_response" %>
20
20
  </div>
@@ -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,26 @@
49
49
  width: 80%;
50
50
  font-size: inherit;
51
51
  }
52
+
53
+ @media (prefers-color-scheme: dark) {
54
+ body {
55
+ background-color: #222;
56
+ color: #ECECEC;
57
+ }
58
+
59
+ #route_table tbody tr:nth-child(odd) {
60
+ background: #333;
61
+ }
62
+
63
+ #route_table tbody tr:nth-child(even) {
64
+ background: #444;
65
+ }
66
+
67
+ #route_table tbody.exact_matches,
68
+ #route_table tbody.fuzzy_matches {
69
+ color: #333;
70
+ }
71
+ }
52
72
  <% end %>
53
73
 
54
74
  <table id='route_table' class='route_table'>
@@ -85,7 +105,7 @@
85
105
  </table>
86
106
 
87
107
  <script type='text/javascript'>
88
- // support forEarch iterator on NodeList
108
+ // support forEach iterator on NodeList
89
109
  NodeList.prototype.forEach = Array.prototype.forEach;
90
110
 
91
111
  // Enables path search functionality
@@ -197,4 +217,7 @@
197
217
 
198
218
  setupMatchPaths();
199
219
  setupRouteToggleHelperLinks();
220
+
221
+ // Focus the search input after page has loaded
222
+ document.getElementById('search').focus();
200
223
  </script>
@@ -21,7 +21,9 @@ module ActionDispatch
21
21
  config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie"
22
22
  config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie"
23
23
  config.action_dispatch.use_authenticated_cookie_encryption = false
24
+ config.action_dispatch.use_cookies_with_metadata = false
24
25
  config.action_dispatch.perform_deep_munge = true
26
+ config.action_dispatch.request_id_header = "X-Request-Id"
25
27
 
26
28
  config.action_dispatch.default_headers = {
27
29
  "X-Frame-Options" => "SAMEORIGIN",
@@ -37,11 +39,15 @@ module ActionDispatch
37
39
  config.eager_load_namespaces << ActionDispatch
38
40
 
39
41
  initializer "action_dispatch.configure" do |app|
42
+ ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
40
43
  ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
41
44
  ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
42
45
  ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
43
- ActionDispatch::Response.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
44
- ActionDispatch::Response.default_headers = app.config.action_dispatch.default_headers
46
+
47
+ ActiveSupport.on_load(:action_dispatch_response) do
48
+ self.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
49
+ self.default_headers = app.config.action_dispatch.default_headers
50
+ end
45
51
 
46
52
  ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
47
53
  ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)
@@ -90,7 +90,21 @@ module ActionDispatch
90
90
  # +nil+ if the given key is not found in the session.
91
91
  def [](key)
92
92
  load_for_read!
93
- @delegate[key.to_s]
93
+ key = key.to_s
94
+
95
+ if key == "session_id"
96
+ id&.public_id
97
+ else
98
+ @delegate[key]
99
+ end
100
+ end
101
+
102
+ # Returns the nested value specified by the sequence of keys, returning
103
+ # +nil+ if any intermediate step is +nil+.
104
+ def dig(*keys)
105
+ load_for_read!
106
+ keys = keys.map.with_index { |key, i| i.zero? ? key.to_s : key }
107
+ @delegate.dig(*keys)
94
108
  end
95
109
 
96
110
  # Returns true if the session has the given key or false.
@@ -144,7 +158,7 @@ module ActionDispatch
144
158
  # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
145
159
  def update(hash)
146
160
  load_for_write!
147
- @delegate.update stringify_keys(hash)
161
+ @delegate.update hash.stringify_keys
148
162
  end
149
163
 
150
164
  # Deletes given key from the session.
@@ -208,7 +222,6 @@ module ActionDispatch
208
222
  end
209
223
 
210
224
  private
211
-
212
225
  def load_for_read!
213
226
  load! if !loaded? && exists?
214
227
  end
@@ -220,15 +233,9 @@ module ActionDispatch
220
233
  def load!
221
234
  id, session = @by.load_session @req
222
235
  options[:id] = id
223
- @delegate.replace(stringify_keys(session))
236
+ @delegate.replace(session.stringify_keys)
224
237
  @loaded = true
225
238
  end
226
-
227
- def stringify_keys(other)
228
- other.each_with_object({}) { |(key, value), hash|
229
- hash[key.to_s] = value
230
- }
231
- end
232
239
  end
233
240
  end
234
241
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+
3
5
  module ActionDispatch
4
6
  class Request
5
7
  class Utils # :nodoc:
@@ -39,6 +41,10 @@ module ActionDispatch
39
41
  end
40
42
  end
41
43
 
44
+ def self.set_binary_encoding(request, params, controller, action)
45
+ CustomParamEncoder.encode(request, params, controller, action)
46
+ end
47
+
42
48
  class ParamEncoder # :nodoc:
43
49
  # Convert nested Hash to HashWithIndifferentAccess.
44
50
  def self.normalize_encode_params(params)
@@ -49,8 +55,8 @@ module ActionDispatch
49
55
  if params.has_key?(:tempfile)
50
56
  ActionDispatch::Http::UploadedFile.new(params)
51
57
  else
52
- params.each_with_object({}) do |(key, val), new_hash|
53
- new_hash[key] = normalize_encode_params(val)
58
+ params.transform_values do |val|
59
+ normalize_encode_params(val)
54
60
  end.with_indifferent_access
55
61
  end
56
62
  else
@@ -71,6 +77,26 @@ module ActionDispatch
71
77
  list
72
78
  end
73
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
74
100
  end
75
101
  end
76
102
  end