actionpack 7.0.8.7 → 7.2.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +90 -537
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +119 -106
- data/lib/abstract_controller/caching/fragments.rb +51 -52
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +94 -67
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +9 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +121 -91
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
- data/lib/abstract_controller/rendering.rb +14 -13
- data/lib/abstract_controller/translation.rb +12 -30
- data/lib/abstract_controller/url_for.rb +9 -5
- data/lib/abstract_controller.rb +8 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +78 -73
- data/lib/action_controller/base.rb +199 -141
- data/lib/action_controller/caching.rb +16 -11
- data/lib/action_controller/deprecator.rb +9 -0
- data/lib/action_controller/form_builder.rb +21 -16
- data/lib/action_controller/log_subscriber.rb +19 -5
- data/lib/action_controller/metal/allow_browser.rb +123 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +187 -174
- data/lib/action_controller/metal/content_security_policy.rb +26 -25
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +65 -54
- data/lib/action_controller/metal/default_headers.rb +6 -2
- data/lib/action_controller/metal/etag_with_flash.rb +4 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
- data/lib/action_controller/metal/exceptions.rb +19 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +20 -16
- data/lib/action_controller/metal/helpers.rb +64 -67
- data/lib/action_controller/metal/http_authentication.rb +212 -199
- data/lib/action_controller/metal/implicit_render.rb +21 -17
- data/lib/action_controller/metal/instrumentation.rb +22 -12
- data/lib/action_controller/metal/live.rb +125 -92
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +58 -58
- data/lib/action_controller/metal/permissions_policy.rb +14 -13
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +110 -84
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -82
- data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
- data/lib/action_controller/metal/rescue.rb +12 -8
- data/lib/action_controller/metal/streaming.rb +174 -132
- data/lib/action_controller/metal/strong_parameters.rb +598 -473
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +23 -14
- data/lib/action_controller/metal.rb +145 -61
- data/lib/action_controller/railtie.rb +25 -9
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +105 -66
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +157 -128
- data/lib/action_controller.rb +17 -3
- data/lib/action_dispatch/constants.rb +34 -0
- data/lib/action_dispatch/deprecator.rb +9 -0
- data/lib/action_dispatch/http/cache.rb +28 -29
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +48 -45
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +23 -21
- data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
- data/lib/action_dispatch/http/mime_type.rb +60 -30
- data/lib/action_dispatch/http/mime_types.rb +5 -1
- data/lib/action_dispatch/http/parameters.rb +12 -10
- data/lib/action_dispatch/http/permissions_policy.rb +32 -27
- data/lib/action_dispatch/http/rack_cache.rb +4 -0
- data/lib/action_dispatch/http/request.rb +132 -79
- data/lib/action_dispatch/http/response.rb +136 -103
- data/lib/action_dispatch/http/upload.rb +19 -15
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +19 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +18 -15
- data/lib/action_dispatch/journey/route.rb +12 -9
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +13 -10
- data/lib/action_dispatch/journey/routes.rb +6 -4
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +25 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
- data/lib/action_dispatch/middleware/callbacks.rb +4 -0
- data/lib/action_dispatch/middleware/cookies.rb +192 -194
- data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
- data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
- data/lib/action_dispatch/middleware/debug_view.rb +9 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
- data/lib/action_dispatch/middleware/executor.rb +9 -1
- data/lib/action_dispatch/middleware/flash.rb +65 -46
- data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
- data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
- data/lib/action_dispatch/middleware/reloader.rb +9 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
- data/lib/action_dispatch/middleware/request_id.rb +15 -8
- data/lib/action_dispatch/middleware/server_timing.rb +8 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
- data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
- data/lib/action_dispatch/middleware/ssl.rb +60 -45
- data/lib/action_dispatch/middleware/stack.rb +15 -9
- data/lib/action_dispatch/middleware/static.rb +40 -34
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- 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 +47 -38
- data/lib/action_dispatch/railtie.rb +12 -4
- data/lib/action_dispatch/request/session.rb +39 -27
- data/lib/action_dispatch/request/utils.rb +10 -3
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +59 -9
- data/lib/action_dispatch/routing/mapper.rb +686 -639
- data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
- data/lib/action_dispatch/routing/redirection.rb +52 -38
- data/lib/action_dispatch/routing/route_set.rb +106 -62
- data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
- data/lib/action_dispatch/routing/url_for.rb +131 -122
- data/lib/action_dispatch/routing.rb +152 -150
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +27 -19
- data/lib/action_dispatch/system_testing/driver.rb +16 -22
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +9 -7
- data/lib/action_dispatch/testing/assertions/response.rb +36 -26
- data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
- data/lib/action_dispatch/testing/assertions.rb +5 -1
- data/lib/action_dispatch/testing/integration.rb +240 -229
- data/lib/action_dispatch/testing/request_encoder.rb +6 -1
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +14 -9
- data/lib/action_dispatch/testing/test_request.rb +4 -2
- data/lib/action_dispatch/testing/test_response.rb +34 -19
- data/lib/action_dispatch.rb +52 -21
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +18 -17
- metadata +86 -27
@@ -1,16 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "rack/utils"
|
4
6
|
|
5
7
|
module ActionDispatch
|
6
|
-
#
|
7
|
-
#
|
8
|
+
# # Action Dispatch Static
|
9
|
+
#
|
10
|
+
# This middleware serves static files from disk, if available. If no file is
|
11
|
+
# found, it hands off to the main app.
|
8
12
|
#
|
9
|
-
# In Rails apps, this middleware is configured to serve assets from
|
10
|
-
#
|
13
|
+
# In Rails apps, this middleware is configured to serve assets from the
|
14
|
+
# `public/` directory.
|
11
15
|
#
|
12
|
-
# Only GET and HEAD requests are served. POST and other HTTP methods
|
13
|
-
#
|
16
|
+
# Only GET and HEAD requests are served. POST and other HTTP methods are handed
|
17
|
+
# off to the main app.
|
14
18
|
#
|
15
19
|
# Only files in the root directory are served; path traversal is denied.
|
16
20
|
class Static
|
@@ -24,36 +28,38 @@ module ActionDispatch
|
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
#
|
31
|
+
# # Action Dispatch FileHandler
|
32
|
+
#
|
33
|
+
# This endpoint serves static files from disk using `Rack::Files`.
|
28
34
|
#
|
29
|
-
# URL paths are matched with static files according to expected
|
30
|
-
#
|
35
|
+
# URL paths are matched with static files according to expected conventions:
|
36
|
+
# `path`, `path`.html, `path`/index.html.
|
31
37
|
#
|
32
|
-
# Precompressed versions of these files are checked first. Brotli (.br)
|
33
|
-
#
|
34
|
-
#
|
38
|
+
# Precompressed versions of these files are checked first. Brotli (.br) and gzip
|
39
|
+
# (.gz) files are supported. If `path`.br exists, this endpoint returns that
|
40
|
+
# file with a `content-encoding: br` header.
|
35
41
|
#
|
36
|
-
# If no matching file is found, this endpoint responds
|
42
|
+
# If no matching file is found, this endpoint responds `404 Not Found`.
|
37
43
|
#
|
38
|
-
# Pass the
|
39
|
-
#
|
40
|
-
#
|
44
|
+
# Pass the `root` directory to search for matching files, an optional `index:
|
45
|
+
# "index"` to change the default `path`/index.html, and optional additional
|
46
|
+
# response headers.
|
41
47
|
class FileHandler
|
42
|
-
#
|
48
|
+
# `Accept-Encoding` value -> file extension
|
43
49
|
PRECOMPRESSED = {
|
44
50
|
"br" => ".br",
|
45
51
|
"gzip" => ".gz",
|
46
52
|
"identity" => nil
|
47
53
|
}
|
48
54
|
|
49
|
-
def initialize(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript)/)
|
55
|
+
def initialize(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript|image\/svg\+xml)/)
|
50
56
|
@root = root.chomp("/").b
|
51
57
|
@index = index
|
52
58
|
|
53
59
|
@precompressed = Array(precompressed).map(&:to_s) | %w[ identity ]
|
54
60
|
@compressible_content_types = compressible_content_types
|
55
61
|
|
56
|
-
@file_server = ::Rack::
|
62
|
+
@file_server = ::Rack::Files.new(@root, headers)
|
57
63
|
end
|
58
64
|
|
59
65
|
def call(env)
|
@@ -76,7 +82,7 @@ module ActionDispatch
|
|
76
82
|
request.path_info, ::Rack::Utils.escape_path(filepath).b
|
77
83
|
|
78
84
|
@file_server.call(request.env).tap do |status, headers, body|
|
79
|
-
# Omit
|
85
|
+
# Omit content-encoding/type/etc headers for 304 Not Modified
|
80
86
|
if status != 304
|
81
87
|
headers.update(content_headers)
|
82
88
|
end
|
@@ -87,11 +93,11 @@ module ActionDispatch
|
|
87
93
|
|
88
94
|
# Match a URI path to a static file to be served.
|
89
95
|
#
|
90
|
-
# Used by the
|
91
|
-
#
|
96
|
+
# Used by the `Static` class to negotiate a servable file in the `public/`
|
97
|
+
# directory (see Static#call).
|
92
98
|
#
|
93
|
-
# Checks for
|
94
|
-
#
|
99
|
+
# Checks for `path`, `path`.html, and `path`/index.html files, in that order,
|
100
|
+
# including .br and .gzip compressed extensions.
|
95
101
|
#
|
96
102
|
# If a matching file is found, the path and necessary response headers
|
97
103
|
# (Content-Type, Content-Encoding) are returned.
|
@@ -104,7 +110,7 @@ module ActionDispatch
|
|
104
110
|
end
|
105
111
|
|
106
112
|
def try_files(filepath, content_type, accept_encoding:)
|
107
|
-
headers = {
|
113
|
+
headers = { Rack::CONTENT_TYPE => content_type }
|
108
114
|
|
109
115
|
if compressible? content_type
|
110
116
|
try_precompressed_files filepath, headers, accept_encoding: accept_encoding
|
@@ -116,18 +122,18 @@ module ActionDispatch
|
|
116
122
|
def try_precompressed_files(filepath, headers, accept_encoding:)
|
117
123
|
each_precompressed_filepath(filepath) do |content_encoding, precompressed_filepath|
|
118
124
|
if file_readable? precompressed_filepath
|
119
|
-
# Identity encoding is default, so we skip Accept-Encoding
|
120
|
-
#
|
125
|
+
# Identity encoding is default, so we skip Accept-Encoding negotiation and
|
126
|
+
# needn't set Content-Encoding.
|
121
127
|
#
|
122
|
-
# Vary header is expected when we've found other available
|
123
|
-
#
|
128
|
+
# Vary header is expected when we've found other available encodings that
|
129
|
+
# Accept-Encoding ruled out.
|
124
130
|
if content_encoding == "identity"
|
125
131
|
return precompressed_filepath, headers
|
126
132
|
else
|
127
|
-
headers[
|
133
|
+
headers[ActionDispatch::Constants::VARY] = "accept-encoding"
|
128
134
|
|
129
135
|
if accept_encoding.any? { |enc, _| /\b#{content_encoding}\b/i.match?(enc) }
|
130
|
-
headers[
|
136
|
+
headers[ActionDispatch::Constants::CONTENT_ENCODING] = content_encoding
|
131
137
|
return precompressed_filepath, headers
|
132
138
|
end
|
133
139
|
end
|
@@ -160,9 +166,9 @@ module ActionDispatch
|
|
160
166
|
content_type = ::Rack::Mime.mime_type(ext, nil)
|
161
167
|
yield path, content_type || "text/plain"
|
162
168
|
|
163
|
-
# Tack on .html and /index.html only for paths that don't have
|
164
|
-
#
|
165
|
-
#
|
169
|
+
# Tack on .html and /index.html only for paths that don't have an explicit,
|
170
|
+
# resolvable file extension. No need to check for foo.js.html and
|
171
|
+
# foo.js/index.html.
|
166
172
|
unless content_type
|
167
173
|
default_ext = ::ActionController::Base.default_static_extension
|
168
174
|
if ext != default_ext
|
@@ -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,11 +1,11 @@
|
|
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>
|
@@ -17,6 +17,6 @@
|
|
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 %>
|
@@ -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 %>
|
@@ -1,6 +1,6 @@
|
|
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 %>
|
@@ -8,24 +8,24 @@
|
|
8
8
|
</header>
|
9
9
|
|
10
10
|
<main role="main" id="container">
|
11
|
-
<%= render "rescues/message_and_suggestions", exception: @exception %>
|
12
|
-
<%= render "rescues/actions", exception: @exception, request: @request %>
|
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="#" onclick="return toggle(<%= wrapper.
|
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>
|
@@ -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" %>
|
@@ -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 {
|
@@ -148,6 +149,18 @@
|
|
148
149
|
background-color: #FCC;
|
149
150
|
}
|
150
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
|
+
|
151
164
|
.button_to {
|
152
165
|
display: inline-block;
|
153
166
|
margin-top: 0.75em;
|
@@ -225,6 +238,10 @@
|
|
225
238
|
background-color: #900;
|
226
239
|
}
|
227
240
|
|
241
|
+
.error_highlight {
|
242
|
+
color: #333;
|
243
|
+
}
|
244
|
+
|
228
245
|
input[type="submit"] {
|
229
246
|
box-shadow: 0 3px #800;
|
230
247
|
}
|
@@ -1,19 +1,23 @@
|
|
1
1
|
<header role="banner">
|
2
|
-
<h1>No template for interactive request</h1>
|
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
|
-
|
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_path %>/<%= @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>
|
19
23
|
</main>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
</header>
|
4
4
|
|
5
5
|
<main role="main" id="container">
|
6
|
-
<h2><%= h @
|
6
|
+
<h2><%= h @exception_wrapper.message %></h2>
|
7
7
|
|
8
8
|
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
9
9
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
@@ -2,12 +2,12 @@
|
|
2
2
|
<h1>Routing Error</h1>
|
3
3
|
</header>
|
4
4
|
<main role="main" id="container">
|
5
|
-
<h2><%= h @
|
6
|
-
<% unless @
|
5
|
+
<h2><%= h @exception_wrapper.message %></h2>
|
6
|
+
<% unless @exception_wrapper.failures.empty? %>
|
7
7
|
<p>
|
8
8
|
<h2>Failure reasons:</h2>
|
9
9
|
<ol>
|
10
|
-
<% @
|
10
|
+
<% @exception_wrapper.failures.each do |route, reason| %>
|
11
11
|
<li><code><%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %></li>
|
12
12
|
<% end %>
|
13
13
|
</ol>
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<header role="banner">
|
2
2
|
<h1>
|
3
|
-
<%= @
|
3
|
+
<%= @exception_wrapper.exception_name %> in
|
4
4
|
<%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
|
5
5
|
</h1>
|
6
6
|
</header>
|
7
7
|
|
8
8
|
<main role="main" id="container">
|
9
9
|
<p>
|
10
|
-
Showing <i><%= @
|
10
|
+
Showing <i><%= @exception_wrapper.file_name %></i> where line <b>#<%= @exception_wrapper.line_number %></b> raised:
|
11
11
|
</p>
|
12
|
-
<pre><code><%= h @
|
12
|
+
<pre><code><%= h @exception_wrapper.message %></code></pre>
|
13
13
|
|
14
14
|
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
15
15
|
|
16
|
-
<p><%= @
|
16
|
+
<p><%= @exception_wrapper.sub_template_message %></p>
|
17
17
|
|
18
18
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
19
19
|
<%= render template: "rescues/_request_and_response" %>
|
@@ -1,24 +1,45 @@
|
|
1
1
|
<% content_for :style do %>
|
2
|
+
h2, p {
|
3
|
+
padding-left: 30px;
|
4
|
+
}
|
5
|
+
|
2
6
|
#route_table {
|
3
7
|
margin: 0;
|
4
8
|
border-collapse: collapse;
|
9
|
+
word-wrap:break-word;
|
10
|
+
table-layout: fixed;
|
11
|
+
width:100%;
|
5
12
|
}
|
6
13
|
|
7
14
|
#route_table thead tr {
|
8
15
|
border-bottom: 2px solid #ddd;
|
9
16
|
}
|
10
17
|
|
18
|
+
#route_table th {
|
19
|
+
padding-left: 30px;
|
20
|
+
text-align: left;
|
21
|
+
}
|
22
|
+
|
11
23
|
#route_table thead tr.bottom {
|
12
24
|
border-bottom: none;
|
13
25
|
}
|
14
26
|
|
15
27
|
#route_table thead tr.bottom th {
|
16
|
-
padding: 10px
|
28
|
+
padding: 10px 30px;
|
17
29
|
line-height: 15px;
|
18
30
|
}
|
19
31
|
|
20
|
-
#route_table
|
32
|
+
#route_table #search_container {
|
33
|
+
padding: 7px 30px;
|
34
|
+
}
|
35
|
+
|
36
|
+
#route_table thead tr th input#search {
|
21
37
|
-webkit-appearance: textfield;
|
38
|
+
width:100%;
|
39
|
+
}
|
40
|
+
|
41
|
+
#route_table thead th.http-verb {
|
42
|
+
width: 10%;
|
22
43
|
}
|
23
44
|
|
24
45
|
#route_table tbody tr {
|
@@ -45,11 +66,6 @@
|
|
45
66
|
padding: 4px 30px;
|
46
67
|
}
|
47
68
|
|
48
|
-
#path_search {
|
49
|
-
width: 80%;
|
50
|
-
font-size: inherit;
|
51
|
-
}
|
52
|
-
|
53
69
|
@media (prefers-color-scheme: dark) {
|
54
70
|
#route_table tbody tr:nth-child(odd) {
|
55
71
|
background: #282828;
|
@@ -62,28 +78,22 @@
|
|
62
78
|
}
|
63
79
|
<% end %>
|
64
80
|
|
65
|
-
<table id='route_table'
|
81
|
+
<table id='route_table'>
|
66
82
|
<thead>
|
67
83
|
<tr>
|
68
|
-
<th>Helper
|
69
|
-
|
70
|
-
<th>Path</th>
|
71
|
-
<th>Controller#Action</th>
|
72
|
-
</tr>
|
73
|
-
<tr class='bottom'>
|
74
|
-
<th><%# Helper %>
|
75
|
-
<%= link_to "Path", "#", 'data-route-helper' => '_path',
|
84
|
+
<th>Helper
|
85
|
+
(<%= link_to "Path", "#", 'data-route-helper' => '_path',
|
76
86
|
title: "Returns a relative path (without the http or domain)" %> /
|
77
87
|
<%= link_to "Url", "#", 'data-route-helper' => '_url',
|
78
|
-
title: "Returns an absolute URL (with the http and domain)" %>
|
79
|
-
</th>
|
80
|
-
<th><%# HTTP Verb %>
|
81
|
-
</th>
|
82
|
-
<th><%# Path %>
|
83
|
-
<%= search_field(:path, nil, id: 'search', placeholder: "Path Match") %>
|
84
|
-
</th>
|
85
|
-
<th><%# Controller#action %>
|
88
|
+
title: "Returns an absolute URL (with the http and domain)" %>)
|
86
89
|
</th>
|
90
|
+
<th class="http-verb">HTTP Verb</th>
|
91
|
+
<th>Path</th>
|
92
|
+
<th>Controller#Action</th>
|
93
|
+
<th>Source Location</th>
|
94
|
+
</tr>
|
95
|
+
<tr>
|
96
|
+
<th colspan="5" id="search_container"><%= search_field(:query, nil, id: 'search', placeholder: "Search") %></th>
|
87
97
|
</tr>
|
88
98
|
</thead>
|
89
99
|
<tbody class='exact_matches' id='exact_matches'>
|
@@ -99,8 +109,8 @@
|
|
99
109
|
// support forEach iterator on NodeList
|
100
110
|
NodeList.prototype.forEach = Array.prototype.forEach;
|
101
111
|
|
102
|
-
// Enables
|
103
|
-
function
|
112
|
+
// Enables query search functionality
|
113
|
+
function setupMatchingRoutes() {
|
104
114
|
// Check if there are any matched results in a section
|
105
115
|
function checkNoMatch(section, trElement) {
|
106
116
|
if (section.children.length <= 1) {
|
@@ -128,8 +138,8 @@
|
|
128
138
|
}
|
129
139
|
|
130
140
|
// remove params or fragments
|
131
|
-
function
|
132
|
-
return
|
141
|
+
function sanitizeQuery(query) {
|
142
|
+
return query.replace(/[#?].*/, '');
|
133
143
|
}
|
134
144
|
|
135
145
|
var pathElements = document.querySelectorAll('#route_table [data-route-path]'),
|
@@ -148,7 +158,7 @@
|
|
148
158
|
function buildTr(string) {
|
149
159
|
var tr = document.createElement('tr');
|
150
160
|
var th = document.createElement('th');
|
151
|
-
th.setAttribute('colspan',
|
161
|
+
th.setAttribute('colspan', 5);
|
152
162
|
tr.appendChild(th);
|
153
163
|
th.innerText = string;
|
154
164
|
return tr;
|
@@ -156,16 +166,16 @@
|
|
156
166
|
|
157
167
|
// On key press perform a search for matching paths
|
158
168
|
delayedKeyup(searchElem, function() {
|
159
|
-
var
|
160
|
-
defaultExactMatch = buildTr(
|
161
|
-
defaultFuzzyMatch = buildTr(
|
162
|
-
noExactMatch = buildTr('No
|
163
|
-
noFuzzyMatch = buildTr('No
|
169
|
+
var query = sanitizeQuery(searchElem.value),
|
170
|
+
defaultExactMatch = buildTr("Routes matching '" + query + "':"),
|
171
|
+
defaultFuzzyMatch = buildTr("Routes containing '" + query + "':"),
|
172
|
+
noExactMatch = buildTr('No exact matches found'),
|
173
|
+
noFuzzyMatch = buildTr('No fuzzy matches found');
|
164
174
|
|
165
|
-
if (!
|
175
|
+
if (!query)
|
166
176
|
return searchElem.onblur();
|
167
177
|
|
168
|
-
getJSON('/rails/info/routes?
|
178
|
+
getJSON('/rails/info/routes?query=' + query, function(matches){
|
169
179
|
// Clear out results section
|
170
180
|
exactSection.replaceChildren(defaultExactMatch);
|
171
181
|
fuzzySection.replaceChildren(defaultFuzzyMatch);
|
@@ -173,7 +183,6 @@
|
|
173
183
|
// Display exact matches and fuzzy matches
|
174
184
|
pathElements.forEach(function(elem) {
|
175
185
|
var elemPath = elem.getAttribute('data-route-path');
|
176
|
-
|
177
186
|
if (matches['exact'].indexOf(elemPath) != -1)
|
178
187
|
exactSection.appendChild(elem.parentNode.cloneNode(true));
|
179
188
|
|
@@ -215,7 +224,7 @@
|
|
215
224
|
});
|
216
225
|
}
|
217
226
|
|
218
|
-
|
227
|
+
setupMatchingRoutes();
|
219
228
|
setupRouteToggleHelperLinks();
|
220
229
|
|
221
230
|
// Focus the search input after page has loaded
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "action_dispatch"
|
6
|
+
require "action_dispatch/log_subscriber"
|
4
7
|
require "active_support/messages/rotation_configuration"
|
5
8
|
|
6
9
|
module ActionDispatch
|
@@ -8,7 +11,7 @@ module ActionDispatch
|
|
8
11
|
config.action_dispatch = ActiveSupport::OrderedOptions.new
|
9
12
|
config.action_dispatch.x_sendfile_header = nil
|
10
13
|
config.action_dispatch.ip_spoofing_check = true
|
11
|
-
config.action_dispatch.show_exceptions =
|
14
|
+
config.action_dispatch.show_exceptions = :all
|
12
15
|
config.action_dispatch.tld_length = 1
|
13
16
|
config.action_dispatch.ignore_accept_header = false
|
14
17
|
config.action_dispatch.rescue_templates = {}
|
@@ -23,9 +26,9 @@ module ActionDispatch
|
|
23
26
|
config.action_dispatch.use_authenticated_cookie_encryption = false
|
24
27
|
config.action_dispatch.use_cookies_with_metadata = false
|
25
28
|
config.action_dispatch.perform_deep_munge = true
|
26
|
-
config.action_dispatch.request_id_header =
|
27
|
-
config.action_dispatch.return_only_request_media_type_on_content_type = true
|
29
|
+
config.action_dispatch.request_id_header = ActionDispatch::Constants::X_REQUEST_ID
|
28
30
|
config.action_dispatch.log_rescued_responses = true
|
31
|
+
config.action_dispatch.debug_exception_log_level = :fatal
|
29
32
|
|
30
33
|
config.action_dispatch.default_headers = {
|
31
34
|
"X-Frame-Options" => "SAMEORIGIN",
|
@@ -40,13 +43,16 @@ module ActionDispatch
|
|
40
43
|
|
41
44
|
config.eager_load_namespaces << ActionDispatch
|
42
45
|
|
46
|
+
initializer "action_dispatch.deprecator", before: :load_environment_config do |app|
|
47
|
+
app.deprecators[:action_dispatch] = ActionDispatch.deprecator
|
48
|
+
end
|
49
|
+
|
43
50
|
initializer "action_dispatch.configure" do |app|
|
44
51
|
ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
|
45
52
|
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
|
46
53
|
|
47
54
|
ActiveSupport.on_load(:action_dispatch_request) do
|
48
55
|
self.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
|
49
|
-
self.return_only_media_type_on_content_type = app.config.action_dispatch.return_only_request_media_type_on_content_type
|
50
56
|
ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
|
51
57
|
end
|
52
58
|
|
@@ -61,6 +67,8 @@ module ActionDispatch
|
|
61
67
|
config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
|
62
68
|
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
|
63
69
|
|
70
|
+
ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
|
71
|
+
|
64
72
|
ActionDispatch.test_app = app
|
65
73
|
end
|
66
74
|
end
|