omg-actionpack 8.0.0.alpha1
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 +7 -0
- data/CHANGELOG.md +129 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +57 -0
- data/lib/abstract_controller/asset_paths.rb +14 -0
- data/lib/abstract_controller/base.rb +299 -0
- data/lib/abstract_controller/caching/fragments.rb +149 -0
- data/lib/abstract_controller/caching.rb +68 -0
- data/lib/abstract_controller/callbacks.rb +265 -0
- data/lib/abstract_controller/collector.rb +44 -0
- data/lib/abstract_controller/deprecator.rb +9 -0
- data/lib/abstract_controller/error.rb +8 -0
- data/lib/abstract_controller/helpers.rb +243 -0
- data/lib/abstract_controller/logger.rb +16 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +25 -0
- data/lib/abstract_controller/rendering.rb +126 -0
- data/lib/abstract_controller/translation.rb +42 -0
- data/lib/abstract_controller/url_for.rb +37 -0
- data/lib/abstract_controller.rb +36 -0
- data/lib/action_controller/api/api_rendering.rb +18 -0
- data/lib/action_controller/api.rb +155 -0
- data/lib/action_controller/base.rb +332 -0
- data/lib/action_controller/caching.rb +49 -0
- data/lib/action_controller/deprecator.rb +9 -0
- data/lib/action_controller/form_builder.rb +55 -0
- data/lib/action_controller/log_subscriber.rb +96 -0
- data/lib/action_controller/metal/allow_browser.rb +123 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
- data/lib/action_controller/metal/conditional_get.rb +341 -0
- data/lib/action_controller/metal/content_security_policy.rb +86 -0
- data/lib/action_controller/metal/cookies.rb +20 -0
- data/lib/action_controller/metal/data_streaming.rb +154 -0
- data/lib/action_controller/metal/default_headers.rb +21 -0
- data/lib/action_controller/metal/etag_with_flash.rb +22 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +59 -0
- data/lib/action_controller/metal/exceptions.rb +106 -0
- data/lib/action_controller/metal/flash.rb +67 -0
- data/lib/action_controller/metal/head.rb +67 -0
- data/lib/action_controller/metal/helpers.rb +129 -0
- data/lib/action_controller/metal/http_authentication.rb +565 -0
- data/lib/action_controller/metal/implicit_render.rb +67 -0
- data/lib/action_controller/metal/instrumentation.rb +120 -0
- data/lib/action_controller/metal/live.rb +398 -0
- data/lib/action_controller/metal/logging.rb +22 -0
- data/lib/action_controller/metal/mime_responds.rb +337 -0
- data/lib/action_controller/metal/parameter_encoding.rb +84 -0
- data/lib/action_controller/metal/params_wrapper.rb +312 -0
- data/lib/action_controller/metal/permissions_policy.rb +38 -0
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +251 -0
- data/lib/action_controller/metal/renderers.rb +181 -0
- data/lib/action_controller/metal/rendering.rb +260 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +667 -0
- data/lib/action_controller/metal/rescue.rb +33 -0
- data/lib/action_controller/metal/streaming.rb +183 -0
- data/lib/action_controller/metal/strong_parameters.rb +1546 -0
- data/lib/action_controller/metal/testing.rb +25 -0
- data/lib/action_controller/metal/url_for.rb +65 -0
- data/lib/action_controller/metal.rb +339 -0
- data/lib/action_controller/railtie.rb +149 -0
- data/lib/action_controller/railties/helpers.rb +26 -0
- data/lib/action_controller/renderer.rb +161 -0
- data/lib/action_controller/template_assertions.rb +13 -0
- data/lib/action_controller/test_case.rb +691 -0
- data/lib/action_controller.rb +80 -0
- data/lib/action_dispatch/constants.rb +34 -0
- data/lib/action_dispatch/deprecator.rb +9 -0
- data/lib/action_dispatch/http/cache.rb +249 -0
- data/lib/action_dispatch/http/content_disposition.rb +47 -0
- data/lib/action_dispatch/http/content_security_policy.rb +365 -0
- data/lib/action_dispatch/http/filter_parameters.rb +80 -0
- data/lib/action_dispatch/http/filter_redirect.rb +50 -0
- data/lib/action_dispatch/http/headers.rb +134 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +187 -0
- data/lib/action_dispatch/http/mime_type.rb +389 -0
- data/lib/action_dispatch/http/mime_types.rb +54 -0
- data/lib/action_dispatch/http/parameters.rb +119 -0
- data/lib/action_dispatch/http/permissions_policy.rb +189 -0
- data/lib/action_dispatch/http/rack_cache.rb +67 -0
- data/lib/action_dispatch/http/request.rb +498 -0
- data/lib/action_dispatch/http/response.rb +556 -0
- data/lib/action_dispatch/http/upload.rb +107 -0
- data/lib/action_dispatch/http/url.rb +344 -0
- data/lib/action_dispatch/journey/formatter.rb +226 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +149 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +50 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +217 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +27 -0
- data/lib/action_dispatch/journey/nodes/node.rb +208 -0
- data/lib/action_dispatch/journey/parser.rb +103 -0
- data/lib/action_dispatch/journey/path/pattern.rb +209 -0
- data/lib/action_dispatch/journey/route.rb +189 -0
- data/lib/action_dispatch/journey/router/utils.rb +105 -0
- data/lib/action_dispatch/journey/router.rb +151 -0
- data/lib/action_dispatch/journey/routes.rb +82 -0
- data/lib/action_dispatch/journey/scanner.rb +70 -0
- data/lib/action_dispatch/journey/visitors.rb +267 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +159 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/journey.rb +7 -0
- data/lib/action_dispatch/log_subscriber.rb +25 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
- data/lib/action_dispatch/middleware/callbacks.rb +38 -0
- data/lib/action_dispatch/middleware/cookies.rb +719 -0
- data/lib/action_dispatch/middleware/debug_exceptions.rb +206 -0
- data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
- data/lib/action_dispatch/middleware/debug_view.rb +73 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +350 -0
- data/lib/action_dispatch/middleware/executor.rb +32 -0
- data/lib/action_dispatch/middleware/flash.rb +318 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +64 -0
- data/lib/action_dispatch/middleware/reloader.rb +16 -0
- data/lib/action_dispatch/middleware/remote_ip.rb +199 -0
- data/lib/action_dispatch/middleware/request_id.rb +50 -0
- data/lib/action_dispatch/middleware/server_timing.rb +78 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +112 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +66 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +129 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +34 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +88 -0
- data/lib/action_dispatch/middleware/ssl.rb +180 -0
- data/lib/action_dispatch/middleware/stack.rb +194 -0
- data/lib/action_dispatch/middleware/static.rb +192 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +62 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +35 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +284 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +232 -0
- data/lib/action_dispatch/railtie.rb +77 -0
- data/lib/action_dispatch/request/session.rb +283 -0
- data/lib/action_dispatch/request/utils.rb +109 -0
- data/lib/action_dispatch/routing/endpoint.rb +19 -0
- data/lib/action_dispatch/routing/inspector.rb +323 -0
- data/lib/action_dispatch/routing/mapper.rb +2372 -0
- data/lib/action_dispatch/routing/polymorphic_routes.rb +363 -0
- data/lib/action_dispatch/routing/redirection.rb +218 -0
- data/lib/action_dispatch/routing/route_set.rb +958 -0
- data/lib/action_dispatch/routing/routes_proxy.rb +66 -0
- data/lib/action_dispatch/routing/url_for.rb +244 -0
- data/lib/action_dispatch/routing.rb +262 -0
- data/lib/action_dispatch/system_test_case.rb +206 -0
- data/lib/action_dispatch/system_testing/browser.rb +75 -0
- data/lib/action_dispatch/system_testing/driver.rb +85 -0
- data/lib/action_dispatch/system_testing/server.rb +33 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
- data/lib/action_dispatch/testing/assertion_response.rb +48 -0
- data/lib/action_dispatch/testing/assertions/response.rb +114 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +343 -0
- data/lib/action_dispatch/testing/assertions.rb +25 -0
- data/lib/action_dispatch/testing/integration.rb +694 -0
- data/lib/action_dispatch/testing/request_encoder.rb +60 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +57 -0
- data/lib/action_dispatch/testing/test_request.rb +73 -0
- data/lib/action_dispatch/testing/test_response.rb +58 -0
- data/lib/action_dispatch.rb +147 -0
- data/lib/action_pack/gem_version.rb +19 -0
- data/lib/action_pack/version.rb +12 -0
- data/lib/action_pack.rb +27 -0
- metadata +375 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :markup: markdown
|
|
4
|
+
|
|
5
|
+
require "rack/utils"
|
|
6
|
+
|
|
7
|
+
module ActionDispatch
|
|
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.
|
|
12
|
+
#
|
|
13
|
+
# In Rails apps, this middleware is configured to serve assets from the
|
|
14
|
+
# `public/` directory.
|
|
15
|
+
#
|
|
16
|
+
# Only GET and HEAD requests are served. POST and other HTTP methods are handed
|
|
17
|
+
# off to the main app.
|
|
18
|
+
#
|
|
19
|
+
# Only files in the root directory are served; path traversal is denied.
|
|
20
|
+
class Static
|
|
21
|
+
def initialize(app, path, index: "index", headers: {})
|
|
22
|
+
@app = app
|
|
23
|
+
@file_handler = FileHandler.new(path, index: index, headers: headers)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def call(env)
|
|
27
|
+
@file_handler.attempt(env) || @app.call(env)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# # Action Dispatch FileHandler
|
|
32
|
+
#
|
|
33
|
+
# This endpoint serves static files from disk using `Rack::Files`.
|
|
34
|
+
#
|
|
35
|
+
# URL paths are matched with static files according to expected conventions:
|
|
36
|
+
# `path`, `path`.html, `path`/index.html.
|
|
37
|
+
#
|
|
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.
|
|
41
|
+
#
|
|
42
|
+
# If no matching file is found, this endpoint responds `404 Not Found`.
|
|
43
|
+
#
|
|
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.
|
|
47
|
+
class FileHandler
|
|
48
|
+
# `Accept-Encoding` value -> file extension
|
|
49
|
+
PRECOMPRESSED = {
|
|
50
|
+
"br" => ".br",
|
|
51
|
+
"gzip" => ".gz",
|
|
52
|
+
"identity" => nil
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
def initialize(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript|image\/svg\+xml)/)
|
|
56
|
+
@root = root.chomp("/").b
|
|
57
|
+
@index = index
|
|
58
|
+
|
|
59
|
+
@precompressed = Array(precompressed).map(&:to_s) | %w[ identity ]
|
|
60
|
+
@compressible_content_types = compressible_content_types
|
|
61
|
+
|
|
62
|
+
@file_server = ::Rack::Files.new(@root, headers)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def call(env)
|
|
66
|
+
attempt(env) || @file_server.call(env)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def attempt(env)
|
|
70
|
+
request = Rack::Request.new env
|
|
71
|
+
|
|
72
|
+
if request.get? || request.head?
|
|
73
|
+
if found = find_file(request.path_info, accept_encoding: request.accept_encoding)
|
|
74
|
+
serve request, *found
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
def serve(request, filepath, content_headers)
|
|
81
|
+
original, request.path_info =
|
|
82
|
+
request.path_info, ::Rack::Utils.escape_path(filepath).b
|
|
83
|
+
|
|
84
|
+
@file_server.call(request.env).tap do |status, headers, body|
|
|
85
|
+
# Omit content-encoding/type/etc headers for 304 Not Modified
|
|
86
|
+
if status != 304
|
|
87
|
+
headers.update(content_headers)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
ensure
|
|
91
|
+
request.path_info = original
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Match a URI path to a static file to be served.
|
|
95
|
+
#
|
|
96
|
+
# Used by the `Static` class to negotiate a servable file in the `public/`
|
|
97
|
+
# directory (see Static#call).
|
|
98
|
+
#
|
|
99
|
+
# Checks for `path`, `path`.html, and `path`/index.html files, in that order,
|
|
100
|
+
# including .br and .gzip compressed extensions.
|
|
101
|
+
#
|
|
102
|
+
# If a matching file is found, the path and necessary response headers
|
|
103
|
+
# (Content-Type, Content-Encoding) are returned.
|
|
104
|
+
def find_file(path_info, accept_encoding:)
|
|
105
|
+
each_candidate_filepath(path_info) do |filepath, content_type|
|
|
106
|
+
if response = try_files(filepath, content_type, accept_encoding: accept_encoding)
|
|
107
|
+
return response
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def try_files(filepath, content_type, accept_encoding:)
|
|
113
|
+
headers = { Rack::CONTENT_TYPE => content_type }
|
|
114
|
+
|
|
115
|
+
if compressible? content_type
|
|
116
|
+
try_precompressed_files filepath, headers, accept_encoding: accept_encoding
|
|
117
|
+
elsif file_readable? filepath
|
|
118
|
+
[ filepath, headers ]
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def try_precompressed_files(filepath, headers, accept_encoding:)
|
|
123
|
+
each_precompressed_filepath(filepath) do |content_encoding, precompressed_filepath|
|
|
124
|
+
if file_readable? precompressed_filepath
|
|
125
|
+
# Identity encoding is default, so we skip Accept-Encoding negotiation and
|
|
126
|
+
# needn't set Content-Encoding.
|
|
127
|
+
#
|
|
128
|
+
# Vary header is expected when we've found other available encodings that
|
|
129
|
+
# Accept-Encoding ruled out.
|
|
130
|
+
if content_encoding == "identity"
|
|
131
|
+
return precompressed_filepath, headers
|
|
132
|
+
else
|
|
133
|
+
headers[ActionDispatch::Constants::VARY] = "accept-encoding"
|
|
134
|
+
|
|
135
|
+
if accept_encoding.any? { |enc, _| /\b#{content_encoding}\b/i.match?(enc) }
|
|
136
|
+
headers[ActionDispatch::Constants::CONTENT_ENCODING] = content_encoding
|
|
137
|
+
return precompressed_filepath, headers
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def file_readable?(path)
|
|
145
|
+
file_path = File.join(@root, path.b)
|
|
146
|
+
File.file?(file_path) && File.readable?(file_path)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def compressible?(content_type)
|
|
150
|
+
@compressible_content_types.match?(content_type)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def each_precompressed_filepath(filepath)
|
|
154
|
+
@precompressed.each do |content_encoding|
|
|
155
|
+
precompressed_ext = PRECOMPRESSED.fetch(content_encoding)
|
|
156
|
+
yield content_encoding, "#{filepath}#{precompressed_ext}"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
nil
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def each_candidate_filepath(path_info)
|
|
163
|
+
return unless path = clean_path(path_info)
|
|
164
|
+
|
|
165
|
+
ext = ::File.extname(path)
|
|
166
|
+
content_type = ::Rack::Mime.mime_type(ext, nil)
|
|
167
|
+
yield path, content_type || "text/plain"
|
|
168
|
+
|
|
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.
|
|
172
|
+
unless content_type
|
|
173
|
+
default_ext = ::ActionController::Base.default_static_extension
|
|
174
|
+
if ext != default_ext
|
|
175
|
+
default_content_type = ::Rack::Mime.mime_type(default_ext, "text/plain")
|
|
176
|
+
|
|
177
|
+
yield "#{path}#{default_ext}", default_content_type
|
|
178
|
+
yield "#{path}/#{@index}#{default_ext}", default_content_type
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
nil
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def clean_path(path_info)
|
|
186
|
+
path = ::Rack::Utils.unescape_path path_info.chomp("/")
|
|
187
|
+
if ::Rack::Utils.valid_path? path
|
|
188
|
+
::Rack::Utils.clean_path_info path
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<% actions = exception_wrapper.actions %>
|
|
2
|
+
|
|
3
|
+
<% if actions.any? %>
|
|
4
|
+
<div class="actions">
|
|
5
|
+
<% actions.each do |action, _| %>
|
|
6
|
+
<%= button_to action, ActionDispatch::ActionableExceptions.endpoint, params: {
|
|
7
|
+
error: exception_wrapper.exception_class_name,
|
|
8
|
+
action: action,
|
|
9
|
+
location: request.path
|
|
10
|
+
} %>
|
|
11
|
+
<% end %>
|
|
12
|
+
</div>
|
|
13
|
+
<% end %>
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<% if exception_wrapper.has_corrections? %>
|
|
2
|
+
<div class="exception-message">
|
|
3
|
+
<%= simple_format h(exception_wrapper.original_message), { class: "message" }, wrapper_tag: "div" %>
|
|
4
|
+
</div>
|
|
5
|
+
<%
|
|
6
|
+
# The 'did_you_mean' gem can raise exceptions when calling #corrections on
|
|
7
|
+
# the exception. If it does there are no corrections to show.
|
|
8
|
+
corrections = exception_wrapper.corrections rescue []
|
|
9
|
+
%>
|
|
10
|
+
<% if corrections.any? %>
|
|
11
|
+
<b>Did you mean?</b>
|
|
12
|
+
<ul>
|
|
13
|
+
<% corrections.each do |correction| %>
|
|
14
|
+
<li class="correction"><%= h correction %></li>
|
|
15
|
+
<% end %>
|
|
16
|
+
</ul>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% else %>
|
|
19
|
+
<div class="exception-message">
|
|
20
|
+
<%= simple_format h(exception_wrapper.message), { class: "message" }, wrapper_tag: "div" %>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<h2 class="request-heading">Request</h2>
|
|
2
|
+
<% if params_valid? %>
|
|
3
|
+
<p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
|
|
4
|
+
<% end %>
|
|
5
|
+
|
|
6
|
+
<div class="details">
|
|
7
|
+
<div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
|
|
8
|
+
<div id="session_dump" class="hidden"><pre><%= debug_hash @request.session %></pre></div>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="details">
|
|
12
|
+
<div class="summary"><a href="#" onclick="return toggleEnvDump()">Toggle env dump</a></div>
|
|
13
|
+
<div id="env_dump" class="hidden"><pre><%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %></pre></div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<h2 class="response-heading">Response</h2>
|
|
17
|
+
<p><b>Headers</b>:</p> <pre><%= debug_headers(defined?(@response) ? @response.headers : {}) %></pre>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<%
|
|
2
|
+
clean_params = params_valid? ? @request.filtered_parameters.clone : {}
|
|
3
|
+
clean_params.delete("action")
|
|
4
|
+
clean_params.delete("controller")
|
|
5
|
+
|
|
6
|
+
request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
|
|
7
|
+
|
|
8
|
+
def debug_hash(object)
|
|
9
|
+
object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
|
|
10
|
+
end unless self.class.method_defined?(:debug_hash)
|
|
11
|
+
%>
|
|
12
|
+
|
|
13
|
+
Request parameters
|
|
14
|
+
<%= request_dump %>
|
|
15
|
+
|
|
16
|
+
Session dump
|
|
17
|
+
<%= debug_hash @request.session %>
|
|
18
|
+
|
|
19
|
+
Env dump
|
|
20
|
+
<%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %>
|
|
21
|
+
|
|
22
|
+
Response headers
|
|
23
|
+
<%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<% error_index = local_assigns[:error_index] || 0 %>
|
|
2
|
+
|
|
3
|
+
<% source_extracts.each_with_index do |source_extract, index| %>
|
|
4
|
+
<% if source_extract[:code] %>
|
|
5
|
+
<div class="source <%= "hidden" if show_source_idx != index %>" id="frame-source-<%= error_index %>-<%= index %>">
|
|
6
|
+
<div class="info">
|
|
7
|
+
Extracted source (around line <strong>#<%= source_extract[:line_number] %></strong>):
|
|
8
|
+
</div>
|
|
9
|
+
<div class="data">
|
|
10
|
+
<table cellpadding="0" cellspacing="0" class="lines">
|
|
11
|
+
<tr>
|
|
12
|
+
<td>
|
|
13
|
+
<pre class="line_numbers">
|
|
14
|
+
<% source_extract[:code].each_key do |line_number| %>
|
|
15
|
+
<span><%= line_number -%></span>
|
|
16
|
+
<% end %>
|
|
17
|
+
</pre>
|
|
18
|
+
</td>
|
|
19
|
+
<td width="100%">
|
|
20
|
+
<pre>
|
|
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 -%>
|
|
26
|
+
</pre>
|
|
27
|
+
</td>
|
|
28
|
+
</tr>
|
|
29
|
+
</table>
|
|
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 -%>
|
|
34
|
+
</div>
|
|
35
|
+
<% end %>
|
|
36
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<% @source_extracts.first(3).each do |source_extract| %>
|
|
2
|
+
<% if source_extract[:code] %>
|
|
3
|
+
Extracted source (around line #<%= source_extract[:line_number] %>):
|
|
4
|
+
|
|
5
|
+
<% source_extract[:code].each do |line, source| -%>
|
|
6
|
+
<%= line == source_extract[:line_number] ? "*#{line}" : "##{line}" -%> <%= source -%><% end -%>
|
|
7
|
+
<% end %>
|
|
8
|
+
<% end %>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<% names = traces.keys %>
|
|
2
|
+
<% error_index = local_assigns[:error_index] || 0 %>
|
|
3
|
+
|
|
4
|
+
<p><code>Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %></code></p>
|
|
5
|
+
|
|
6
|
+
<div id="traces-<%= error_index %>">
|
|
7
|
+
<% names.each do |name| %>
|
|
8
|
+
<%
|
|
9
|
+
show = "show('#{name.gsub(/\s/, '-')}-#{error_index}');"
|
|
10
|
+
hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}-#{error_index}');"}
|
|
11
|
+
%>
|
|
12
|
+
<a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<% traces.each do |name, trace| %>
|
|
16
|
+
<div id="<%= "#{name.gsub(/\s/, '-')}-#{error_index}" %>" style="display: <%= (name == trace_to_show) ? 'block' : 'none' %>;">
|
|
17
|
+
<code class="traces">
|
|
18
|
+
<% trace.each do |frame| %>
|
|
19
|
+
<a class="trace-frames trace-frames-<%= error_index %>" data-exception-object-id="<%= frame[:exception_object_id] %>" data-frame-id="<%= frame[:id] %>" href="#">
|
|
20
|
+
<%= frame[:trace] %>
|
|
21
|
+
</a>
|
|
22
|
+
<br>
|
|
23
|
+
<% end %>
|
|
24
|
+
</code>
|
|
25
|
+
</div>
|
|
26
|
+
<% end %>
|
|
27
|
+
|
|
28
|
+
<script>
|
|
29
|
+
(function() {
|
|
30
|
+
var traceFrames = document.getElementsByClassName('trace-frames-<%= error_index %>');
|
|
31
|
+
var selectedFrame, currentSource = document.getElementById('frame-source-<%= error_index %>-0');
|
|
32
|
+
|
|
33
|
+
// Add click listeners for all stack frames
|
|
34
|
+
for (var i = 0; i < traceFrames.length; i++) {
|
|
35
|
+
traceFrames[i].addEventListener('click', function(e) {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
var target = e.target;
|
|
38
|
+
var frame_id = target.dataset.frameId;
|
|
39
|
+
|
|
40
|
+
if (selectedFrame) {
|
|
41
|
+
selectedFrame.className = selectedFrame.className.replace("selected", "");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
target.className += " selected";
|
|
45
|
+
selectedFrame = target;
|
|
46
|
+
|
|
47
|
+
// Change the extracted source code
|
|
48
|
+
changeSourceExtract(frame_id);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
function changeSourceExtract(frame_id) {
|
|
52
|
+
var el = document.getElementById('frame-source-<%= error_index %>-' + frame_id);
|
|
53
|
+
if (currentSource && el) {
|
|
54
|
+
currentSource.className += " hidden";
|
|
55
|
+
el.className = el.className.replace(" hidden", "");
|
|
56
|
+
currentSource = el;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
})();
|
|
61
|
+
</script>
|
|
62
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<h1>Blocked hosts: <%= @hosts.join(", ") %></h1>
|
|
3
|
+
</header>
|
|
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>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Blocked hosts: <%= @hosts.join(", ") %>
|
|
2
|
+
|
|
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
|
+
|
|
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
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<h1>
|
|
3
|
+
<%= @exception_wrapper.exception_class_name %>
|
|
4
|
+
<% if params_valid? && @request.parameters['controller'] %>
|
|
5
|
+
in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
|
|
6
|
+
<% end %>
|
|
7
|
+
</h1>
|
|
8
|
+
</header>
|
|
9
|
+
|
|
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
|
+
|
|
14
|
+
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx, error_index: 0 %>
|
|
15
|
+
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show, error_index: 0 %>
|
|
16
|
+
|
|
17
|
+
<% if @exception_wrapper.has_cause? %>
|
|
18
|
+
<h2>Exception Causes</h2>
|
|
19
|
+
<% end %>
|
|
20
|
+
|
|
21
|
+
<% @exception_wrapper.wrapped_causes.each.with_index(1) do |wrapper, index| %>
|
|
22
|
+
<div class="details">
|
|
23
|
+
<a class="summary" href="#" onclick="return toggle(<%= wrapper.exception_id %>)">
|
|
24
|
+
<%= wrapper.exception_class_name %>: <%= h wrapper.message %>
|
|
25
|
+
</a>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div id="<%= wrapper.exception_id %>" class="hidden">
|
|
29
|
+
<%= render "rescues/source", source_extracts: wrapper.source_extracts, show_source_idx: wrapper.source_to_show_id, error_index: index %>
|
|
30
|
+
<%= render "rescues/trace", traces: wrapper.traces, trace_to_show: wrapper.trace_to_show, error_index: index %>
|
|
31
|
+
</div>
|
|
32
|
+
<% end %>
|
|
33
|
+
|
|
34
|
+
<%= render template: "rescues/_request_and_response" %>
|
|
35
|
+
</main>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<%= @exception_wrapper.exception_class_name %><%
|
|
2
|
+
if params_valid? && @request.parameters['controller']
|
|
3
|
+
%> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
|
|
4
|
+
<% end %>
|
|
5
|
+
|
|
6
|
+
<%= @exception_wrapper.message %>
|
|
7
|
+
<%= render template: "rescues/_source" %>
|
|
8
|
+
<%= render template: "rescues/_trace" %>
|
|
9
|
+
<%= render template: "rescues/_request_and_response" %>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<header role="banner">
|
|
2
|
+
<h1>
|
|
3
|
+
<%= @exception.class.to_s %>
|
|
4
|
+
<% if @request.parameters['controller'] %>
|
|
5
|
+
in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
|
|
6
|
+
<% end %>
|
|
7
|
+
</h1>
|
|
8
|
+
</header>
|
|
9
|
+
|
|
10
|
+
<main role="main" id="container">
|
|
11
|
+
<h2>
|
|
12
|
+
<%= h @exception.message %>
|
|
13
|
+
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
|
|
14
|
+
<br />To resolve this issue run: bin/rails active_storage:install
|
|
15
|
+
<% end %>
|
|
16
|
+
<% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
|
|
17
|
+
<br />To resolve this issue run: bin/rails action_mailbox:install
|
|
18
|
+
<% end %>
|
|
19
|
+
</h2>
|
|
20
|
+
|
|
21
|
+
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
|
22
|
+
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
|
23
|
+
<%= render template: "rescues/_request_and_response" %>
|
|
24
|
+
</main>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%= @exception.class.to_s %><%
|
|
2
|
+
if @request.parameters['controller']
|
|
3
|
+
%> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
|
|
4
|
+
<% end %>
|
|
5
|
+
|
|
6
|
+
<%= @exception.message %>
|
|
7
|
+
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
|
|
8
|
+
To resolve this issue run: bin/rails active_storage:install
|
|
9
|
+
<% end %>
|
|
10
|
+
<% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
|
|
11
|
+
To resolve this issue run: bin/rails action_mailbox:install
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
<%= render template: "rescues/_source" %>
|
|
15
|
+
<%= render template: "rescues/_trace" %>
|
|
16
|
+
<%= render template: "rescues/_request_and_response" %>
|