actionpack 6.1.3.2 → 7.0.0.alpha2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +103 -387
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +7 -21
- data/lib/abstract_controller/caching/fragments.rb +2 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +9 -8
- data/lib/abstract_controller/collector.rb +4 -2
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +3 -2
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/translation.rb +0 -2
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +38 -1
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -13
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +19 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +15 -15
- data/lib/action_controller/metal/instrumentation.rb +55 -52
- data/lib/action_controller/metal/live.rb +52 -3
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/params_wrapper.rb +10 -9
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/query_tags.rb +16 -0
- data/lib/action_controller/metal/redirecting.rb +50 -16
- data/lib/action_controller/metal/rendering.rb +7 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +64 -20
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +1 -3
- data/lib/action_controller/metal/strong_parameters.rb +24 -28
- data/lib/action_controller/metal/testing.rb +0 -2
- data/lib/action_controller/metal.rb +7 -10
- data/lib/action_controller/railtie.rb +42 -5
- data/lib/action_controller/test_case.rb +9 -2
- data/lib/action_controller.rb +2 -5
- data/lib/action_dispatch/http/cache.rb +18 -12
- data/lib/action_dispatch/http/content_security_policy.rb +39 -35
- data/lib/action_dispatch/http/filter_parameters.rb +5 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -3
- data/lib/action_dispatch/http/mime_type.rb +9 -11
- data/lib/action_dispatch/http/parameters.rb +4 -4
- data/lib/action_dispatch/http/permissions_policy.rb +1 -1
- data/lib/action_dispatch/http/request.rb +10 -19
- data/lib/action_dispatch/http/response.rb +3 -3
- data/lib/action_dispatch/http/url.rb +9 -10
- data/lib/action_dispatch/journey/formatter.rb +2 -2
- data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
- data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
- data/lib/action_dispatch/journey/nodes/node.rb +70 -5
- data/lib/action_dispatch/journey/path/pattern.rb +22 -13
- data/lib/action_dispatch/journey/route.rb +5 -12
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +1 -1
- data/lib/action_dispatch/journey/routes.rb +3 -3
- data/lib/action_dispatch/journey/visitors.rb +1 -1
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
- data/lib/action_dispatch/middleware/cookies.rb +7 -3
- data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
- data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
- data/lib/action_dispatch/middleware/flash.rb +9 -11
- data/lib/action_dispatch/middleware/host_authorization.rb +9 -17
- data/lib/action_dispatch/middleware/remote_ip.rb +16 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +7 -9
- data/lib/action_dispatch/middleware/stack.rb +27 -9
- data/lib/action_dispatch/middleware/static.rb +2 -5
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +5 -14
- data/lib/action_dispatch/railtie.rb +8 -2
- data/lib/action_dispatch/request/session.rb +43 -13
- data/lib/action_dispatch/routing/mapper.rb +44 -72
- data/lib/action_dispatch/routing/redirection.rb +0 -2
- data/lib/action_dispatch/routing/route_set.rb +9 -6
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +1 -2
- data/lib/action_dispatch/routing.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +5 -5
- data/lib/action_dispatch/system_testing/driver.rb +24 -4
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +10 -6
- data/lib/action_dispatch/testing/assertions.rb +2 -5
- data/lib/action_dispatch/testing/integration.rb +6 -8
- data/lib/action_dispatch/testing/test_process.rb +12 -9
- data/lib/action_dispatch.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +21 -20
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "action_dispatch/http/request"
|
4
|
-
|
5
3
|
module ActionDispatch
|
6
4
|
# This middleware guards from DNS rebinding attacks by explicitly permitting
|
7
5
|
# the hosts a request can be sent to, and is passed the options set in
|
@@ -78,7 +76,7 @@ module ActionDispatch
|
|
78
76
|
|
79
77
|
unless deprecated_response_app.nil?
|
80
78
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
81
|
-
`action_dispatch.hosts_response_app` is deprecated and will be ignored in Rails
|
79
|
+
`action_dispatch.hosts_response_app` is deprecated and will be ignored in Rails 7.0.
|
82
80
|
Use the Host Authorization `response_app` setting instead.
|
83
81
|
MSG
|
84
82
|
|
@@ -102,21 +100,15 @@ module ActionDispatch
|
|
102
100
|
end
|
103
101
|
|
104
102
|
private
|
103
|
+
HOSTNAME = /[a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\]/i
|
104
|
+
VALID_ORIGIN_HOST = /\A(#{HOSTNAME})(?::\d+)?\z/
|
105
|
+
VALID_FORWARDED_HOST = /(?:\A|,[ ]?)(#{HOSTNAME})(?::\d+)?\z/
|
106
|
+
|
105
107
|
def authorized?(request)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
\z
|
111
|
-
/x
|
112
|
-
|
113
|
-
origin_host = valid_host.match(
|
114
|
-
request.get_header("HTTP_HOST").to_s.downcase)
|
115
|
-
forwarded_host = valid_host.match(
|
116
|
-
request.x_forwarded_host.to_s.split(/,\s?/).last)
|
117
|
-
|
118
|
-
origin_host && @permissions.allows?(origin_host[:host]) && (
|
119
|
-
forwarded_host.nil? || @permissions.allows?(forwarded_host[:host]))
|
108
|
+
origin_host = request.get_header("HTTP_HOST")&.slice(VALID_ORIGIN_HOST, 1) || ""
|
109
|
+
forwarded_host = request.x_forwarded_host&.slice(VALID_FORWARDED_HOST, 1) || ""
|
110
|
+
|
111
|
+
@permissions.allows?(origin_host) && (forwarded_host.blank? || @permissions.allows?(forwarded_host))
|
120
112
|
end
|
121
113
|
|
122
114
|
def excluded?(request)
|
@@ -51,10 +51,8 @@ module ActionDispatch
|
|
51
51
|
# clients (like WAP devices), or behind proxies that set headers in an
|
52
52
|
# incorrect or confusing way (like AWS ELB).
|
53
53
|
#
|
54
|
-
# The +custom_proxies+ argument can take an
|
55
|
-
#
|
56
|
-
# single string, IPAddr, or Regexp object is provided, it will be used in
|
57
|
-
# addition to +TRUSTED_PROXIES+. Any proxy setup will put the value you
|
54
|
+
# The +custom_proxies+ argument can take an enumerable which will be used
|
55
|
+
# instead of +TRUSTED_PROXIES+. Any proxy setup will put the value you
|
58
56
|
# want in the middle (or at the beginning) of the X-Forwarded-For list,
|
59
57
|
# with your proxy servers after it. If your proxies aren't removed, pass
|
60
58
|
# them in via the +custom_proxies+ parameter. That way, the middleware will
|
@@ -67,6 +65,20 @@ module ActionDispatch
|
|
67
65
|
elsif custom_proxies.respond_to?(:any?)
|
68
66
|
custom_proxies
|
69
67
|
else
|
68
|
+
ActiveSupport::Deprecation.warn(<<~EOM)
|
69
|
+
Setting config.action_dispatch.trusted_proxies to a single value has
|
70
|
+
been deprecated. Please set this to an enumerable instead. For
|
71
|
+
example, instead of:
|
72
|
+
|
73
|
+
config.action_dispatch.trusted_proxies = IPAddr.new("10.0.0.0/8")
|
74
|
+
|
75
|
+
Wrap the value in an Array:
|
76
|
+
|
77
|
+
config.action_dispatch.trusted_proxies = [IPAddr.new("10.0.0.0/8")]
|
78
|
+
|
79
|
+
Note that unlike passing a single argument, passing an enumerable
|
80
|
+
will *replace* the default set of trusted proxies.
|
81
|
+
EOM
|
70
82
|
Array(custom_proxies) + TRUSTED_PROXIES
|
71
83
|
end
|
72
84
|
end
|
@@ -8,7 +8,7 @@ require "action_dispatch/request/session"
|
|
8
8
|
|
9
9
|
module ActionDispatch
|
10
10
|
module Session
|
11
|
-
class SessionRestoreError < StandardError
|
11
|
+
class SessionRestoreError < StandardError # :nodoc:
|
12
12
|
def initialize
|
13
13
|
super("Session contains objects whose class definition isn't available.\n" \
|
14
14
|
"Remember to require the classes for all objects kept in the session.\n" \
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "action_dispatch/http/request"
|
4
3
|
require "action_dispatch/middleware/exception_wrapper"
|
5
4
|
|
6
5
|
module ActionDispatch
|
@@ -15,14 +14,8 @@ module ActionDispatch
|
|
15
14
|
# If the application returns a "X-Cascade" pass response, this middleware
|
16
15
|
# will send an empty response as result with the correct status code.
|
17
16
|
# If any exception happens inside the exceptions app, this middleware
|
18
|
-
# catches the exceptions and returns a
|
17
|
+
# catches the exceptions and returns a failsafe response.
|
19
18
|
class ShowExceptions
|
20
|
-
FAILSAFE_RESPONSE = [500, { "Content-Type" => "text/plain" },
|
21
|
-
["500 Internal Server Error\n" \
|
22
|
-
"If you are the administrator of this website, then please read this web " \
|
23
|
-
"application's log file and/or the web server's log file to find out what " \
|
24
|
-
"went wrong."]]
|
25
|
-
|
26
19
|
def initialize(app, exceptions_app)
|
27
20
|
@app = app
|
28
21
|
@exceptions_app = exceptions_app
|
@@ -53,7 +46,12 @@ module ActionDispatch
|
|
53
46
|
response[1]["X-Cascade"] == "pass" ? pass_response(status) : response
|
54
47
|
rescue Exception => failsafe_error
|
55
48
|
$stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"
|
56
|
-
|
49
|
+
|
50
|
+
[500, { "Content-Type" => "text/plain" },
|
51
|
+
["500 Internal Server Error\n" \
|
52
|
+
"If you are the administrator of this website, then please read this web " \
|
53
|
+
"application's log file and/or the web server's log file to find out what " \
|
54
|
+
"went wrong."]]
|
57
55
|
end
|
58
56
|
|
59
57
|
def pass_response(status)
|
@@ -72,8 +72,8 @@ module ActionDispatch
|
|
72
72
|
yield(self) if block_given?
|
73
73
|
end
|
74
74
|
|
75
|
-
def each
|
76
|
-
@middlewares.each
|
75
|
+
def each(&block)
|
76
|
+
@middlewares.each(&block)
|
77
77
|
end
|
78
78
|
|
79
79
|
def size
|
@@ -91,7 +91,7 @@ module ActionDispatch
|
|
91
91
|
def unshift(klass, *args, &block)
|
92
92
|
middlewares.unshift(build_middleware(klass, args, block))
|
93
93
|
end
|
94
|
-
ruby2_keywords(:unshift)
|
94
|
+
ruby2_keywords(:unshift)
|
95
95
|
|
96
96
|
def initialize_copy(other)
|
97
97
|
self.middlewares = other.middlewares.dup
|
@@ -101,7 +101,7 @@ module ActionDispatch
|
|
101
101
|
index = assert_index(index, :before)
|
102
102
|
middlewares.insert(index, build_middleware(klass, args, block))
|
103
103
|
end
|
104
|
-
ruby2_keywords(:insert)
|
104
|
+
ruby2_keywords(:insert)
|
105
105
|
|
106
106
|
alias_method :insert_before, :insert
|
107
107
|
|
@@ -109,17 +109,29 @@ module ActionDispatch
|
|
109
109
|
index = assert_index(index, :after)
|
110
110
|
insert(index + 1, *args, &block)
|
111
111
|
end
|
112
|
-
ruby2_keywords(:insert_after)
|
112
|
+
ruby2_keywords(:insert_after)
|
113
113
|
|
114
114
|
def swap(target, *args, &block)
|
115
115
|
index = assert_index(target, :before)
|
116
116
|
insert(index, *args, &block)
|
117
117
|
middlewares.delete_at(index + 1)
|
118
118
|
end
|
119
|
-
ruby2_keywords(:swap)
|
119
|
+
ruby2_keywords(:swap)
|
120
120
|
|
121
|
+
# Deletes a middleware from the middleware stack.
|
122
|
+
#
|
123
|
+
# Returns the array of middlewares not including the deleted item, or
|
124
|
+
# returns nil if the target is not found.
|
121
125
|
def delete(target)
|
122
|
-
middlewares.
|
126
|
+
middlewares.reject! { |m| m.name == target.name }
|
127
|
+
end
|
128
|
+
|
129
|
+
# Deletes a middleware from the middleware stack.
|
130
|
+
#
|
131
|
+
# Returns the array of middlewares not including the deleted item, or
|
132
|
+
# raises +RuntimeError+ if the target is not found.
|
133
|
+
def delete!(target)
|
134
|
+
delete(target) || (raise "No such middleware to remove: #{target.inspect}")
|
123
135
|
end
|
124
136
|
|
125
137
|
def move(target, source)
|
@@ -143,7 +155,7 @@ module ActionDispatch
|
|
143
155
|
def use(klass, *args, &block)
|
144
156
|
middlewares.push(build_middleware(klass, args, block))
|
145
157
|
end
|
146
|
-
ruby2_keywords(:use)
|
158
|
+
ruby2_keywords(:use)
|
147
159
|
|
148
160
|
def build(app = nil, &block)
|
149
161
|
instrumenting = ActiveSupport::Notifications.notifier.listening?(InstrumentationProxy::EVENT_NAME)
|
@@ -158,7 +170,7 @@ module ActionDispatch
|
|
158
170
|
|
159
171
|
private
|
160
172
|
def assert_index(index, where)
|
161
|
-
i = index.is_a?(Integer) ? index :
|
173
|
+
i = index.is_a?(Integer) ? index : index_of(index)
|
162
174
|
raise "No such middleware to insert #{where}: #{index.inspect}" unless i
|
163
175
|
i
|
164
176
|
end
|
@@ -166,5 +178,11 @@ module ActionDispatch
|
|
166
178
|
def build_middleware(klass, args, block)
|
167
179
|
Middleware.new(klass, args, block)
|
168
180
|
end
|
181
|
+
|
182
|
+
def index_of(klass)
|
183
|
+
middlewares.index do |m|
|
184
|
+
m.name == klass.name
|
185
|
+
end
|
186
|
+
end
|
169
187
|
end
|
170
188
|
end
|
@@ -137,11 +137,8 @@ module ActionDispatch
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def file_readable?(path)
|
140
|
-
|
141
|
-
|
142
|
-
false
|
143
|
-
else
|
144
|
-
file_stat.file? && file_stat.readable?
|
140
|
+
file_path = File.join(@root, path.b)
|
141
|
+
File.file?(file_path) && File.readable?(file_path)
|
145
142
|
end
|
146
143
|
|
147
144
|
def compressible?(content_type)
|
@@ -1,24 +1,17 @@
|
|
1
|
-
|
2
|
-
<% if (hide = @exception.blamed_files.length > 8) %>
|
3
|
-
<a href="#" onclick="return toggleTrace()">Toggle blamed files</a>
|
4
|
-
<% end %>
|
5
|
-
<pre id="blame_trace" <%='style="display:none"' if hide %>><code><%= @exception.describe_blame %></code></pre>
|
6
|
-
<% end %>
|
7
|
-
|
8
|
-
<h2 style="margin-top: 30px">Request</h2>
|
1
|
+
<h2 class="request-heading">Request</h2>
|
9
2
|
<% if params_valid? %>
|
10
3
|
<p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
|
11
4
|
<% end %>
|
12
5
|
|
13
6
|
<div class="details">
|
14
7
|
<div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
|
15
|
-
<div id="session_dump"
|
8
|
+
<div id="session_dump" class="hidden"><pre><%= debug_hash @request.session %></pre></div>
|
16
9
|
</div>
|
17
10
|
|
18
11
|
<div class="details">
|
19
12
|
<div class="summary"><a href="#" onclick="return toggleEnvDump()">Toggle env dump</a></div>
|
20
|
-
<div id="env_dump"
|
13
|
+
<div id="env_dump" class="hidden"><pre><%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %></pre></div>
|
21
14
|
</div>
|
22
15
|
|
23
|
-
<h2
|
16
|
+
<h2 class="response-heading">Response</h2>
|
24
17
|
<p><b>Headers</b>:</p> <pre><%= debug_headers(defined?(@response) ? @response.headers : {}) %></pre>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
<% traces.each do |name, trace| %>
|
16
16
|
<div id="<%= "#{name.gsub(/\s/, '-')}-#{error_index}" %>" style="display: <%= (name == trace_to_show) ? 'block' : 'none' %>;">
|
17
|
-
<code
|
17
|
+
<code class="traces">
|
18
18
|
<% trace.each do |frame| %>
|
19
19
|
<a class="trace-frames trace-frames-<%= error_index %>" data-exception-object-id="<%= frame[:exception_object_id] %>" data-frame-id="<%= frame[:id] %>" href="#">
|
20
20
|
<%= frame[:trace] %>
|
@@ -25,7 +25,7 @@
|
|
25
25
|
</div>
|
26
26
|
<% end %>
|
27
27
|
|
28
|
-
<script
|
28
|
+
<script>
|
29
29
|
(function() {
|
30
30
|
var traceFrames = document.getElementsByClassName('trace-frames-<%= error_index %>');
|
31
31
|
var selectedFrame, currentSource = document.getElementById('frame-source-<%= error_index %>-0');
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<header>
|
2
2
|
<h1>Blocked host: <%= @host %></h1>
|
3
3
|
</header>
|
4
|
-
<
|
5
|
-
<h2>To allow requests to <%= @host
|
4
|
+
<main role="main" id="container">
|
5
|
+
<h2>To allow requests to <%= @host %> make sure it is a valid hostname (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:</h2>
|
6
6
|
<pre>config.hosts << "<%= @host %>"</pre>
|
7
|
-
</
|
7
|
+
</main>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
Blocked host: <%= @host %>
|
2
2
|
|
3
|
-
To allow requests to <%= @host
|
3
|
+
To allow requests to <%= @host %> make sure it is a valid hostname (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:
|
4
4
|
|
5
5
|
config.hosts << "<%= @host %>"
|
@@ -7,7 +7,7 @@
|
|
7
7
|
</h1>
|
8
8
|
</header>
|
9
9
|
|
10
|
-
<
|
10
|
+
<main role="main" id="container">
|
11
11
|
<%= render "rescues/message_and_suggestions", exception: @exception %>
|
12
12
|
<%= render "rescues/actions", exception: @exception, request: @request %>
|
13
13
|
|
@@ -20,16 +20,16 @@
|
|
20
20
|
|
21
21
|
<% @exception_wrapper.wrapped_causes.each.with_index(1) do |wrapper, index| %>
|
22
22
|
<div class="details">
|
23
|
-
<a class="summary" href="#"
|
23
|
+
<a class="summary" href="#" onclick="return toggle(<%= wrapper.exception.object_id %>)">
|
24
24
|
<%= wrapper.exception.class.name %>: <%= h wrapper.exception.message %>
|
25
25
|
</a>
|
26
26
|
</div>
|
27
27
|
|
28
|
-
<div id="<%= wrapper.exception.object_id %>"
|
28
|
+
<div id="<%= wrapper.exception.object_id %>" class="hidden">
|
29
29
|
<%= render "rescues/source", source_extracts: wrapper.source_extracts, show_source_idx: wrapper.source_to_show_id, error_index: index %>
|
30
30
|
<%= render "rescues/trace", traces: wrapper.traces, trace_to_show: wrapper.trace_to_show, error_index: index %>
|
31
31
|
</div>
|
32
32
|
<% end %>
|
33
33
|
|
34
34
|
<%= render template: "rescues/_request_and_response" %>
|
35
|
-
</
|
35
|
+
</main>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<header>
|
1
|
+
<header role="banner">
|
2
2
|
<h1>
|
3
3
|
<%= @exception.class.to_s %>
|
4
4
|
<% if @request.parameters['controller'] %>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
</h1>
|
8
8
|
</header>
|
9
9
|
|
10
|
-
<
|
10
|
+
<main role="main" id="container">
|
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}}) %>
|
@@ -21,4 +21,4 @@
|
|
21
21
|
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
22
22
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
23
23
|
<%= render template: "rescues/_request_and_response" %>
|
24
|
-
</
|
24
|
+
</main>
|
@@ -6,6 +6,7 @@
|
|
6
6
|
<%= @exception.message %>
|
7
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
|
+
<% end %>
|
9
10
|
<% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
|
10
11
|
To resolve this issue run: bin/rails action_mailbox:install
|
11
12
|
<% end %>
|
@@ -49,11 +49,19 @@
|
|
49
49
|
line-height: 25px;
|
50
50
|
}
|
51
51
|
|
52
|
+
code.traces {
|
53
|
+
font-size: 11px;
|
54
|
+
}
|
55
|
+
|
56
|
+
.response-heading, .request-heading {
|
57
|
+
margin-top: 30px;
|
58
|
+
}
|
59
|
+
|
52
60
|
.exception-message {
|
53
61
|
padding: 8px 0;
|
54
62
|
}
|
55
63
|
|
56
|
-
.exception-message .message{
|
64
|
+
.exception-message .message {
|
57
65
|
margin-bottom: 8px;
|
58
66
|
line-height: 25px;
|
59
67
|
font-size: 1.5em;
|
@@ -75,6 +83,13 @@
|
|
75
83
|
display: block;
|
76
84
|
}
|
77
85
|
|
86
|
+
a.summary {
|
87
|
+
color: #F0F0F0;
|
88
|
+
text-decoration: none;
|
89
|
+
background: #C52F24;
|
90
|
+
border-bottom: none;
|
91
|
+
}
|
92
|
+
|
78
93
|
.details pre {
|
79
94
|
margin: 5px;
|
80
95
|
border: none;
|
@@ -114,7 +129,7 @@
|
|
114
129
|
|
115
130
|
.source .data .line_numbers {
|
116
131
|
background-color: #ECECEC;
|
117
|
-
color: #
|
132
|
+
color: #555;
|
118
133
|
padding: 1em .5em;
|
119
134
|
border-right: 1px solid #DDD;
|
120
135
|
text-align: right;
|
@@ -143,6 +158,10 @@
|
|
143
158
|
display: none;
|
144
159
|
}
|
145
160
|
|
161
|
+
.correction {
|
162
|
+
list-style-type: none;
|
163
|
+
}
|
164
|
+
|
146
165
|
input[type="submit"] {
|
147
166
|
color: white;
|
148
167
|
background-color: #C00;
|
@@ -153,6 +172,7 @@
|
|
153
172
|
font-weight: bold;
|
154
173
|
margin: 0;
|
155
174
|
padding: 10px 18px;
|
175
|
+
cursor: pointer;
|
156
176
|
-webkit-appearance: none;
|
157
177
|
}
|
158
178
|
input[type="submit"]:focus,
|
@@ -164,15 +184,14 @@
|
|
164
184
|
transform: translateY(1px)
|
165
185
|
}
|
166
186
|
|
167
|
-
|
168
187
|
a { color: #980905; }
|
169
188
|
a:visited { color: #666; }
|
170
189
|
a.trace-frames {
|
171
190
|
color: #666;
|
172
191
|
overflow-wrap: break-word;
|
173
192
|
}
|
174
|
-
a:hover { color: #C00; }
|
175
|
-
a.
|
193
|
+
a:hover, a.trace-frames.selected { color: #C00; }
|
194
|
+
a.summary:hover { color: #FFF; }
|
176
195
|
|
177
196
|
@media (prefers-color-scheme: dark) {
|
178
197
|
body {
|
@@ -180,11 +199,7 @@
|
|
180
199
|
color: #ECECEC;
|
181
200
|
}
|
182
201
|
|
183
|
-
.details {
|
184
|
-
border-color: #666;
|
185
|
-
}
|
186
|
-
|
187
|
-
.summary {
|
202
|
+
.details, .summary {
|
188
203
|
border-color: #666;
|
189
204
|
}
|
190
205
|
|
@@ -219,8 +234,7 @@
|
|
219
234
|
|
220
235
|
a { color: #C00; }
|
221
236
|
a.trace-frames { color: #999; }
|
222
|
-
a:hover { color: #E9382B; }
|
223
|
-
a.trace-frames.selected { color: #E9382B; }
|
237
|
+
a:hover, a.trace-frames.selected { color: #E9382B; }
|
224
238
|
}
|
225
239
|
|
226
240
|
<%= yield :style %>
|
@@ -228,8 +242,7 @@
|
|
228
242
|
|
229
243
|
<script>
|
230
244
|
var toggle = function(id) {
|
231
|
-
|
232
|
-
s.display = s.display == 'none' ? 'block' : 'none';
|
245
|
+
document.getElementById(id).classList.toggle('hidden');
|
233
246
|
return false;
|
234
247
|
}
|
235
248
|
var show = function(id) {
|
@@ -238,9 +251,6 @@
|
|
238
251
|
var hide = function(id) {
|
239
252
|
document.getElementById(id).style.display = 'none';
|
240
253
|
}
|
241
|
-
var toggleTrace = function() {
|
242
|
-
return toggle('blame_trace');
|
243
|
-
}
|
244
254
|
var toggleSessionDump = function() {
|
245
255
|
return toggle('session_dump');
|
246
256
|
}
|
@@ -251,7 +261,7 @@
|
|
251
261
|
</head>
|
252
262
|
<body>
|
253
263
|
|
254
|
-
<%= yield %>
|
264
|
+
<%= yield %>
|
255
265
|
|
256
266
|
</body>
|
257
267
|
</html>
|