actionpack 4.2.11.1 → 5.2.4.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 +4 -4
- data/CHANGELOG.md +287 -488
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -7
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +45 -49
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +78 -15
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +47 -31
- data/lib/abstract_controller/collector.rb +8 -11
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +25 -25
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +4 -2
- data/lib/abstract_controller/rendering.rb +42 -41
- data/lib/abstract_controller/translation.rb +10 -7
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +12 -5
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/api.rb +149 -0
- data/lib/action_controller/base.rb +27 -19
- data/lib/action_controller/caching.rb +14 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +10 -15
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +118 -44
- data/lib/action_controller/metal/content_security_policy.rb +52 -0
- data/lib/action_controller/metal/cookies.rb +3 -3
- data/lib/action_controller/metal/data_streaming.rb +27 -46
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +20 -13
- data/lib/action_controller/metal/exceptions.rb +8 -14
- data/lib/action_controller/metal/flash.rb +4 -3
- data/lib/action_controller/metal/force_ssl.rb +23 -21
- data/lib/action_controller/metal/head.rb +21 -19
- data/lib/action_controller/metal/helpers.rb +24 -14
- data/lib/action_controller/metal/http_authentication.rb +64 -57
- data/lib/action_controller/metal/implicit_render.rb +62 -8
- data/lib/action_controller/metal/instrumentation.rb +19 -21
- data/lib/action_controller/metal/live.rb +90 -106
- data/lib/action_controller/metal/mime_responds.rb +33 -46
- data/lib/action_controller/metal/parameter_encoding.rb +51 -0
- data/lib/action_controller/metal/params_wrapper.rb +61 -53
- data/lib/action_controller/metal/redirecting.rb +49 -28
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +72 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +229 -93
- data/lib/action_controller/metal/rescue.rb +9 -16
- data/lib/action_controller/metal/streaming.rb +12 -10
- data/lib/action_controller/metal/strong_parameters.rb +583 -164
- data/lib/action_controller/metal/testing.rb +2 -17
- data/lib/action_controller/metal/url_for.rb +19 -10
- data/lib/action_controller/metal.rb +98 -83
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +2 -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 +280 -411
- data/lib/action_controller.rb +29 -21
- data/lib/action_dispatch/http/cache.rb +93 -47
- data/lib/action_dispatch/http/content_security_policy.rb +272 -0
- data/lib/action_dispatch/http/filter_parameters.rb +26 -20
- data/lib/action_dispatch/http/filter_redirect.rb +10 -11
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +56 -41
- data/lib/action_dispatch/http/mime_type.rb +134 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameter_filter.rb +25 -11
- data/lib/action_dispatch/http/parameters.rb +98 -39
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +200 -118
- data/lib/action_dispatch/http/response.rb +225 -110
- data/lib/action_dispatch/http/upload.rb +12 -6
- data/lib/action_dispatch/http/url.rb +110 -28
- data/lib/action_dispatch/journey/formatter.rb +55 -32
- data/lib/action_dispatch/journey/gtg/builder.rb +7 -5
- data/lib/action_dispatch/journey/gtg/simulator.rb +3 -9
- data/lib/action_dispatch/journey/gtg/transition_table.rb +17 -16
- data/lib/action_dispatch/journey/nfa/builder.rb +5 -3
- data/lib/action_dispatch/journey/nfa/dot.rb +13 -13
- data/lib/action_dispatch/journey/nfa/simulator.rb +3 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -48
- data/lib/action_dispatch/journey/nodes/node.rb +18 -6
- data/lib/action_dispatch/journey/parser.rb +23 -22
- data/lib/action_dispatch/journey/parser.y +3 -2
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +50 -44
- data/lib/action_dispatch/journey/route.rb +106 -28
- data/lib/action_dispatch/journey/router/utils.rb +20 -11
- data/lib/action_dispatch/journey/router.rb +35 -23
- data/lib/action_dispatch/journey/routes.rb +18 -16
- data/lib/action_dispatch/journey/scanner.rb +18 -15
- data/lib/action_dispatch/journey/visitors.rb +99 -52
- data/lib/action_dispatch/journey.rb +7 -5
- data/lib/action_dispatch/middleware/callbacks.rb +1 -2
- data/lib/action_dispatch/middleware/cookies.rb +304 -193
- data/lib/action_dispatch/middleware/debug_exceptions.rb +152 -57
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +68 -69
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/public_exceptions.rb +27 -25
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +41 -31
- data/lib/action_dispatch/middleware/request_id.rb +17 -9
- data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -25
- data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
- data/lib/action_dispatch/middleware/session/cookie_store.rb +72 -67
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +26 -22
- data/lib/action_dispatch/middleware/ssl.rb +114 -36
- data/lib/action_dispatch/middleware/stack.rb +31 -44
- data/lib/action_dispatch/middleware/static.rb +57 -50
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -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 +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +64 -64
- data/lib/action_dispatch/railtie.rb +19 -11
- data/lib/action_dispatch/request/session.rb +106 -59
- data/lib/action_dispatch/request/utils.rb +67 -24
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +58 -67
- data/lib/action_dispatch/routing/mapper.rb +733 -447
- data/lib/action_dispatch/routing/polymorphic_routes.rb +161 -139
- data/lib/action_dispatch/routing/redirection.rb +36 -26
- data/lib/action_dispatch/routing/route_set.rb +321 -291
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +65 -25
- data/lib/action_dispatch/routing.rb +17 -18
- 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/response.rb +45 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +30 -26
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +347 -209
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +28 -22
- data/lib/action_dispatch/testing/test_request.rb +27 -34
- data/lib/action_dispatch/testing/test_response.rb +35 -7
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +4 -2
- metadata +56 -38
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,28 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/inflector/methods"
|
2
4
|
require "active_support/dependencies"
|
3
5
|
|
4
6
|
module ActionDispatch
|
5
7
|
class MiddlewareStack
|
6
8
|
class Middleware
|
7
|
-
attr_reader :args, :block, :
|
8
|
-
|
9
|
-
def initialize(klass_or_name, *args, &block)
|
10
|
-
@klass = nil
|
11
|
-
|
12
|
-
if klass_or_name.respond_to?(:name)
|
13
|
-
@klass = klass_or_name
|
14
|
-
@name = @klass.name
|
15
|
-
else
|
16
|
-
@name = klass_or_name.to_s
|
17
|
-
end
|
9
|
+
attr_reader :args, :block, :klass
|
18
10
|
|
19
|
-
|
20
|
-
@
|
11
|
+
def initialize(klass, args, block)
|
12
|
+
@klass = klass
|
13
|
+
@args = args
|
14
|
+
@block = block
|
21
15
|
end
|
22
16
|
|
23
|
-
def klass
|
24
|
-
@klass || classcache[@name]
|
25
|
-
end
|
17
|
+
def name; klass.name; end
|
26
18
|
|
27
19
|
def ==(middleware)
|
28
20
|
case middleware
|
@@ -30,24 +22,20 @@ module ActionDispatch
|
|
30
22
|
klass == middleware.klass
|
31
23
|
when Class
|
32
24
|
klass == middleware
|
33
|
-
else
|
34
|
-
normalize(@name) == normalize(middleware)
|
35
25
|
end
|
36
26
|
end
|
37
27
|
|
38
28
|
def inspect
|
39
|
-
klass.
|
29
|
+
if klass.is_a?(Class)
|
30
|
+
klass.to_s
|
31
|
+
else
|
32
|
+
klass.class.to_s
|
33
|
+
end
|
40
34
|
end
|
41
35
|
|
42
36
|
def build(app)
|
43
37
|
klass.new(app, *args, &block)
|
44
38
|
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def normalize(object)
|
49
|
-
object.to_s.strip.sub(/^::/, '')
|
50
|
-
end
|
51
39
|
end
|
52
40
|
|
53
41
|
include Enumerable
|
@@ -75,19 +63,17 @@ module ActionDispatch
|
|
75
63
|
middlewares[i]
|
76
64
|
end
|
77
65
|
|
78
|
-
def unshift(*args, &block)
|
79
|
-
|
80
|
-
middlewares.unshift(middleware)
|
66
|
+
def unshift(klass, *args, &block)
|
67
|
+
middlewares.unshift(build_middleware(klass, args, block))
|
81
68
|
end
|
82
69
|
|
83
70
|
def initialize_copy(other)
|
84
71
|
self.middlewares = other.middlewares.dup
|
85
72
|
end
|
86
73
|
|
87
|
-
def insert(index, *args, &block)
|
74
|
+
def insert(index, klass, *args, &block)
|
88
75
|
index = assert_index(index, :before)
|
89
|
-
|
90
|
-
middlewares.insert(index, middleware)
|
76
|
+
middlewares.insert(index, build_middleware(klass, args, block))
|
91
77
|
end
|
92
78
|
|
93
79
|
alias_method :insert_before, :insert
|
@@ -104,26 +90,27 @@ module ActionDispatch
|
|
104
90
|
end
|
105
91
|
|
106
92
|
def delete(target)
|
107
|
-
middlewares.
|
93
|
+
middlewares.delete_if { |m| m.klass == target }
|
108
94
|
end
|
109
95
|
|
110
|
-
def use(*args, &block)
|
111
|
-
|
112
|
-
middlewares.push(middleware)
|
96
|
+
def use(klass, *args, &block)
|
97
|
+
middlewares.push(build_middleware(klass, args, block))
|
113
98
|
end
|
114
99
|
|
115
100
|
def build(app = nil, &block)
|
116
|
-
app
|
117
|
-
raise "MiddlewareStack#build requires an app" unless app
|
118
|
-
middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) }
|
101
|
+
middlewares.freeze.reverse.inject(app || block) { |a, e| e.build(a) }
|
119
102
|
end
|
120
103
|
|
121
|
-
|
104
|
+
private
|
122
105
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
128
115
|
end
|
129
116
|
end
|
@@ -1,35 +1,41 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/utils"
|
4
|
+
require "active_support/core_ext/uri"
|
3
5
|
|
4
6
|
module ActionDispatch
|
5
7
|
# This middleware returns a file's contents from disk in the body response.
|
6
|
-
# When initialized it can accept
|
7
|
-
#
|
8
|
+
# When initialized, it can accept optional HTTP headers, which will be set
|
9
|
+
# when a response containing a file's contents is delivered.
|
8
10
|
#
|
9
|
-
# This middleware will render the file specified in
|
10
|
-
# where the base path is in the +root+ directory. For example if the +root+
|
11
|
-
# is set to
|
12
|
-
#
|
13
|
-
# located at
|
14
|
-
# does not exist a 404 "File not Found" response will be returned.
|
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.
|
15
17
|
class FileHandler
|
16
|
-
def initialize(root,
|
17
|
-
@root = root.chomp(
|
18
|
-
@
|
19
|
-
|
20
|
-
@file_server = ::Rack::File.new(@root, headers)
|
18
|
+
def initialize(root, index: "index", headers: {})
|
19
|
+
@root = root.chomp("/").b
|
20
|
+
@file_server = ::Rack::File.new(@root, headers)
|
21
|
+
@index = index
|
21
22
|
end
|
22
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).
|
23
30
|
def match?(path)
|
24
|
-
path =
|
25
|
-
return false unless valid_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
|
26
34
|
|
27
|
-
paths = [path, "#{path}#{ext}", "#{path}
|
28
|
-
Rack::Utils.clean_path_info v
|
29
|
-
}
|
35
|
+
paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"]
|
30
36
|
|
31
37
|
if match = paths.detect { |p|
|
32
|
-
path = File.join(@root, p.
|
38
|
+
path = File.join(@root, p.b)
|
33
39
|
begin
|
34
40
|
File.file?(path) && File.readable?(path)
|
35
41
|
rescue SystemCallError
|
@@ -37,31 +43,35 @@ module ActionDispatch
|
|
37
43
|
end
|
38
44
|
|
39
45
|
}
|
40
|
-
return ::Rack::Utils.
|
46
|
+
return ::Rack::Utils.escape_path(match).b
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
44
50
|
def call(env)
|
45
|
-
|
51
|
+
serve(Rack::Request.new(env))
|
52
|
+
end
|
53
|
+
|
54
|
+
def serve(request)
|
55
|
+
path = request.path_info
|
46
56
|
gzip_path = gzip_file_path(path)
|
47
57
|
|
48
|
-
if gzip_path && gzip_encoding_accepted?(
|
49
|
-
|
50
|
-
status, headers, body = @file_server.call(env)
|
58
|
+
if gzip_path && gzip_encoding_accepted?(request)
|
59
|
+
request.path_info = gzip_path
|
60
|
+
status, headers, body = @file_server.call(request.env)
|
51
61
|
if status == 304
|
52
62
|
return [status, headers, body]
|
53
63
|
end
|
54
|
-
headers[
|
55
|
-
headers[
|
64
|
+
headers["Content-Encoding"] = "gzip"
|
65
|
+
headers["Content-Type"] = content_type(path)
|
56
66
|
else
|
57
|
-
status, headers, body = @file_server.call(env)
|
67
|
+
status, headers, body = @file_server.call(request.env)
|
58
68
|
end
|
59
69
|
|
60
|
-
headers[
|
70
|
+
headers["Vary"] = "Accept-Encoding" if gzip_path
|
61
71
|
|
62
72
|
return [status, headers, body]
|
63
73
|
ensure
|
64
|
-
|
74
|
+
request.path_info = path
|
65
75
|
end
|
66
76
|
|
67
77
|
private
|
@@ -70,54 +80,51 @@ module ActionDispatch
|
|
70
80
|
end
|
71
81
|
|
72
82
|
def content_type(path)
|
73
|
-
::Rack::Mime.mime_type(::File.extname(path),
|
83
|
+
::Rack::Mime.mime_type(::File.extname(path), "text/plain".freeze)
|
74
84
|
end
|
75
85
|
|
76
|
-
def gzip_encoding_accepted?(
|
77
|
-
|
86
|
+
def gzip_encoding_accepted?(request)
|
87
|
+
request.accept_encoding.any? { |enc, quality| enc =~ /\bgzip\b/i }
|
78
88
|
end
|
79
89
|
|
80
90
|
def gzip_file_path(path)
|
81
91
|
can_gzip_mime = content_type(path) =~ /\A(?:text\/|application\/javascript)/
|
82
92
|
gzip_path = "#{path}.gz"
|
83
|
-
if can_gzip_mime && File.exist?(File.join(@root, ::Rack::Utils.
|
84
|
-
gzip_path
|
93
|
+
if can_gzip_mime && File.exist?(File.join(@root, ::Rack::Utils.unescape_path(gzip_path).b))
|
94
|
+
gzip_path.b
|
85
95
|
else
|
86
96
|
false
|
87
97
|
end
|
88
98
|
end
|
89
|
-
|
90
|
-
def valid_path?(path)
|
91
|
-
path.valid_encoding? && !path.include?("\0")
|
92
|
-
end
|
93
99
|
end
|
94
100
|
|
95
101
|
# This middleware will attempt to return the contents of a file's body from
|
96
|
-
# disk in the response.
|
102
|
+
# disk in the response. If a file is not found on disk, the request will be
|
97
103
|
# delegated to the application stack. This middleware is commonly initialized
|
98
|
-
# to serve assets from a server's
|
104
|
+
# to serve assets from a server's +public/+ directory.
|
99
105
|
#
|
100
106
|
# This middleware verifies the path to ensure that only files
|
101
107
|
# living in the root directory can be rendered. A request cannot
|
102
108
|
# produce a directory traversal using this middleware. Only 'GET' and 'HEAD'
|
103
109
|
# requests will result in a file being returned.
|
104
110
|
class Static
|
105
|
-
def initialize(app, path,
|
111
|
+
def initialize(app, path, index: "index", headers: {})
|
106
112
|
@app = app
|
107
|
-
@file_handler = FileHandler.new(path,
|
113
|
+
@file_handler = FileHandler.new(path, index: index, headers: headers)
|
108
114
|
end
|
109
115
|
|
110
116
|
def call(env)
|
111
|
-
|
112
|
-
|
113
|
-
|
117
|
+
req = Rack::Request.new env
|
118
|
+
|
119
|
+
if req.get? || req.head?
|
120
|
+
path = req.path_info.chomp("/".freeze)
|
114
121
|
if match = @file_handler.match?(path)
|
115
|
-
|
116
|
-
return @file_handler.
|
122
|
+
req.path_info = match
|
123
|
+
return @file_handler.serve(req)
|
117
124
|
end
|
118
125
|
end
|
119
126
|
|
120
|
-
@app.call(env)
|
127
|
+
@app.call(req.env)
|
121
128
|
end
|
122
129
|
end
|
123
130
|
end
|
@@ -5,20 +5,8 @@
|
|
5
5
|
<pre id="blame_trace" <%='style="display:none"' if hide %>><code><%= @exception.describe_blame %></code></pre>
|
6
6
|
<% end %>
|
7
7
|
|
8
|
-
<%
|
9
|
-
clean_params = @request.filtered_parameters.clone
|
10
|
-
clean_params.delete("action")
|
11
|
-
clean_params.delete("controller")
|
12
|
-
|
13
|
-
request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
|
14
|
-
|
15
|
-
def debug_hash(object)
|
16
|
-
object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
|
17
|
-
end unless self.class.method_defined?(:debug_hash)
|
18
|
-
%>
|
19
|
-
|
20
8
|
<h2 style="margin-top: 30px">Request</h2>
|
21
|
-
<p><b>Parameters</b>:</p> <pre><%=
|
9
|
+
<p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
|
22
10
|
|
23
11
|
<div class="details">
|
24
12
|
<div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
|
@@ -31,4 +19,4 @@
|
|
31
19
|
</div>
|
32
20
|
|
33
21
|
<h2 style="margin-top: 30px">Response</h2>
|
34
|
-
<p><b>Headers</b>:</p> <pre><%= defined?(@response) ? @response.headers
|
22
|
+
<p><b>Headers</b>:</p> <pre><%= debug_headers(defined?(@response) ? @response.headers : {}) %></pre>
|
File without changes
|
@@ -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,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>
|
@@ -0,0 +1,13 @@
|
|
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 %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}.match?(@exception.message) %>
|
8
|
+
To resolve this issue run: bin/rails active_storage:install
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<%= render template: "rescues/_source" %>
|
12
|
+
<%= render template: "rescues/_trace" %>
|
13
|
+
<%= render template: "rescues/_request_and_response" %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= @exception.
|
1
|
+
<%= @exception.cause.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
|
2
2
|
|
3
3
|
Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised:
|
4
4
|
<%= @exception.message %>
|
@@ -4,13 +4,13 @@
|
|
4
4
|
<%= route[:name] %><span class='helper'>_path</span>
|
5
5
|
<% end %>
|
6
6
|
</td>
|
7
|
-
<td
|
7
|
+
<td>
|
8
8
|
<%= route[:verb] %>
|
9
9
|
</td>
|
10
|
-
<td data-route-path='<%= route[:path] %>'
|
10
|
+
<td data-route-path='<%= route[:path] %>'>
|
11
11
|
<%= route[:path] %>
|
12
12
|
</td>
|
13
|
-
<td
|
14
|
-
<%= route[:reqs] %>
|
13
|
+
<td>
|
14
|
+
<%=simple_format route[:reqs] %>
|
15
15
|
</td>
|
16
16
|
</tr>
|
@@ -17,6 +17,10 @@
|
|
17
17
|
line-height: 15px;
|
18
18
|
}
|
19
19
|
|
20
|
+
#route_table thead tr.bottom th input#search {
|
21
|
+
-webkit-appearance: textfield;
|
22
|
+
}
|
23
|
+
|
20
24
|
#route_table tbody tr {
|
21
25
|
border-bottom: 1px solid #ddd;
|
22
26
|
}
|
@@ -60,7 +64,7 @@
|
|
60
64
|
<%= link_to "Path", "#", 'data-route-helper' => '_path',
|
61
65
|
title: "Returns a relative path (without the http or domain)" %> /
|
62
66
|
<%= link_to "Url", "#", 'data-route-helper' => '_url',
|
63
|
-
title: "Returns an absolute
|
67
|
+
title: "Returns an absolute URL (with the http and domain)" %>
|
64
68
|
</th>
|
65
69
|
<th><%# HTTP Verb %>
|
66
70
|
</th>
|
@@ -81,92 +85,87 @@
|
|
81
85
|
</table>
|
82
86
|
|
83
87
|
<script type='text/javascript'>
|
84
|
-
//
|
85
|
-
|
86
|
-
if (!elems instanceof Array) { elems = [elems]; }
|
87
|
-
for (var i = 0, len = elems.length; i < len; i++) {
|
88
|
-
func(elems[i]);
|
89
|
-
}
|
90
|
-
}
|
91
|
-
|
92
|
-
// Sets innerHTML for an element
|
93
|
-
function setContent(elem, text) {
|
94
|
-
elem.innerHTML = text;
|
95
|
-
}
|
88
|
+
// support forEarch iterator on NodeList
|
89
|
+
NodeList.prototype.forEach = Array.prototype.forEach;
|
96
90
|
|
97
91
|
// Enables path search functionality
|
98
92
|
function setupMatchPaths() {
|
99
|
-
// Check if
|
100
|
-
function
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
showMatch(string, regexp, section, elem);
|
105
|
-
}
|
106
|
-
|
107
|
-
// Check if the route path data attribute contains the user input
|
108
|
-
function checkFuzzyMatch(section, elem, value) {
|
109
|
-
var string = elem.getAttribute("data-route-path"),
|
110
|
-
regexp = value;
|
111
|
-
|
112
|
-
showMatch(string, regexp, section, elem);
|
93
|
+
// Check if there are any matched results in a section
|
94
|
+
function checkNoMatch(section, noMatchText) {
|
95
|
+
if (section.children.length <= 1) {
|
96
|
+
section.innerHTML += noMatchText;
|
97
|
+
}
|
113
98
|
}
|
114
99
|
|
115
|
-
//
|
116
|
-
function
|
117
|
-
|
118
|
-
|
119
|
-
|
100
|
+
// get JSON from URL and invoke callback with result
|
101
|
+
function getJSON(url, success) {
|
102
|
+
var xhr = new XMLHttpRequest();
|
103
|
+
xhr.open('GET', url);
|
104
|
+
xhr.onload = function() {
|
105
|
+
if (this.status == 200)
|
106
|
+
success(JSON.parse(this.response));
|
107
|
+
};
|
108
|
+
xhr.send();
|
120
109
|
}
|
121
110
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
111
|
+
function delayedKeyup(input, callback) {
|
112
|
+
var timeout;
|
113
|
+
input.onkeyup = function(){
|
114
|
+
if (timeout) clearTimeout(timeout);
|
115
|
+
timeout = setTimeout(callback, 300);
|
126
116
|
}
|
127
117
|
}
|
128
118
|
|
129
|
-
//
|
119
|
+
// remove params or fragments
|
130
120
|
function sanitizePath(path) {
|
131
|
-
|
132
|
-
return path.replace(/\#.*|\?.*/, '');
|
121
|
+
return path.replace(/[#?].*/, '');
|
133
122
|
}
|
134
123
|
|
135
|
-
var
|
136
|
-
searchElem
|
137
|
-
|
138
|
-
|
124
|
+
var pathElements = document.querySelectorAll('#route_table [data-route-path]'),
|
125
|
+
searchElem = document.querySelector('#search'),
|
126
|
+
exactSection = document.querySelector('#exact_matches'),
|
127
|
+
fuzzySection = document.querySelector('#fuzzy_matches');
|
139
128
|
|
140
129
|
// Remove matches when no search value is present
|
141
130
|
searchElem.onblur = function(e) {
|
142
131
|
if (searchElem.value === "") {
|
143
|
-
|
144
|
-
|
132
|
+
exactSection.innerHTML = "";
|
133
|
+
fuzzySection.innerHTML = "";
|
145
134
|
}
|
146
135
|
}
|
147
136
|
|
148
137
|
// On key press perform a search for matching paths
|
149
|
-
searchElem
|
150
|
-
var
|
151
|
-
defaultExactMatch = '<tr><th colspan="4">Paths Matching (' +
|
152
|
-
defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' +
|
138
|
+
delayedKeyup(searchElem, function() {
|
139
|
+
var path = sanitizePath(searchElem.value),
|
140
|
+
defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + path +'):</th></tr>',
|
141
|
+
defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + path +'):</th></tr>',
|
153
142
|
noExactMatch = '<tr><th colspan="4">No Exact Matches Found</th></tr>',
|
154
143
|
noFuzzyMatch = '<tr><th colspan="4">No Fuzzy Matches Found</th></tr>';
|
155
144
|
|
156
|
-
|
157
|
-
|
158
|
-
setContent(fuzzyMatches, defaultFuzzyMatch);
|
145
|
+
if (!path)
|
146
|
+
return searchElem.onblur();
|
159
147
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
})
|
148
|
+
getJSON('/rails/info/routes?path=' + path, function(matches){
|
149
|
+
// Clear out results section
|
150
|
+
exactSection.innerHTML = defaultExactMatch;
|
151
|
+
fuzzySection.innerHTML = defaultFuzzyMatch;
|
165
152
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
153
|
+
// Display exact matches and fuzzy matches
|
154
|
+
pathElements.forEach(function(elem) {
|
155
|
+
var elemPath = elem.getAttribute('data-route-path');
|
156
|
+
|
157
|
+
if (matches['exact'].indexOf(elemPath) != -1)
|
158
|
+
exactSection.appendChild(elem.parentNode.cloneNode(true));
|
159
|
+
|
160
|
+
if (matches['fuzzy'].indexOf(elemPath) != -1)
|
161
|
+
fuzzySection.appendChild(elem.parentNode.cloneNode(true));
|
162
|
+
})
|
163
|
+
|
164
|
+
// Display 'No Matches' message when no matches are found
|
165
|
+
checkNoMatch(exactSection, noExactMatch);
|
166
|
+
checkNoMatch(fuzzySection, noFuzzyMatch);
|
167
|
+
})
|
168
|
+
})
|
170
169
|
}
|
171
170
|
|
172
171
|
// Enables functionality to toggle between `_path` and `_url` helper suffixes
|
@@ -174,19 +173,20 @@
|
|
174
173
|
|
175
174
|
// Sets content for each element
|
176
175
|
function setValOn(elems, val) {
|
177
|
-
|
178
|
-
|
176
|
+
elems.forEach(function(elem) {
|
177
|
+
elem.innerHTML = val;
|
179
178
|
});
|
180
179
|
}
|
181
180
|
|
182
181
|
// Sets onClick event for each element
|
183
182
|
function onClick(elems, func) {
|
184
|
-
|
183
|
+
elems.forEach(function(elem) {
|
185
184
|
elem.onclick = func;
|
186
185
|
});
|
187
186
|
}
|
188
187
|
|
189
188
|
var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
|
189
|
+
|
190
190
|
onClick(toggleLinks, function(){
|
191
191
|
var helperTxt = this.getAttribute("data-route-helper"),
|
192
192
|
helperElems = document.querySelectorAll('[data-route-name] span.helper');
|