actionpack 5.2.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +429 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +57 -0
- data/lib/abstract_controller.rb +27 -0
- data/lib/abstract_controller/asset_paths.rb +12 -0
- data/lib/abstract_controller/base.rb +265 -0
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/caching/fragments.rb +166 -0
- data/lib/abstract_controller/callbacks.rb +212 -0
- data/lib/abstract_controller/collector.rb +43 -0
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +194 -0
- data/lib/abstract_controller/logger.rb +14 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +20 -0
- data/lib/abstract_controller/rendering.rb +127 -0
- data/lib/abstract_controller/translation.rb +31 -0
- data/lib/abstract_controller/url_for.rb +35 -0
- data/lib/action_controller.rb +66 -0
- data/lib/action_controller/api.rb +149 -0
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/base.rb +276 -0
- data/lib/action_controller/caching.rb +46 -0
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +78 -0
- data/lib/action_controller/metal.rb +256 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +274 -0
- data/lib/action_controller/metal/content_security_policy.rb +52 -0
- data/lib/action_controller/metal/cookies.rb +16 -0
- data/lib/action_controller/metal/data_streaming.rb +152 -0
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
- data/lib/action_controller/metal/exceptions.rb +53 -0
- data/lib/action_controller/metal/flash.rb +61 -0
- data/lib/action_controller/metal/force_ssl.rb +99 -0
- data/lib/action_controller/metal/head.rb +60 -0
- data/lib/action_controller/metal/helpers.rb +123 -0
- data/lib/action_controller/metal/http_authentication.rb +519 -0
- data/lib/action_controller/metal/implicit_render.rb +73 -0
- data/lib/action_controller/metal/instrumentation.rb +107 -0
- data/lib/action_controller/metal/live.rb +312 -0
- data/lib/action_controller/metal/mime_responds.rb +313 -0
- data/lib/action_controller/metal/parameter_encoding.rb +51 -0
- data/lib/action_controller/metal/params_wrapper.rb +293 -0
- data/lib/action_controller/metal/redirecting.rb +133 -0
- data/lib/action_controller/metal/renderers.rb +181 -0
- data/lib/action_controller/metal/rendering.rb +122 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +445 -0
- data/lib/action_controller/metal/rescue.rb +28 -0
- data/lib/action_controller/metal/streaming.rb +223 -0
- data/lib/action_controller/metal/strong_parameters.rb +1086 -0
- data/lib/action_controller/metal/testing.rb +16 -0
- data/lib/action_controller/metal/url_for.rb +58 -0
- data/lib/action_controller/railtie.rb +89 -0
- data/lib/action_controller/railties/helpers.rb +24 -0
- data/lib/action_controller/renderer.rb +117 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +629 -0
- data/lib/action_dispatch.rb +112 -0
- data/lib/action_dispatch/http/cache.rb +222 -0
- data/lib/action_dispatch/http/content_security_policy.rb +272 -0
- data/lib/action_dispatch/http/filter_parameters.rb +84 -0
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +132 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +175 -0
- data/lib/action_dispatch/http/mime_type.rb +342 -0
- data/lib/action_dispatch/http/mime_types.rb +50 -0
- data/lib/action_dispatch/http/parameter_filter.rb +86 -0
- data/lib/action_dispatch/http/parameters.rb +126 -0
- data/lib/action_dispatch/http/rack_cache.rb +63 -0
- data/lib/action_dispatch/http/request.rb +430 -0
- data/lib/action_dispatch/http/response.rb +519 -0
- data/lib/action_dispatch/http/upload.rb +84 -0
- data/lib/action_dispatch/http/url.rb +350 -0
- data/lib/action_dispatch/journey.rb +7 -0
- data/lib/action_dispatch/journey/formatter.rb +189 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
- data/lib/action_dispatch/journey/nodes/node.rb +140 -0
- data/lib/action_dispatch/journey/parser.rb +199 -0
- data/lib/action_dispatch/journey/parser.y +50 -0
- data/lib/action_dispatch/journey/parser_extras.rb +31 -0
- data/lib/action_dispatch/journey/path/pattern.rb +198 -0
- data/lib/action_dispatch/journey/route.rb +203 -0
- data/lib/action_dispatch/journey/router.rb +156 -0
- data/lib/action_dispatch/journey/router/utils.rb +102 -0
- data/lib/action_dispatch/journey/routes.rb +82 -0
- data/lib/action_dispatch/journey/scanner.rb +64 -0
- data/lib/action_dispatch/journey/visitors.rb +268 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/callbacks.rb +36 -0
- data/lib/action_dispatch/middleware/cookies.rb +685 -0
- data/lib/action_dispatch/middleware/debug_exceptions.rb +205 -0
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +147 -0
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +300 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +57 -0
- data/lib/action_dispatch/middleware/reloader.rb +12 -0
- data/lib/action_dispatch/middleware/remote_ip.rb +183 -0
- data/lib/action_dispatch/middleware/request_id.rb +43 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +92 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +54 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +118 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +28 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +62 -0
- data/lib/action_dispatch/middleware/ssl.rb +150 -0
- data/lib/action_dispatch/middleware/stack.rb +116 -0
- data/lib/action_dispatch/middleware/static.rb +130 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -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 +27 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +161 -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 +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
- data/lib/action_dispatch/railtie.rb +55 -0
- data/lib/action_dispatch/request/session.rb +234 -0
- data/lib/action_dispatch/request/utils.rb +78 -0
- data/lib/action_dispatch/routing.rb +260 -0
- data/lib/action_dispatch/routing/endpoint.rb +17 -0
- data/lib/action_dispatch/routing/inspector.rb +225 -0
- data/lib/action_dispatch/routing/mapper.rb +2267 -0
- data/lib/action_dispatch/routing/polymorphic_routes.rb +352 -0
- data/lib/action_dispatch/routing/redirection.rb +201 -0
- data/lib/action_dispatch/routing/route_set.rb +890 -0
- data/lib/action_dispatch/routing/routes_proxy.rb +69 -0
- data/lib/action_dispatch/routing/url_for.rb +236 -0
- data/lib/action_dispatch/system_test_case.rb +147 -0
- data/lib/action_dispatch/system_testing/browser.rb +49 -0
- data/lib/action_dispatch/system_testing/driver.rb +59 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
- data/lib/action_dispatch/testing/assertion_response.rb +47 -0
- data/lib/action_dispatch/testing/assertions.rb +24 -0
- data/lib/action_dispatch/testing/assertions/response.rb +107 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +222 -0
- data/lib/action_dispatch/testing/integration.rb +652 -0
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +50 -0
- data/lib/action_dispatch/testing/test_request.rb +71 -0
- data/lib/action_dispatch/testing/test_response.rb +53 -0
- data/lib/action_pack.rb +26 -0
- data/lib/action_pack/gem_version.rb +17 -0
- data/lib/action_pack/version.rb +10 -0
- metadata +318 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/inflector/methods"
|
4
|
+
require "active_support/dependencies"
|
5
|
+
|
6
|
+
module ActionDispatch
|
7
|
+
class MiddlewareStack
|
8
|
+
class Middleware
|
9
|
+
attr_reader :args, :block, :klass
|
10
|
+
|
11
|
+
def initialize(klass, args, block)
|
12
|
+
@klass = klass
|
13
|
+
@args = args
|
14
|
+
@block = block
|
15
|
+
end
|
16
|
+
|
17
|
+
def name; klass.name; end
|
18
|
+
|
19
|
+
def ==(middleware)
|
20
|
+
case middleware
|
21
|
+
when Middleware
|
22
|
+
klass == middleware.klass
|
23
|
+
when Class
|
24
|
+
klass == middleware
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def inspect
|
29
|
+
if klass.is_a?(Class)
|
30
|
+
klass.to_s
|
31
|
+
else
|
32
|
+
klass.class.to_s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def build(app)
|
37
|
+
klass.new(app, *args, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
include Enumerable
|
42
|
+
|
43
|
+
attr_accessor :middlewares
|
44
|
+
|
45
|
+
def initialize(*args)
|
46
|
+
@middlewares = []
|
47
|
+
yield(self) if block_given?
|
48
|
+
end
|
49
|
+
|
50
|
+
def each
|
51
|
+
@middlewares.each { |x| yield x }
|
52
|
+
end
|
53
|
+
|
54
|
+
def size
|
55
|
+
middlewares.size
|
56
|
+
end
|
57
|
+
|
58
|
+
def last
|
59
|
+
middlewares.last
|
60
|
+
end
|
61
|
+
|
62
|
+
def [](i)
|
63
|
+
middlewares[i]
|
64
|
+
end
|
65
|
+
|
66
|
+
def unshift(klass, *args, &block)
|
67
|
+
middlewares.unshift(build_middleware(klass, args, block))
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize_copy(other)
|
71
|
+
self.middlewares = other.middlewares.dup
|
72
|
+
end
|
73
|
+
|
74
|
+
def insert(index, klass, *args, &block)
|
75
|
+
index = assert_index(index, :before)
|
76
|
+
middlewares.insert(index, build_middleware(klass, args, block))
|
77
|
+
end
|
78
|
+
|
79
|
+
alias_method :insert_before, :insert
|
80
|
+
|
81
|
+
def insert_after(index, *args, &block)
|
82
|
+
index = assert_index(index, :after)
|
83
|
+
insert(index + 1, *args, &block)
|
84
|
+
end
|
85
|
+
|
86
|
+
def swap(target, *args, &block)
|
87
|
+
index = assert_index(target, :before)
|
88
|
+
insert(index, *args, &block)
|
89
|
+
middlewares.delete_at(index + 1)
|
90
|
+
end
|
91
|
+
|
92
|
+
def delete(target)
|
93
|
+
middlewares.delete_if { |m| m.klass == target }
|
94
|
+
end
|
95
|
+
|
96
|
+
def use(klass, *args, &block)
|
97
|
+
middlewares.push(build_middleware(klass, args, block))
|
98
|
+
end
|
99
|
+
|
100
|
+
def build(app = Proc.new)
|
101
|
+
middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) }
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def assert_index(index, where)
|
107
|
+
i = index.is_a?(Integer) ? index : middlewares.index { |m| m.klass == index }
|
108
|
+
raise "No such middleware to insert #{where}: #{index.inspect}" unless i
|
109
|
+
i
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_middleware(klass, args, block)
|
113
|
+
Middleware.new(klass, args, block)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/utils"
|
4
|
+
require "active_support/core_ext/uri"
|
5
|
+
|
6
|
+
module ActionDispatch
|
7
|
+
# This middleware returns a file's contents from disk in the body response.
|
8
|
+
# When initialized, it can accept optional HTTP headers, which will be set
|
9
|
+
# when a response containing a file's contents is delivered.
|
10
|
+
#
|
11
|
+
# This middleware will render the file specified in <tt>env["PATH_INFO"]</tt>
|
12
|
+
# where the base path is in the +root+ directory. For example, if the +root+
|
13
|
+
# is set to +public/+, then a request with <tt>env["PATH_INFO"]</tt> of
|
14
|
+
# +assets/application.js+ will return a response with the contents of a file
|
15
|
+
# located at +public/assets/application.js+ if the file exists. If the file
|
16
|
+
# does not exist, a 404 "File not Found" response will be returned.
|
17
|
+
class FileHandler
|
18
|
+
def initialize(root, index: "index", headers: {})
|
19
|
+
@root = root.chomp("/").b
|
20
|
+
@file_server = ::Rack::File.new(@root, headers)
|
21
|
+
@index = index
|
22
|
+
end
|
23
|
+
|
24
|
+
# Takes a path to a file. If the file is found, has valid encoding, and has
|
25
|
+
# correct read permissions, the return value is a URI-escaped string
|
26
|
+
# representing the filename. Otherwise, false is returned.
|
27
|
+
#
|
28
|
+
# Used by the +Static+ class to check the existence of a valid file
|
29
|
+
# in the server's +public/+ directory (see Static#call).
|
30
|
+
def match?(path)
|
31
|
+
path = ::Rack::Utils.unescape_path path
|
32
|
+
return false unless ::Rack::Utils.valid_path? path
|
33
|
+
path = ::Rack::Utils.clean_path_info path
|
34
|
+
|
35
|
+
paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"]
|
36
|
+
|
37
|
+
if match = paths.detect { |p|
|
38
|
+
path = File.join(@root, p.b)
|
39
|
+
begin
|
40
|
+
File.file?(path) && File.readable?(path)
|
41
|
+
rescue SystemCallError
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
}
|
46
|
+
return ::Rack::Utils.escape_path(match).b
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def call(env)
|
51
|
+
serve(Rack::Request.new(env))
|
52
|
+
end
|
53
|
+
|
54
|
+
def serve(request)
|
55
|
+
path = request.path_info
|
56
|
+
gzip_path = gzip_file_path(path)
|
57
|
+
|
58
|
+
if gzip_path && gzip_encoding_accepted?(request)
|
59
|
+
request.path_info = gzip_path
|
60
|
+
status, headers, body = @file_server.call(request.env)
|
61
|
+
if status == 304
|
62
|
+
return [status, headers, body]
|
63
|
+
end
|
64
|
+
headers["Content-Encoding"] = "gzip"
|
65
|
+
headers["Content-Type"] = content_type(path)
|
66
|
+
else
|
67
|
+
status, headers, body = @file_server.call(request.env)
|
68
|
+
end
|
69
|
+
|
70
|
+
headers["Vary"] = "Accept-Encoding" if gzip_path
|
71
|
+
|
72
|
+
return [status, headers, body]
|
73
|
+
ensure
|
74
|
+
request.path_info = path
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def ext
|
79
|
+
::ActionController::Base.default_static_extension
|
80
|
+
end
|
81
|
+
|
82
|
+
def content_type(path)
|
83
|
+
::Rack::Mime.mime_type(::File.extname(path), "text/plain".freeze)
|
84
|
+
end
|
85
|
+
|
86
|
+
def gzip_encoding_accepted?(request)
|
87
|
+
request.accept_encoding.any? { |enc, quality| enc =~ /\bgzip\b/i }
|
88
|
+
end
|
89
|
+
|
90
|
+
def gzip_file_path(path)
|
91
|
+
can_gzip_mime = content_type(path) =~ /\A(?:text\/|application\/javascript)/
|
92
|
+
gzip_path = "#{path}.gz"
|
93
|
+
if can_gzip_mime && File.exist?(File.join(@root, ::Rack::Utils.unescape_path(gzip_path).b))
|
94
|
+
gzip_path.b
|
95
|
+
else
|
96
|
+
false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# This middleware will attempt to return the contents of a file's body from
|
102
|
+
# disk in the response. If a file is not found on disk, the request will be
|
103
|
+
# delegated to the application stack. This middleware is commonly initialized
|
104
|
+
# to serve assets from a server's +public/+ directory.
|
105
|
+
#
|
106
|
+
# This middleware verifies the path to ensure that only files
|
107
|
+
# living in the root directory can be rendered. A request cannot
|
108
|
+
# produce a directory traversal using this middleware. Only 'GET' and 'HEAD'
|
109
|
+
# requests will result in a file being returned.
|
110
|
+
class Static
|
111
|
+
def initialize(app, path, index: "index", headers: {})
|
112
|
+
@app = app
|
113
|
+
@file_handler = FileHandler.new(path, index: index, headers: headers)
|
114
|
+
end
|
115
|
+
|
116
|
+
def call(env)
|
117
|
+
req = Rack::Request.new env
|
118
|
+
|
119
|
+
if req.get? || req.head?
|
120
|
+
path = req.path_info.chomp("/".freeze)
|
121
|
+
if match = @file_handler.match?(path)
|
122
|
+
req.path_info = match
|
123
|
+
return @file_handler.serve(req)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
@app.call(req.env)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<% unless @exception.blamed_files.blank? %>
|
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>
|
9
|
+
<p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
|
10
|
+
|
11
|
+
<div class="details">
|
12
|
+
<div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
|
13
|
+
<div id="session_dump" style="display:none"><pre><%= debug_hash @request.session %></pre></div>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div class="details">
|
17
|
+
<div class="summary"><a href="#" onclick="return toggleEnvDump()">Toggle env dump</a></div>
|
18
|
+
<div id="env_dump" style="display:none"><pre><%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %></pre></div>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<h2 style="margin-top: 30px">Response</h2>
|
22
|
+
<p><b>Headers</b>:</p> <pre><%= debug_headers(defined?(@response) ? @response.headers : {}) %></pre>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%
|
2
|
+
clean_params = @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,27 @@
|
|
1
|
+
<% @source_extracts.each_with_index do |source_extract, index| %>
|
2
|
+
<% if source_extract[:code] %>
|
3
|
+
<div class="source <%="hidden" if @show_source_idx != index%>" id="frame-source-<%=index%>">
|
4
|
+
<div class="info">
|
5
|
+
Extracted source (around line <strong>#<%= source_extract[:line_number] %></strong>):
|
6
|
+
</div>
|
7
|
+
<div class="data">
|
8
|
+
<table cellpadding="0" cellspacing="0" class="lines">
|
9
|
+
<tr>
|
10
|
+
<td>
|
11
|
+
<pre class="line_numbers">
|
12
|
+
<% source_extract[:code].each_key do |line_number| %>
|
13
|
+
<span><%= line_number -%></span>
|
14
|
+
<% end %>
|
15
|
+
</pre>
|
16
|
+
</td>
|
17
|
+
<td width="100%">
|
18
|
+
<pre>
|
19
|
+
<% source_extract[:code].each do |line, source| -%><div class="line<%= " active" if line == source_extract[:line_number] -%>"><%= source -%></div><% end -%>
|
20
|
+
</pre>
|
21
|
+
</td>
|
22
|
+
</tr>
|
23
|
+
</table>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
27
|
+
<% 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,52 @@
|
|
1
|
+
<% names = @traces.keys %>
|
2
|
+
|
3
|
+
<p><code>Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %></code></p>
|
4
|
+
|
5
|
+
<div id="traces">
|
6
|
+
<% names.each do |name| %>
|
7
|
+
<%
|
8
|
+
show = "show('#{name.gsub(/\s/, '-')}');"
|
9
|
+
hide = (names - [name]).collect {|hide_name| "hide('#{hide_name.gsub(/\s/, '-')}');"}
|
10
|
+
%>
|
11
|
+
<a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% @traces.each do |name, trace| %>
|
15
|
+
<div id="<%= name.gsub(/\s/, '-') %>" style="display: <%= (name == @trace_to_show) ? 'block' : 'none' %>;">
|
16
|
+
<pre><code><% trace.each do |frame| %><a class="trace-frames" data-frame-id="<%= frame[:id] %>" href="#"><%= frame[:trace] %></a><br><% end %></code></pre>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<script type="text/javascript">
|
21
|
+
var traceFrames = document.getElementsByClassName('trace-frames');
|
22
|
+
var selectedFrame, currentSource = document.getElementById('frame-source-0');
|
23
|
+
|
24
|
+
// Add click listeners for all stack frames
|
25
|
+
for (var i = 0; i < traceFrames.length; i++) {
|
26
|
+
traceFrames[i].addEventListener('click', function(e) {
|
27
|
+
e.preventDefault();
|
28
|
+
var target = e.target;
|
29
|
+
var frame_id = target.dataset.frameId;
|
30
|
+
|
31
|
+
if (selectedFrame) {
|
32
|
+
selectedFrame.className = selectedFrame.className.replace("selected", "");
|
33
|
+
}
|
34
|
+
|
35
|
+
target.className += " selected";
|
36
|
+
selectedFrame = target;
|
37
|
+
|
38
|
+
// Change the extracted source code
|
39
|
+
changeSourceExtract(frame_id);
|
40
|
+
});
|
41
|
+
|
42
|
+
function changeSourceExtract(frame_id) {
|
43
|
+
var el = document.getElementById('frame-source-' + frame_id);
|
44
|
+
if (currentSource && el) {
|
45
|
+
currentSource.className += " hidden";
|
46
|
+
el.className = el.className.replace(" hidden", "");
|
47
|
+
currentSource = el;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
</script>
|
52
|
+
</div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<header>
|
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
|
+
<div id="container">
|
11
|
+
<h2><%= h @exception.message %></h2>
|
12
|
+
|
13
|
+
<%= render template: "rescues/_source" %>
|
14
|
+
<%= render template: "rescues/_trace" %>
|
15
|
+
<%= render template: "rescues/_request_and_response" %>
|
16
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
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
|
+
<%= render template: "rescues/_source" %>
|
8
|
+
<%= render template: "rescues/_trace" %>
|
9
|
+
<%= render template: "rescues/_request_and_response" %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<header>
|
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
|
+
<div id="container">
|
11
|
+
<h2>
|
12
|
+
<%= h @exception.message %>
|
13
|
+
<% if %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}.match?(@exception.message) %>
|
14
|
+
<br />To resolve this issue run: bin/rails active_storage:install
|
15
|
+
<% end %>
|
16
|
+
</h2>
|
17
|
+
|
18
|
+
<%= render template: "rescues/_source" %>
|
19
|
+
<%= render template: "rescues/_trace" %>
|
20
|
+
<%= render template: "rescues/_request_and_response" %>
|
21
|
+
</div>
|