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,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_dispatch"
|
4
|
+
require "active_support/messages/rotation_configuration"
|
2
5
|
|
3
6
|
module ActionDispatch
|
4
7
|
class Railtie < Rails::Railtie # :nodoc:
|
@@ -8,22 +11,29 @@ module ActionDispatch
|
|
8
11
|
config.action_dispatch.show_exceptions = true
|
9
12
|
config.action_dispatch.tld_length = 1
|
10
13
|
config.action_dispatch.ignore_accept_header = false
|
11
|
-
config.action_dispatch.rescue_templates = {
|
12
|
-
config.action_dispatch.rescue_responses = {
|
14
|
+
config.action_dispatch.rescue_templates = {}
|
15
|
+
config.action_dispatch.rescue_responses = {}
|
13
16
|
config.action_dispatch.default_charset = nil
|
14
17
|
config.action_dispatch.rack_cache = false
|
15
|
-
config.action_dispatch.http_auth_salt =
|
16
|
-
config.action_dispatch.signed_cookie_salt =
|
17
|
-
config.action_dispatch.encrypted_cookie_salt =
|
18
|
-
config.action_dispatch.encrypted_signed_cookie_salt =
|
18
|
+
config.action_dispatch.http_auth_salt = "http authentication"
|
19
|
+
config.action_dispatch.signed_cookie_salt = "signed cookie"
|
20
|
+
config.action_dispatch.encrypted_cookie_salt = "encrypted cookie"
|
21
|
+
config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie"
|
22
|
+
config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie"
|
23
|
+
config.action_dispatch.use_authenticated_cookie_encryption = false
|
19
24
|
config.action_dispatch.perform_deep_munge = true
|
20
25
|
|
21
26
|
config.action_dispatch.default_headers = {
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
"X-Frame-Options" => "SAMEORIGIN",
|
28
|
+
"X-XSS-Protection" => "1; mode=block",
|
29
|
+
"X-Content-Type-Options" => "nosniff",
|
30
|
+
"X-Download-Options" => "noopen",
|
31
|
+
"X-Permitted-Cross-Domain-Policies" => "none",
|
32
|
+
"Referrer-Policy" => "strict-origin-when-cross-origin"
|
25
33
|
}
|
26
34
|
|
35
|
+
config.action_dispatch.cookies_rotations = ActiveSupport::Messages::RotationConfiguration.new
|
36
|
+
|
27
37
|
config.eager_load_namespaces << ActionDispatch
|
28
38
|
|
29
39
|
initializer "action_dispatch.configure" do |app|
|
@@ -40,8 +50,6 @@ module ActionDispatch
|
|
40
50
|
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
|
41
51
|
|
42
52
|
ActionDispatch.test_app = app
|
43
|
-
|
44
|
-
ActionDispatch::Routing::RouteSet.relative_url_root = app.config.relative_url_root
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end
|
@@ -1,95 +1,105 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/session/abstract/id"
|
2
4
|
|
3
5
|
module ActionDispatch
|
4
|
-
class Request
|
6
|
+
class Request
|
5
7
|
# Session is responsible for lazily loading the session from store.
|
6
8
|
class Session # :nodoc:
|
7
|
-
ENV_SESSION_KEY = Rack::
|
8
|
-
ENV_SESSION_OPTIONS_KEY = Rack::
|
9
|
+
ENV_SESSION_KEY = Rack::RACK_SESSION # :nodoc:
|
10
|
+
ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS # :nodoc:
|
9
11
|
|
10
|
-
# Singleton object used to determine if an optional param wasn't specified
|
12
|
+
# Singleton object used to determine if an optional param wasn't specified.
|
11
13
|
Unspecified = Object.new
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
# Creates a session hash, merging the properties of the previous session if any.
|
16
|
+
def self.create(store, req, default_options)
|
17
|
+
session_was = find req
|
18
|
+
session = Request::Session.new(store, req)
|
16
19
|
session.merge! session_was if session_was
|
17
20
|
|
18
|
-
set(
|
19
|
-
Options.set(
|
21
|
+
set(req, session)
|
22
|
+
Options.set(req, Request::Session::Options.new(store, default_options))
|
20
23
|
session
|
21
24
|
end
|
22
25
|
|
23
|
-
def self.find(
|
24
|
-
|
26
|
+
def self.find(req)
|
27
|
+
req.get_header ENV_SESSION_KEY
|
25
28
|
end
|
26
29
|
|
27
|
-
def self.set(
|
28
|
-
|
30
|
+
def self.set(req, session)
|
31
|
+
req.set_header ENV_SESSION_KEY, session
|
29
32
|
end
|
30
33
|
|
31
34
|
class Options #:nodoc:
|
32
|
-
def self.set(
|
33
|
-
|
35
|
+
def self.set(req, options)
|
36
|
+
req.set_header ENV_SESSION_OPTIONS_KEY, options
|
34
37
|
end
|
35
38
|
|
36
|
-
def self.find(
|
37
|
-
|
39
|
+
def self.find(req)
|
40
|
+
req.get_header ENV_SESSION_OPTIONS_KEY
|
38
41
|
end
|
39
42
|
|
40
|
-
def initialize(by,
|
43
|
+
def initialize(by, default_options)
|
41
44
|
@by = by
|
42
|
-
@env = env
|
43
45
|
@delegate = default_options.dup
|
44
46
|
end
|
45
47
|
|
46
48
|
def [](key)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@
|
53
|
-
|
49
|
+
@delegate[key]
|
50
|
+
end
|
51
|
+
|
52
|
+
def id(req)
|
53
|
+
@delegate.fetch(:id) {
|
54
|
+
@by.send(:extract_session_id, req)
|
55
|
+
}
|
54
56
|
end
|
55
57
|
|
56
|
-
def []=(k,v);
|
58
|
+
def []=(k, v); @delegate[k] = v; end
|
57
59
|
def to_hash; @delegate.dup; end
|
58
60
|
def values_at(*args); @delegate.values_at(*args); end
|
59
61
|
end
|
60
62
|
|
61
|
-
def initialize(by,
|
63
|
+
def initialize(by, req)
|
62
64
|
@by = by
|
63
|
-
@
|
65
|
+
@req = req
|
64
66
|
@delegate = {}
|
65
67
|
@loaded = false
|
66
|
-
@exists = nil #
|
68
|
+
@exists = nil # We haven't checked yet.
|
67
69
|
end
|
68
70
|
|
69
71
|
def id
|
70
|
-
options
|
72
|
+
options.id(@req)
|
71
73
|
end
|
72
74
|
|
73
75
|
def options
|
74
|
-
Options.find @
|
76
|
+
Options.find @req
|
75
77
|
end
|
76
78
|
|
77
79
|
def destroy
|
78
80
|
clear
|
79
81
|
options = self.options || {}
|
80
|
-
|
81
|
-
options[:id] = new_sid # Reset session id with a new value or nil
|
82
|
+
@by.send(:delete_session, @req, options.id(@req), options)
|
82
83
|
|
83
|
-
# Load the new sid to be written with the response
|
84
|
+
# Load the new sid to be written with the response.
|
84
85
|
@loaded = false
|
85
86
|
load_for_write!
|
86
87
|
end
|
87
88
|
|
89
|
+
# Returns value of the key stored in the session or
|
90
|
+
# +nil+ if the given key is not found in the session.
|
88
91
|
def [](key)
|
89
92
|
load_for_read!
|
90
|
-
|
93
|
+
key = key.to_s
|
94
|
+
|
95
|
+
if key == "session_id"
|
96
|
+
id&.public_id
|
97
|
+
else
|
98
|
+
@delegate[key]
|
99
|
+
end
|
91
100
|
end
|
92
101
|
|
102
|
+
# Returns true if the session has the given key or false.
|
93
103
|
def has_key?(key)
|
94
104
|
load_for_read!
|
95
105
|
@delegate.key?(key.to_s)
|
@@ -97,40 +107,73 @@ module ActionDispatch
|
|
97
107
|
alias :key? :has_key?
|
98
108
|
alias :include? :has_key?
|
99
109
|
|
110
|
+
# Returns keys of the session as Array.
|
100
111
|
def keys
|
112
|
+
load_for_read!
|
101
113
|
@delegate.keys
|
102
114
|
end
|
103
115
|
|
116
|
+
# Returns values of the session as Array.
|
104
117
|
def values
|
118
|
+
load_for_read!
|
105
119
|
@delegate.values
|
106
120
|
end
|
107
121
|
|
122
|
+
# Writes given value to given key of the session.
|
108
123
|
def []=(key, value)
|
109
124
|
load_for_write!
|
110
125
|
@delegate[key.to_s] = value
|
111
126
|
end
|
112
127
|
|
128
|
+
# Clears the session.
|
113
129
|
def clear
|
114
130
|
load_for_write!
|
115
131
|
@delegate.clear
|
116
132
|
end
|
117
133
|
|
134
|
+
# Returns the session as Hash.
|
118
135
|
def to_hash
|
119
136
|
load_for_read!
|
120
|
-
@delegate.dup.delete_if { |_,v| v.nil? }
|
121
|
-
end
|
122
|
-
|
137
|
+
@delegate.dup.delete_if { |_, v| v.nil? }
|
138
|
+
end
|
139
|
+
alias :to_h :to_hash
|
140
|
+
|
141
|
+
# Updates the session with given Hash.
|
142
|
+
#
|
143
|
+
# session.to_hash
|
144
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2"}
|
145
|
+
#
|
146
|
+
# session.update({ "foo" => "bar" })
|
147
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
|
148
|
+
#
|
149
|
+
# session.to_hash
|
150
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
|
123
151
|
def update(hash)
|
124
152
|
load_for_write!
|
125
153
|
@delegate.update stringify_keys(hash)
|
126
154
|
end
|
127
155
|
|
156
|
+
# Deletes given key from the session.
|
128
157
|
def delete(key)
|
129
158
|
load_for_write!
|
130
159
|
@delegate.delete key.to_s
|
131
160
|
end
|
132
161
|
|
133
|
-
|
162
|
+
# Returns value of the given key from the session, or raises +KeyError+
|
163
|
+
# if can't find the given key and no default value is set.
|
164
|
+
# Returns default value if specified.
|
165
|
+
#
|
166
|
+
# session.fetch(:foo)
|
167
|
+
# # => KeyError: key not found: "foo"
|
168
|
+
#
|
169
|
+
# session.fetch(:foo, :bar)
|
170
|
+
# # => :bar
|
171
|
+
#
|
172
|
+
# session.fetch(:foo) do
|
173
|
+
# :bar
|
174
|
+
# end
|
175
|
+
# # => :bar
|
176
|
+
def fetch(key, default = Unspecified, &block)
|
134
177
|
load_for_read!
|
135
178
|
if default == Unspecified
|
136
179
|
@delegate.fetch(key.to_s, &block)
|
@@ -149,7 +192,7 @@ module ActionDispatch
|
|
149
192
|
|
150
193
|
def exists?
|
151
194
|
return @exists unless @exists.nil?
|
152
|
-
@exists = @by.send(:session_exists?, @
|
195
|
+
@exists = @by.send(:session_exists?, @req)
|
153
196
|
end
|
154
197
|
|
155
198
|
def loaded?
|
@@ -166,28 +209,32 @@ module ActionDispatch
|
|
166
209
|
@delegate.merge!(other)
|
167
210
|
end
|
168
211
|
|
212
|
+
def each(&block)
|
213
|
+
to_hash.each(&block)
|
214
|
+
end
|
215
|
+
|
169
216
|
private
|
170
217
|
|
171
|
-
|
172
|
-
|
173
|
-
|
218
|
+
def load_for_read!
|
219
|
+
load! if !loaded? && exists?
|
220
|
+
end
|
174
221
|
|
175
|
-
|
176
|
-
|
177
|
-
|
222
|
+
def load_for_write!
|
223
|
+
load! unless loaded?
|
224
|
+
end
|
178
225
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
226
|
+
def load!
|
227
|
+
id, session = @by.load_session @req
|
228
|
+
options[:id] = id
|
229
|
+
@delegate.replace(stringify_keys(session))
|
230
|
+
@loaded = true
|
231
|
+
end
|
185
232
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
233
|
+
def stringify_keys(other)
|
234
|
+
other.each_with_object({}) { |(key, value), hash|
|
235
|
+
hash[key.to_s] = value
|
236
|
+
}
|
237
|
+
end
|
191
238
|
end
|
192
239
|
end
|
193
240
|
end
|
@@ -1,35 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/indifferent_access"
|
4
|
+
|
1
5
|
module ActionDispatch
|
2
|
-
class Request
|
6
|
+
class Request
|
3
7
|
class Utils # :nodoc:
|
8
|
+
mattr_accessor :perform_deep_munge, default: true
|
9
|
+
|
10
|
+
def self.each_param_value(params, &block)
|
11
|
+
case params
|
12
|
+
when Array
|
13
|
+
params.each { |element| each_param_value(element, &block) }
|
14
|
+
when Hash
|
15
|
+
params.each_value { |value| each_param_value(value, &block) }
|
16
|
+
when String
|
17
|
+
block.call params
|
18
|
+
end
|
19
|
+
end
|
4
20
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
def self.normalize_encode_params(params)
|
22
|
+
if perform_deep_munge
|
23
|
+
NoNilParamEncoder.normalize_encode_params params
|
24
|
+
else
|
25
|
+
ParamEncoder.normalize_encode_params params
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.check_param_encoding(params)
|
30
|
+
case params
|
31
|
+
when Array
|
32
|
+
params.each { |element| check_param_encoding(element) }
|
33
|
+
when Hash
|
34
|
+
params.each_value { |value| check_param_encoding(value) }
|
35
|
+
when String
|
36
|
+
unless params.valid_encoding?
|
37
|
+
# Raise Rack::Utils::InvalidParameterError for consistency with Rack.
|
38
|
+
# ActionDispatch::Request#GET will re-raise as a BadRequest error.
|
39
|
+
raise Rack::Utils::InvalidParameterError, "Invalid encoding for parameter: #{params.scrub}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ParamEncoder # :nodoc:
|
45
|
+
# Convert nested Hash to HashWithIndifferentAccess.
|
46
|
+
def self.normalize_encode_params(params)
|
47
|
+
case params
|
48
|
+
when Array
|
49
|
+
handle_array params
|
50
|
+
when Hash
|
51
|
+
if params.has_key?(:tempfile)
|
52
|
+
ActionDispatch::Http::UploadedFile.new(params)
|
53
|
+
else
|
54
|
+
params.each_with_object({}) do |(key, val), new_hash|
|
55
|
+
new_hash[key] = normalize_encode_params(val)
|
56
|
+
end.with_indifferent_access
|
25
57
|
end
|
26
|
-
|
58
|
+
else
|
59
|
+
params
|
27
60
|
end
|
61
|
+
end
|
28
62
|
|
29
|
-
|
63
|
+
def self.handle_array(params)
|
64
|
+
params.map! { |el| normalize_encode_params(el) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Remove nils from the params hash.
|
69
|
+
class NoNilParamEncoder < ParamEncoder # :nodoc:
|
70
|
+
def self.handle_array(params)
|
71
|
+
list = super
|
72
|
+
list.compact!
|
73
|
+
list
|
30
74
|
end
|
31
75
|
end
|
32
76
|
end
|
33
77
|
end
|
34
78
|
end
|
35
|
-
|
@@ -1,10 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionDispatch
|
2
4
|
module Routing
|
3
5
|
class Endpoint # :nodoc:
|
4
6
|
def dispatcher?; false; end
|
5
7
|
def redirect?; false; end
|
6
|
-
def matches?(req);
|
7
|
-
def app;
|
8
|
+
def matches?(req); true; end
|
9
|
+
def app; self; end
|
10
|
+
def rack_app; app; end
|
11
|
+
|
12
|
+
def engine?
|
13
|
+
rack_app.is_a?(Class) && rack_app < Rails::Engine
|
14
|
+
end
|
8
15
|
end
|
9
16
|
end
|
10
17
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
require "active_support/core_ext/string/strip"
|
3
5
|
|
4
6
|
module ActionDispatch
|
5
7
|
module Routing
|
@@ -13,11 +15,7 @@ module ActionDispatch
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def rack_app
|
16
|
-
app.
|
17
|
-
end
|
18
|
-
|
19
|
-
def verb
|
20
|
-
super.source.gsub(/[$^]/, '')
|
18
|
+
app.rack_app
|
21
19
|
end
|
22
20
|
|
23
21
|
def path
|
@@ -28,23 +26,6 @@ module ActionDispatch
|
|
28
26
|
super.to_s
|
29
27
|
end
|
30
28
|
|
31
|
-
def regexp
|
32
|
-
__getobj__.path.to_regexp
|
33
|
-
end
|
34
|
-
|
35
|
-
def json_regexp
|
36
|
-
str = regexp.inspect.
|
37
|
-
sub('\\A' , '^').
|
38
|
-
sub('\\Z' , '$').
|
39
|
-
sub('\\z' , '$').
|
40
|
-
sub(/^\// , '').
|
41
|
-
sub(/\/[a-z]*$/ , '').
|
42
|
-
gsub(/\(\?#.+\)/ , '').
|
43
|
-
gsub(/\(\?-\w+:/ , '(').
|
44
|
-
gsub(/\s/ , '')
|
45
|
-
Regexp.new(str).source
|
46
|
-
end
|
47
|
-
|
48
29
|
def reqs
|
49
30
|
@reqs ||= begin
|
50
31
|
reqs = endpoint
|
@@ -54,25 +35,25 @@ module ActionDispatch
|
|
54
35
|
end
|
55
36
|
|
56
37
|
def controller
|
57
|
-
|
38
|
+
parts.include?(:controller) ? ":controller" : requirements[:controller]
|
58
39
|
end
|
59
40
|
|
60
41
|
def action
|
61
|
-
|
42
|
+
parts.include?(:action) ? ":action" : requirements[:action]
|
62
43
|
end
|
63
44
|
|
64
45
|
def internal?
|
65
|
-
|
46
|
+
internal
|
66
47
|
end
|
67
48
|
|
68
49
|
def engine?
|
69
|
-
|
50
|
+
app.engine?
|
70
51
|
end
|
71
52
|
end
|
72
53
|
|
73
54
|
##
|
74
55
|
# This class is just used for displaying route information when someone
|
75
|
-
# executes `
|
56
|
+
# executes `rails routes` or looks at the RoutingError page.
|
76
57
|
# People should not use this class.
|
77
58
|
class RoutesInspector # :nodoc:
|
78
59
|
def initialize(routes)
|
@@ -81,12 +62,10 @@ module ActionDispatch
|
|
81
62
|
end
|
82
63
|
|
83
64
|
def format(formatter, filter = nil)
|
84
|
-
routes_to_display = filter_routes(filter)
|
85
|
-
|
65
|
+
routes_to_display = filter_routes(normalize_filter(filter))
|
86
66
|
routes = collect_routes(routes_to_display)
|
87
|
-
|
88
67
|
if routes.none?
|
89
|
-
formatter.no_routes
|
68
|
+
formatter.no_routes(collect_routes(@routes))
|
90
69
|
return formatter.result
|
91
70
|
end
|
92
71
|
|
@@ -103,40 +82,48 @@ module ActionDispatch
|
|
103
82
|
|
104
83
|
private
|
105
84
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
85
|
+
def normalize_filter(filter)
|
86
|
+
if filter.is_a?(Hash) && filter[:controller]
|
87
|
+
{ controller: /#{filter[:controller].underscore.sub(/_?controller\z/, "")}/ }
|
88
|
+
elsif filter
|
89
|
+
{ controller: /#{filter}/, action: /#{filter}/, verb: /#{filter}/, name: /#{filter}/, path: /#{filter}/ }
|
90
|
+
end
|
111
91
|
end
|
112
|
-
end
|
113
92
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
93
|
+
def filter_routes(filter)
|
94
|
+
if filter
|
95
|
+
@routes.select do |route|
|
96
|
+
route_wrapper = RouteWrapper.new(route)
|
97
|
+
filter.any? { |default, value| route_wrapper.send(default) =~ value }
|
98
|
+
end
|
99
|
+
else
|
100
|
+
@routes
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def collect_routes(routes)
|
105
|
+
routes.collect do |route|
|
106
|
+
RouteWrapper.new(route)
|
107
|
+
end.reject(&:internal?).collect do |route|
|
108
|
+
collect_engine_routes(route)
|
121
109
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
110
|
+
{ name: route.name,
|
111
|
+
verb: route.verb,
|
112
|
+
path: route.path,
|
113
|
+
reqs: route.reqs }
|
114
|
+
end
|
127
115
|
end
|
128
|
-
end
|
129
116
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
117
|
+
def collect_engine_routes(route)
|
118
|
+
name = route.endpoint
|
119
|
+
return unless route.engine?
|
120
|
+
return if @engines[name]
|
134
121
|
|
135
|
-
|
136
|
-
|
137
|
-
|
122
|
+
routes = route.rack_app.routes
|
123
|
+
if routes.is_a?(ActionDispatch::Routing::RouteSet)
|
124
|
+
@engines[name] = collect_routes(routes.routes)
|
125
|
+
end
|
138
126
|
end
|
139
|
-
end
|
140
127
|
end
|
141
128
|
|
142
129
|
class ConsoleFormatter
|
@@ -160,19 +147,23 @@ module ActionDispatch
|
|
160
147
|
@buffer << draw_header(routes)
|
161
148
|
end
|
162
149
|
|
163
|
-
def no_routes
|
164
|
-
@buffer <<
|
150
|
+
def no_routes(routes)
|
151
|
+
@buffer <<
|
152
|
+
if routes.none?
|
153
|
+
<<-MESSAGE.strip_heredoc
|
165
154
|
You don't have any routes defined!
|
166
155
|
|
167
156
|
Please add some routes in config/routes.rb.
|
168
|
-
|
169
|
-
For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html.
|
170
157
|
MESSAGE
|
158
|
+
else
|
159
|
+
"No routes were found for this controller"
|
160
|
+
end
|
161
|
+
@buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
|
171
162
|
end
|
172
163
|
|
173
164
|
private
|
174
165
|
def draw_section(routes)
|
175
|
-
header_lengths = [
|
166
|
+
header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length)
|
176
167
|
name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
|
177
168
|
|
178
169
|
routes.map do |r|
|
@@ -207,11 +198,11 @@ module ActionDispatch
|
|
207
198
|
@buffer << @view.render(partial: "routes/route", collection: routes)
|
208
199
|
end
|
209
200
|
|
210
|
-
#
|
201
|
+
# The header is part of the HTML page, so we don't construct it here.
|
211
202
|
def header(routes)
|
212
203
|
end
|
213
204
|
|
214
|
-
def no_routes
|
205
|
+
def no_routes(*)
|
215
206
|
@buffer << <<-MESSAGE.strip_heredoc
|
216
207
|
<p>You don't have any routes defined!</p>
|
217
208
|
<ul>
|