actionpack 6.1.7.5 → 7.1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +355 -435
- data/MIT-LICENSE +2 -1
- data/README.rdoc +6 -7
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +33 -37
- data/lib/abstract_controller/caching/fragments.rb +4 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +50 -11
- data/lib/abstract_controller/collector.rb +2 -2
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +78 -30
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
- data/lib/abstract_controller/rendering.rb +12 -14
- data/lib/abstract_controller/translation.rb +26 -7
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +12 -10
- data/lib/action_controller/base.rb +8 -21
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +4 -2
- data/lib/action_controller/log_subscriber.rb +20 -7
- data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +137 -102
- data/lib/action_controller/metal/content_security_policy.rb +37 -3
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +25 -31
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +27 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/head.rb +9 -7
- data/lib/action_controller/metal/helpers.rb +5 -16
- data/lib/action_controller/metal/http_authentication.rb +78 -42
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +62 -50
- data/lib/action_controller/metal/live.rb +67 -2
- data/lib/action_controller/metal/mime_responds.rb +5 -5
- data/lib/action_controller/metal/params_wrapper.rb +24 -13
- data/lib/action_controller/metal/permissions_policy.rb +20 -29
- data/lib/action_controller/metal/redirecting.rb +96 -23
- data/lib/action_controller/metal/renderers.rb +14 -15
- data/lib/action_controller/metal/rendering.rb +121 -16
- data/lib/action_controller/metal/request_forgery_protection.rb +208 -68
- data/lib/action_controller/metal/rescue.rb +7 -4
- data/lib/action_controller/metal/streaming.rb +74 -36
- data/lib/action_controller/metal/strong_parameters.rb +254 -151
- data/lib/action_controller/metal/testing.rb +9 -2
- data/lib/action_controller/metal/url_for.rb +10 -5
- data/lib/action_controller/metal.rb +89 -34
- data/lib/action_controller/railtie.rb +66 -9
- data/lib/action_controller/renderer.rb +99 -85
- data/lib/action_controller/test_case.rb +42 -11
- data/lib/action_controller.rb +10 -6
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +21 -16
- data/lib/action_dispatch/http/content_security_policy.rb +122 -44
- data/lib/action_dispatch/http/filter_parameters.rb +14 -23
- data/lib/action_dispatch/http/headers.rb +3 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -15
- data/lib/action_dispatch/http/mime_type.rb +43 -22
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +6 -6
- data/lib/action_dispatch/http/permissions_policy.rb +57 -19
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +75 -51
- data/lib/action_dispatch/http/response.rb +81 -77
- data/lib/action_dispatch/http/upload.rb +15 -2
- data/lib/action_dispatch/http/url.rb +11 -19
- data/lib/action_dispatch/journey/formatter.rb +8 -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 +36 -27
- data/lib/action_dispatch/journey/route.rb +8 -14
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +10 -9
- data/lib/action_dispatch/journey/routes.rb +5 -5
- 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/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -7
- data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +97 -107
- data/lib/action_dispatch/middleware/debug_exceptions.rb +31 -28
- data/lib/action_dispatch/middleware/debug_locks.rb +7 -4
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +190 -27
- data/lib/action_dispatch/middleware/executor.rb +3 -0
- data/lib/action_dispatch/middleware/flash.rb +24 -18
- data/lib/action_dispatch/middleware/host_authorization.rb +19 -20
- data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
- data/lib/action_dispatch/middleware/reloader.rb +7 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +32 -19
- data/lib/action_dispatch/middleware/request_id.rb +5 -3
- data/lib/action_dispatch/middleware/server_timing.rb +76 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +6 -1
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +19 -13
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +30 -25
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +34 -11
- data/lib/action_dispatch/middleware/static.rb +16 -16
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +5 -5
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +10 -5
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +7 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +9 -9
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +45 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -15
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +6 -6
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +64 -55
- data/lib/action_dispatch/railtie.rb +20 -4
- data/lib/action_dispatch/request/session.rb +59 -19
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +55 -7
- data/lib/action_dispatch/routing/mapper.rb +117 -107
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +20 -8
- data/lib/action_dispatch/routing/route_set.rb +67 -27
- data/lib/action_dispatch/routing/routes_proxy.rb +11 -16
- data/lib/action_dispatch/routing/url_for.rb +29 -26
- data/lib/action_dispatch/routing.rb +12 -13
- data/lib/action_dispatch/system_test_case.rb +8 -8
- data/lib/action_dispatch/system_testing/browser.rb +20 -29
- data/lib/action_dispatch/system_testing/driver.rb +34 -18
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +35 -20
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +0 -8
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +14 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +70 -30
- data/lib/action_dispatch/testing/assertions.rb +3 -4
- data/lib/action_dispatch/testing/integration.rb +33 -25
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +5 -30
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +34 -2
- data/lib/action_dispatch.rb +38 -4
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +67 -30
@@ -4,6 +4,11 @@ require "active_support/inflector/methods"
|
|
4
4
|
require "active_support/dependencies"
|
5
5
|
|
6
6
|
module ActionDispatch
|
7
|
+
# = Action Dispatch \MiddlewareStack
|
8
|
+
#
|
9
|
+
# Read more about {Rails middleware
|
10
|
+
# stack}[https://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack]
|
11
|
+
# in the guides.
|
7
12
|
class MiddlewareStack
|
8
13
|
class Middleware
|
9
14
|
attr_reader :args, :block, :klass
|
@@ -20,13 +25,13 @@ module ActionDispatch
|
|
20
25
|
case middleware
|
21
26
|
when Middleware
|
22
27
|
klass == middleware.klass
|
23
|
-
when
|
28
|
+
when Module
|
24
29
|
klass == middleware
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
33
|
def inspect
|
29
|
-
if klass.is_a?(
|
34
|
+
if klass.is_a?(Module)
|
30
35
|
klass.to_s
|
31
36
|
else
|
32
37
|
klass.class.to_s
|
@@ -72,8 +77,8 @@ module ActionDispatch
|
|
72
77
|
yield(self) if block_given?
|
73
78
|
end
|
74
79
|
|
75
|
-
def each
|
76
|
-
@middlewares.each
|
80
|
+
def each(&block)
|
81
|
+
@middlewares.each(&block)
|
77
82
|
end
|
78
83
|
|
79
84
|
def size
|
@@ -91,7 +96,7 @@ module ActionDispatch
|
|
91
96
|
def unshift(klass, *args, &block)
|
92
97
|
middlewares.unshift(build_middleware(klass, args, block))
|
93
98
|
end
|
94
|
-
ruby2_keywords(:unshift)
|
99
|
+
ruby2_keywords(:unshift)
|
95
100
|
|
96
101
|
def initialize_copy(other)
|
97
102
|
self.middlewares = other.middlewares.dup
|
@@ -101,7 +106,7 @@ module ActionDispatch
|
|
101
106
|
index = assert_index(index, :before)
|
102
107
|
middlewares.insert(index, build_middleware(klass, args, block))
|
103
108
|
end
|
104
|
-
ruby2_keywords(:insert)
|
109
|
+
ruby2_keywords(:insert)
|
105
110
|
|
106
111
|
alias_method :insert_before, :insert
|
107
112
|
|
@@ -109,17 +114,29 @@ module ActionDispatch
|
|
109
114
|
index = assert_index(index, :after)
|
110
115
|
insert(index + 1, *args, &block)
|
111
116
|
end
|
112
|
-
ruby2_keywords(:insert_after)
|
117
|
+
ruby2_keywords(:insert_after)
|
113
118
|
|
114
119
|
def swap(target, *args, &block)
|
115
120
|
index = assert_index(target, :before)
|
116
121
|
insert(index, *args, &block)
|
117
122
|
middlewares.delete_at(index + 1)
|
118
123
|
end
|
119
|
-
ruby2_keywords(:swap)
|
124
|
+
ruby2_keywords(:swap)
|
120
125
|
|
126
|
+
# Deletes a middleware from the middleware stack.
|
127
|
+
#
|
128
|
+
# Returns the array of middlewares not including the deleted item, or
|
129
|
+
# returns nil if the target is not found.
|
121
130
|
def delete(target)
|
122
|
-
middlewares.
|
131
|
+
middlewares.reject! { |m| m.name == target.name }
|
132
|
+
end
|
133
|
+
|
134
|
+
# Deletes a middleware from the middleware stack.
|
135
|
+
#
|
136
|
+
# Returns the array of middlewares not including the deleted item, or
|
137
|
+
# raises +RuntimeError+ if the target is not found.
|
138
|
+
def delete!(target)
|
139
|
+
delete(target) || (raise "No such middleware to remove: #{target.inspect}")
|
123
140
|
end
|
124
141
|
|
125
142
|
def move(target, source)
|
@@ -143,7 +160,7 @@ module ActionDispatch
|
|
143
160
|
def use(klass, *args, &block)
|
144
161
|
middlewares.push(build_middleware(klass, args, block))
|
145
162
|
end
|
146
|
-
ruby2_keywords(:use)
|
163
|
+
ruby2_keywords(:use)
|
147
164
|
|
148
165
|
def build(app = nil, &block)
|
149
166
|
instrumenting = ActiveSupport::Notifications.notifier.listening?(InstrumentationProxy::EVENT_NAME)
|
@@ -158,7 +175,7 @@ module ActionDispatch
|
|
158
175
|
|
159
176
|
private
|
160
177
|
def assert_index(index, where)
|
161
|
-
i = index.is_a?(Integer) ? index :
|
178
|
+
i = index.is_a?(Integer) ? index : index_of(index)
|
162
179
|
raise "No such middleware to insert #{where}: #{index.inspect}" unless i
|
163
180
|
i
|
164
181
|
end
|
@@ -166,5 +183,11 @@ module ActionDispatch
|
|
166
183
|
def build_middleware(klass, args, block)
|
167
184
|
Middleware.new(klass, args, block)
|
168
185
|
end
|
186
|
+
|
187
|
+
def index_of(klass)
|
188
|
+
middlewares.index do |m|
|
189
|
+
m.name == klass.name
|
190
|
+
end
|
191
|
+
end
|
169
192
|
end
|
170
193
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rack/utils"
|
4
|
-
require "active_support/core_ext/uri"
|
5
4
|
|
6
5
|
module ActionDispatch
|
6
|
+
# = Action Dispatch \Static
|
7
|
+
#
|
7
8
|
# This middleware serves static files from disk, if available.
|
8
9
|
# If no file is found, it hands off to the main app.
|
9
10
|
#
|
10
|
-
# In Rails apps, this middleware is configured to serve assets from
|
11
|
+
# In \Rails apps, this middleware is configured to serve assets from
|
11
12
|
# the +public/+ directory.
|
12
13
|
#
|
13
14
|
# Only GET and HEAD requests are served. POST and other HTTP methods
|
@@ -25,22 +26,24 @@ module ActionDispatch
|
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
|
-
#
|
29
|
+
# = Action Dispatch \FileHandler
|
30
|
+
#
|
31
|
+
# This endpoint serves static files from disk using +Rack::Files+.
|
29
32
|
#
|
30
33
|
# URL paths are matched with static files according to expected
|
31
34
|
# conventions: +path+, +path+.html, +path+/index.html.
|
32
35
|
#
|
33
36
|
# Precompressed versions of these files are checked first. Brotli (.br)
|
34
37
|
# and gzip (.gz) files are supported. If +path+.br exists, this
|
35
|
-
# endpoint returns that file with a <tt>
|
38
|
+
# endpoint returns that file with a <tt>content-encoding: br</tt> header.
|
36
39
|
#
|
37
|
-
# If no matching file is found, this endpoint responds 404 Not Found
|
40
|
+
# If no matching file is found, this endpoint responds <tt>404 Not Found</tt>.
|
38
41
|
#
|
39
42
|
# Pass the +root+ directory to search for matching files, an optional
|
40
43
|
# <tt>index: "index"</tt> to change the default +path+/index.html, and optional
|
41
44
|
# additional response headers.
|
42
45
|
class FileHandler
|
43
|
-
# Accept-Encoding value -> file extension
|
46
|
+
# +Accept-Encoding+ value -> file extension
|
44
47
|
PRECOMPRESSED = {
|
45
48
|
"br" => ".br",
|
46
49
|
"gzip" => ".gz",
|
@@ -54,7 +57,7 @@ module ActionDispatch
|
|
54
57
|
@precompressed = Array(precompressed).map(&:to_s) | %w[ identity ]
|
55
58
|
@compressible_content_types = compressible_content_types
|
56
59
|
|
57
|
-
@file_server = ::Rack::
|
60
|
+
@file_server = ::Rack::Files.new(@root, headers)
|
58
61
|
end
|
59
62
|
|
60
63
|
def call(env)
|
@@ -77,7 +80,7 @@ module ActionDispatch
|
|
77
80
|
request.path_info, ::Rack::Utils.escape_path(filepath).b
|
78
81
|
|
79
82
|
@file_server.call(request.env).tap do |status, headers, body|
|
80
|
-
# Omit
|
83
|
+
# Omit content-encoding/type/etc headers for 304 Not Modified
|
81
84
|
if status != 304
|
82
85
|
headers.update(content_headers)
|
83
86
|
end
|
@@ -105,7 +108,7 @@ module ActionDispatch
|
|
105
108
|
end
|
106
109
|
|
107
110
|
def try_files(filepath, content_type, accept_encoding:)
|
108
|
-
headers = {
|
111
|
+
headers = { Rack::CONTENT_TYPE => content_type }
|
109
112
|
|
110
113
|
if compressible? content_type
|
111
114
|
try_precompressed_files filepath, headers, accept_encoding: accept_encoding
|
@@ -125,10 +128,10 @@ module ActionDispatch
|
|
125
128
|
if content_encoding == "identity"
|
126
129
|
return precompressed_filepath, headers
|
127
130
|
else
|
128
|
-
headers[
|
131
|
+
headers[ActionDispatch::Constants::VARY] = "accept-encoding"
|
129
132
|
|
130
133
|
if accept_encoding.any? { |enc, _| /\b#{content_encoding}\b/i.match?(enc) }
|
131
|
-
headers[
|
134
|
+
headers[ActionDispatch::Constants::CONTENT_ENCODING] = content_encoding
|
132
135
|
return precompressed_filepath, headers
|
133
136
|
end
|
134
137
|
end
|
@@ -137,11 +140,8 @@ module ActionDispatch
|
|
137
140
|
end
|
138
141
|
|
139
142
|
def file_readable?(path)
|
140
|
-
|
141
|
-
|
142
|
-
false
|
143
|
-
else
|
144
|
-
file_stat.file? && file_stat.readable?
|
143
|
+
file_path = File.join(@root, path.b)
|
144
|
+
File.file?(file_path) && File.readable?(file_path)
|
145
145
|
end
|
146
146
|
|
147
147
|
def compressible?(content_type)
|
@@ -1,10 +1,10 @@
|
|
1
|
-
<% actions =
|
1
|
+
<% actions = exception_wrapper.actions %>
|
2
2
|
|
3
3
|
<% if actions.any? %>
|
4
4
|
<div class="actions">
|
5
5
|
<% actions.each do |action, _| %>
|
6
6
|
<%= button_to action, ActionDispatch::ActionableExceptions.endpoint, params: {
|
7
|
-
error:
|
7
|
+
error: exception_wrapper.exception_class_name,
|
8
8
|
action: action,
|
9
9
|
location: request.path
|
10
10
|
} %>
|
@@ -1,22 +1,22 @@
|
|
1
|
-
<% if
|
1
|
+
<% if exception_wrapper.has_corrections? %>
|
2
2
|
<div class="exception-message">
|
3
|
-
<%= simple_format h(
|
3
|
+
<%= simple_format h(exception_wrapper.original_message), { class: "message" }, wrapper_tag: "div" %>
|
4
4
|
</div>
|
5
5
|
<%
|
6
6
|
# The 'did_you_mean' gem can raise exceptions when calling #corrections on
|
7
7
|
# the exception. If it does there are no corrections to show.
|
8
|
-
corrections =
|
8
|
+
corrections = exception_wrapper.corrections rescue []
|
9
9
|
%>
|
10
10
|
<% if corrections.any? %>
|
11
11
|
<b>Did you mean?</b>
|
12
12
|
<ul>
|
13
13
|
<% corrections.each do |correction| %>
|
14
|
-
<li
|
14
|
+
<li class="correction"><%= h correction %></li>
|
15
15
|
<% end %>
|
16
16
|
</ul>
|
17
17
|
<% end %>
|
18
18
|
<% else %>
|
19
19
|
<div class="exception-message">
|
20
|
-
<%= simple_format h(
|
20
|
+
<%= simple_format h(exception_wrapper.message), { class: "message" }, wrapper_tag: "div" %>
|
21
21
|
</div>
|
22
22
|
<% end %>
|
@@ -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>
|
@@ -18,12 +18,19 @@
|
|
18
18
|
</td>
|
19
19
|
<td width="100%">
|
20
20
|
<pre>
|
21
|
-
<% source_extract[:code].each do |line, source|
|
21
|
+
<% source_extract[:code].each do |line, source| -%>
|
22
|
+
<div class="line<%= " active" if line == source_extract[:line_number] -%>"><% if source.is_a?(Array) -%><%= source[0] -%><span class="error_highlight"><%= source[1] -%></span><%= source[2] -%>
|
23
|
+
<% else -%>
|
24
|
+
<%= source -%>
|
25
|
+
<% end -%></div><% end -%>
|
22
26
|
</pre>
|
23
27
|
</td>
|
24
28
|
</tr>
|
25
29
|
</table>
|
26
30
|
</div>
|
31
|
+
<%- unless self.error_highlight_available? -%>
|
32
|
+
<p class="error_highlight_tip">Tip: You may want to add <code>gem 'error_highlight', '>= 0.4.0'</code> into your Gemfile, which will display the fine-grained error location.</p>
|
33
|
+
<%- end -%>
|
27
34
|
</div>
|
28
35
|
<% end %>
|
29
36
|
<% end %>
|
@@ -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,12 @@
|
|
1
1
|
<header>
|
2
|
-
<h1>Blocked
|
2
|
+
<h1>Blocked hosts: <%= @hosts.join(", ") %></h1>
|
3
3
|
</header>
|
4
|
-
<
|
5
|
-
<h2>To allow requests to
|
6
|
-
<pre>
|
7
|
-
|
4
|
+
<main role="main" id="container">
|
5
|
+
<h2>To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:</h2>
|
6
|
+
<pre>
|
7
|
+
<% @hosts.each do |host| %>
|
8
|
+
config.hosts << "<%= host %>"
|
9
|
+
<% end %>
|
10
|
+
</pre>
|
11
|
+
<p>For more details view: <a href="https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization">the Host Authorization guide</a></p>
|
12
|
+
</main>
|
@@ -1,5 +1,9 @@
|
|
1
|
-
Blocked
|
1
|
+
Blocked hosts: <%= @hosts.join(", ") %>
|
2
2
|
|
3
|
-
To allow requests to
|
3
|
+
To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:
|
4
4
|
|
5
|
-
|
5
|
+
<% @hosts.each do |host| %>
|
6
|
+
config.hosts << "<%= host %>"
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
For more details on host authorization view: https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization
|
@@ -1,35 +1,35 @@
|
|
1
1
|
<header>
|
2
2
|
<h1>
|
3
|
-
<%= @
|
3
|
+
<%= @exception_wrapper.exception_class_name %>
|
4
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
|
-
<
|
11
|
-
<%= render "rescues/message_and_suggestions", exception: @exception %>
|
12
|
-
<%= render "rescues/actions", exception: @exception, request: @request %>
|
10
|
+
<main role="main" id="container">
|
11
|
+
<%= render "rescues/message_and_suggestions", exception: @exception, exception_wrapper: @exception_wrapper %>
|
12
|
+
<%= render "rescues/actions", exception: @exception, request: @request, exception_wrapper: @exception_wrapper %>
|
13
13
|
|
14
14
|
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx, error_index: 0 %>
|
15
15
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show, error_index: 0 %>
|
16
16
|
|
17
|
-
<% if @
|
17
|
+
<% if @exception_wrapper.has_cause? %>
|
18
18
|
<h2>Exception Causes</h2>
|
19
19
|
<% end %>
|
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="#"
|
24
|
-
<%= wrapper.
|
23
|
+
<a class="summary" href="#" onclick="return toggle(<%= wrapper.exception_id %>)">
|
24
|
+
<%= wrapper.exception_class_name %>: <%= h wrapper.message %>
|
25
25
|
</a>
|
26
26
|
</div>
|
27
27
|
|
28
|
-
<div id="<%= wrapper.
|
28
|
+
<div id="<%= wrapper.exception_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,9 +1,9 @@
|
|
1
|
-
<%= @
|
1
|
+
<%= @exception_wrapper.exception_class_name %><%
|
2
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
|
|
6
|
-
<%= @
|
6
|
+
<%= @exception_wrapper.message %>
|
7
7
|
<%= render template: "rescues/_source" %>
|
8
8
|
<%= render template: "rescues/_trace" %>
|
9
9
|
<%= render template: "rescues/_request_and_response" %>
|
@@ -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>
|
@@ -3,6 +3,7 @@
|
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8" />
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
|
+
<meta name="turbo-visit-control" content="reload">
|
6
7
|
<title>Action Controller: Exception caught</title>
|
7
8
|
<style>
|
8
9
|
body {
|
@@ -49,11 +50,19 @@
|
|
49
50
|
line-height: 25px;
|
50
51
|
}
|
51
52
|
|
53
|
+
code.traces {
|
54
|
+
font-size: 11px;
|
55
|
+
}
|
56
|
+
|
57
|
+
.response-heading, .request-heading {
|
58
|
+
margin-top: 30px;
|
59
|
+
}
|
60
|
+
|
52
61
|
.exception-message {
|
53
62
|
padding: 8px 0;
|
54
63
|
}
|
55
64
|
|
56
|
-
.exception-message .message{
|
65
|
+
.exception-message .message {
|
57
66
|
margin-bottom: 8px;
|
58
67
|
line-height: 25px;
|
59
68
|
font-size: 1.5em;
|
@@ -75,6 +84,13 @@
|
|
75
84
|
display: block;
|
76
85
|
}
|
77
86
|
|
87
|
+
a.summary {
|
88
|
+
color: #F0F0F0;
|
89
|
+
text-decoration: none;
|
90
|
+
background: #C52F24;
|
91
|
+
border-bottom: none;
|
92
|
+
}
|
93
|
+
|
78
94
|
.details pre {
|
79
95
|
margin: 5px;
|
80
96
|
border: none;
|
@@ -114,7 +130,7 @@
|
|
114
130
|
|
115
131
|
.source .data .line_numbers {
|
116
132
|
background-color: #ECECEC;
|
117
|
-
color: #
|
133
|
+
color: #555;
|
118
134
|
padding: 1em .5em;
|
119
135
|
border-right: 1px solid #DDD;
|
120
136
|
text-align: right;
|
@@ -133,6 +149,18 @@
|
|
133
149
|
background-color: #FCC;
|
134
150
|
}
|
135
151
|
|
152
|
+
.error_highlight {
|
153
|
+
display: inline-block;
|
154
|
+
background-color: #FF9;
|
155
|
+
text-decoration: #F00 wavy underline;
|
156
|
+
}
|
157
|
+
|
158
|
+
.error_highlight_tip {
|
159
|
+
color: #666;
|
160
|
+
padding: 2px 2px;
|
161
|
+
font-size: 10px;
|
162
|
+
}
|
163
|
+
|
136
164
|
.button_to {
|
137
165
|
display: inline-block;
|
138
166
|
margin-top: 0.75em;
|
@@ -143,6 +171,10 @@
|
|
143
171
|
display: none;
|
144
172
|
}
|
145
173
|
|
174
|
+
.correction {
|
175
|
+
list-style-type: none;
|
176
|
+
}
|
177
|
+
|
146
178
|
input[type="submit"] {
|
147
179
|
color: white;
|
148
180
|
background-color: #C00;
|
@@ -153,6 +185,7 @@
|
|
153
185
|
font-weight: bold;
|
154
186
|
margin: 0;
|
155
187
|
padding: 10px 18px;
|
188
|
+
cursor: pointer;
|
156
189
|
-webkit-appearance: none;
|
157
190
|
}
|
158
191
|
input[type="submit"]:focus,
|
@@ -164,15 +197,14 @@
|
|
164
197
|
transform: translateY(1px)
|
165
198
|
}
|
166
199
|
|
167
|
-
|
168
200
|
a { color: #980905; }
|
169
201
|
a:visited { color: #666; }
|
170
202
|
a.trace-frames {
|
171
203
|
color: #666;
|
172
204
|
overflow-wrap: break-word;
|
173
205
|
}
|
174
|
-
a:hover { color: #C00; }
|
175
|
-
a.
|
206
|
+
a:hover, a.trace-frames.selected { color: #C00; }
|
207
|
+
a.summary:hover { color: #FFF; }
|
176
208
|
|
177
209
|
@media (prefers-color-scheme: dark) {
|
178
210
|
body {
|
@@ -180,11 +212,7 @@
|
|
180
212
|
color: #ECECEC;
|
181
213
|
}
|
182
214
|
|
183
|
-
.details {
|
184
|
-
border-color: #666;
|
185
|
-
}
|
186
|
-
|
187
|
-
.summary {
|
215
|
+
.details, .summary {
|
188
216
|
border-color: #666;
|
189
217
|
}
|
190
218
|
|
@@ -210,6 +238,10 @@
|
|
210
238
|
background-color: #900;
|
211
239
|
}
|
212
240
|
|
241
|
+
.error_highlight {
|
242
|
+
color: #333;
|
243
|
+
}
|
244
|
+
|
213
245
|
input[type="submit"] {
|
214
246
|
box-shadow: 0 3px #800;
|
215
247
|
}
|
@@ -219,8 +251,7 @@
|
|
219
251
|
|
220
252
|
a { color: #C00; }
|
221
253
|
a.trace-frames { color: #999; }
|
222
|
-
a:hover { color: #E9382B; }
|
223
|
-
a.trace-frames.selected { color: #E9382B; }
|
254
|
+
a:hover, a.trace-frames.selected { color: #E9382B; }
|
224
255
|
}
|
225
256
|
|
226
257
|
<%= yield :style %>
|
@@ -228,8 +259,7 @@
|
|
228
259
|
|
229
260
|
<script>
|
230
261
|
var toggle = function(id) {
|
231
|
-
|
232
|
-
s.display = s.display == 'none' ? 'block' : 'none';
|
262
|
+
document.getElementById(id).classList.toggle('hidden');
|
233
263
|
return false;
|
234
264
|
}
|
235
265
|
var show = function(id) {
|
@@ -238,9 +268,6 @@
|
|
238
268
|
var hide = function(id) {
|
239
269
|
document.getElementById(id).style.display = 'none';
|
240
270
|
}
|
241
|
-
var toggleTrace = function() {
|
242
|
-
return toggle('blame_trace');
|
243
|
-
}
|
244
271
|
var toggleSessionDump = function() {
|
245
272
|
return toggle('session_dump');
|
246
273
|
}
|
@@ -251,7 +278,7 @@
|
|
251
278
|
</head>
|
252
279
|
<body>
|
253
280
|
|
254
|
-
<%= yield %>
|
281
|
+
<%= yield %>
|
255
282
|
|
256
283
|
</body>
|
257
284
|
</html>
|
@@ -1,19 +1,23 @@
|
|
1
|
-
<header>
|
2
|
-
<h1>No template for interactive request</h1>
|
1
|
+
<header role="banner">
|
2
|
+
<h1>No view template for interactive request</h1>
|
3
3
|
</header>
|
4
4
|
|
5
|
-
<
|
5
|
+
<main id="container">
|
6
6
|
<h2><%= h @exception.message %></h2>
|
7
7
|
|
8
|
-
<
|
9
|
-
<
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
<div class="summary">
|
9
|
+
<p>
|
10
|
+
<strong>NOTE:</strong> Rails usually expects a controller action to render a view template with the same name.
|
11
|
+
</p>
|
12
|
+
<p>
|
13
|
+
For example, a <code><%= @exception.controller %>#<%= @exception.action_name %></code> action defined in <code>app/controllers/<%= @exception.controller.controller_path %>_controller.rb</code> should have a corresponding view template
|
14
|
+
in a file named <code>app/views/<%= @exception.controller.controller_name %>/<%= @exception.action_name %>.html.erb</code>.
|
15
|
+
</p>
|
16
|
+
<p>
|
17
|
+
However, if this controller is an API endpoint responding with 204 (No Content), which does not require a view template because it doesn't serve an HTML response, then this error will occur when trying to access it with a browser. In this particular scenario, you can ignore this error.
|
18
|
+
</p>
|
19
|
+
<p>
|
20
|
+
You can find more about view template rendering conventions in the <a href="https://guides.rubyonrails.org/layouts_and_rendering.html#rendering-by-default-convention-over-configuration-in-action">Rails Guides on Layouts and Rendering in Rails</a>.
|
21
|
+
</p>
|
22
|
+
</div>
|
23
|
+
</main>
|