actionpack 6.1.7.5 → 7.1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- 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>
|