actionpack 5.2.8.1 → 6.0.6
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 +270 -347
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/abstract_controller/base.rb +4 -3
- data/lib/abstract_controller/caching/fragments.rb +6 -22
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +12 -0
- data/lib/abstract_controller/collector.rb +1 -2
- data/lib/abstract_controller/helpers.rb +7 -6
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
- data/lib/abstract_controller/translation.rb +4 -4
- data/lib/action_controller/api.rb +2 -1
- data/lib/action_controller/base.rb +2 -7
- data/lib/action_controller/caching.rb +1 -2
- data/lib/action_controller/log_subscriber.rb +8 -5
- data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
- data/lib/action_controller/metal/conditional_get.rb +9 -3
- data/lib/action_controller/metal/content_security_policy.rb +0 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -6
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +23 -2
- data/lib/action_controller/metal/flash.rb +5 -5
- data/lib/action_controller/metal/force_ssl.rb +15 -56
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/helpers.rb +3 -4
- data/lib/action_controller/metal/http_authentication.rb +20 -21
- data/lib/action_controller/metal/implicit_render.rb +4 -14
- data/lib/action_controller/metal/instrumentation.rb +3 -6
- data/lib/action_controller/metal/live.rb +29 -31
- data/lib/action_controller/metal/mime_responds.rb +13 -2
- data/lib/action_controller/metal/params_wrapper.rb +18 -14
- data/lib/action_controller/metal/redirecting.rb +5 -5
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +2 -3
- data/lib/action_controller/metal/request_forgery_protection.rb +25 -48
- data/lib/action_controller/metal/streaming.rb +0 -1
- data/lib/action_controller/metal/strong_parameters.rb +65 -44
- data/lib/action_controller/metal/url_for.rb +1 -1
- data/lib/action_controller/metal.rb +8 -6
- data/lib/action_controller/railties/helpers.rb +1 -1
- data/lib/action_controller/renderer.rb +17 -3
- data/lib/action_controller/template_assertions.rb +1 -1
- data/lib/action_controller/test_case.rb +7 -8
- data/lib/action_controller.rb +5 -1
- data/lib/action_dispatch/http/cache.rb +14 -11
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +28 -17
- data/lib/action_dispatch/http/filter_parameters.rb +8 -7
- data/lib/action_dispatch/http/filter_redirect.rb +1 -2
- data/lib/action_dispatch/http/headers.rb +1 -2
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -6
- data/lib/action_dispatch/http/mime_type.rb +14 -8
- data/lib/action_dispatch/http/parameter_filter.rb +5 -79
- data/lib/action_dispatch/http/parameters.rb +15 -6
- data/lib/action_dispatch/http/request.rb +21 -14
- data/lib/action_dispatch/http/response.rb +40 -21
- data/lib/action_dispatch/http/upload.rb +9 -1
- data/lib/action_dispatch/http/url.rb +81 -82
- data/lib/action_dispatch/journey/formatter.rb +2 -3
- data/lib/action_dispatch/journey/gtg/builder.rb +0 -1
- data/lib/action_dispatch/journey/gtg/transition_table.rb +0 -1
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -1
- data/lib/action_dispatch/journey/nodes/node.rb +9 -8
- data/lib/action_dispatch/journey/path/pattern.rb +6 -3
- data/lib/action_dispatch/journey/route.rb +5 -4
- data/lib/action_dispatch/journey/router/utils.rb +10 -10
- data/lib/action_dispatch/journey/router.rb +0 -4
- data/lib/action_dispatch/journey/routes.rb +0 -2
- data/lib/action_dispatch/journey/scanner.rb +10 -4
- data/lib/action_dispatch/journey/visitors.rb +1 -4
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -4
- data/lib/action_dispatch/middleware/cookies.rb +62 -78
- data/lib/action_dispatch/middleware/debug_exceptions.rb +45 -61
- data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +49 -16
- data/lib/action_dispatch/middleware/flash.rb +1 -1
- data/lib/action_dispatch/middleware/host_authorization.rb +121 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +9 -12
- data/lib/action_dispatch/middleware/request_id.rb +2 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +0 -1
- data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -7
- data/lib/action_dispatch/middleware/show_exceptions.rb +1 -2
- data/lib/action_dispatch/middleware/ssl.rb +8 -8
- data/lib/action_dispatch/middleware/stack.rb +38 -2
- data/lib/action_dispatch/middleware/static.rb +6 -7
- 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/_request_and_response.html.erb +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +7 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +5 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -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 +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
- data/lib/action_dispatch/railtie.rb +7 -2
- data/lib/action_dispatch/request/session.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +97 -50
- data/lib/action_dispatch/routing/mapper.rb +63 -42
- data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -6
- data/lib/action_dispatch/routing/route_set.rb +25 -31
- data/lib/action_dispatch/routing/url_for.rb +2 -2
- data/lib/action_dispatch/routing.rb +21 -20
- data/lib/action_dispatch/system_test_case.rb +44 -6
- data/lib/action_dispatch/system_testing/browser.rb +38 -7
- data/lib/action_dispatch/system_testing/driver.rb +11 -2
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -5
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +7 -6
- data/lib/action_dispatch/testing/assertion_response.rb +0 -1
- data/lib/action_dispatch/testing/assertions/response.rb +2 -3
- data/lib/action_dispatch/testing/assertions/routing.rb +15 -3
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/integration.rb +33 -12
- data/lib/action_dispatch/testing/request_encoder.rb +2 -2
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch/testing/test_response.rb +4 -32
- data/lib/action_dispatch.rb +7 -2
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +29 -15
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -10,12 +10,15 @@
|
|
10
10
|
<div id="container">
|
11
11
|
<h2>
|
12
12
|
<%= h @exception.message %>
|
13
|
-
<% if %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}
|
14
|
-
<br />To resolve this issue run:
|
13
|
+
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
|
14
|
+
<br />To resolve this issue run: 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: rails action_mailbox:install
|
15
18
|
<% end %>
|
16
19
|
</h2>
|
17
20
|
|
18
|
-
<%= render
|
19
|
-
<%= render
|
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 %>
|
20
23
|
<%= render template: "rescues/_request_and_response" %>
|
21
24
|
</div>
|
@@ -4,8 +4,11 @@
|
|
4
4
|
<% end %>
|
5
5
|
|
6
6
|
<%= @exception.message %>
|
7
|
-
<% if %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}
|
8
|
-
To resolve this issue run:
|
7
|
+
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
|
8
|
+
To resolve this issue run: rails active_storage:install
|
9
|
+
<% end %>
|
10
|
+
<% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
|
11
|
+
To resolve this issue run: rails action_mailbox:install
|
9
12
|
<% end %>
|
10
13
|
|
11
14
|
<%= render template: "rescues/_source" %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<header>
|
2
|
+
<h1>No template for interactive request</h1>
|
3
|
+
</header>
|
4
|
+
|
5
|
+
<div id="container">
|
6
|
+
<h2><%= h @exception.message %></h2>
|
7
|
+
|
8
|
+
<p class="summary">
|
9
|
+
<strong>NOTE!</strong><br>
|
10
|
+
Unless told otherwise, Rails expects an action to render a template with the same name,<br>
|
11
|
+
contained in a folder named after its controller.
|
12
|
+
|
13
|
+
If this controller is an API responding with 204 (No Content), <br>
|
14
|
+
which does not require a template,
|
15
|
+
then this error will occur when trying to access it via browser,<br>
|
16
|
+
since we expect an HTML template
|
17
|
+
to be rendered for such requests. If that's the case, carry on.
|
18
|
+
</p>
|
19
|
+
</div>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<div id="container">
|
6
6
|
<h2><%= h @exception.message %></h2>
|
7
7
|
|
8
|
-
<%= render
|
9
|
-
<%= render
|
8
|
+
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
9
|
+
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
10
10
|
<%= render template: "rescues/_request_and_response" %>
|
11
11
|
</div>
|
@@ -11,10 +11,10 @@
|
|
11
11
|
</p>
|
12
12
|
<pre><code><%= h @exception.message %></code></pre>
|
13
13
|
|
14
|
-
<%= render
|
14
|
+
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
15
15
|
|
16
16
|
<p><%= @exception.sub_template_message %></p>
|
17
17
|
|
18
|
-
<%= render
|
18
|
+
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
19
19
|
<%= render template: "rescues/_request_and_response" %>
|
20
20
|
</div>
|
@@ -21,7 +21,9 @@ module ActionDispatch
|
|
21
21
|
config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie"
|
22
22
|
config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie"
|
23
23
|
config.action_dispatch.use_authenticated_cookie_encryption = false
|
24
|
+
config.action_dispatch.use_cookies_with_metadata = false
|
24
25
|
config.action_dispatch.perform_deep_munge = true
|
26
|
+
config.action_dispatch.return_only_media_type_on_content_type = true
|
25
27
|
|
26
28
|
config.action_dispatch.default_headers = {
|
27
29
|
"X-Frame-Options" => "SAMEORIGIN",
|
@@ -40,8 +42,11 @@ module ActionDispatch
|
|
40
42
|
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
|
41
43
|
ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
|
42
44
|
ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
|
43
|
-
|
44
|
-
|
45
|
+
ActiveSupport.on_load(:action_dispatch_response) do
|
46
|
+
self.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
|
47
|
+
self.default_headers = app.config.action_dispatch.default_headers
|
48
|
+
self.return_only_media_type_on_content_type = app.config.action_dispatch.return_only_media_type_on_content_type
|
49
|
+
end
|
45
50
|
|
46
51
|
ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
|
47
52
|
ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)
|
@@ -93,12 +93,20 @@ module ActionDispatch
|
|
93
93
|
key = key.to_s
|
94
94
|
|
95
95
|
if key == "session_id"
|
96
|
-
id
|
96
|
+
id&.public_id
|
97
97
|
else
|
98
98
|
@delegate[key]
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
+
# Returns the nested value specified by the sequence of keys, returning
|
103
|
+
# +nil+ if any intermediate step is +nil+.
|
104
|
+
def dig(*keys)
|
105
|
+
load_for_read!
|
106
|
+
keys = keys.map.with_index { |key, i| i.zero? ? key.to_s : key }
|
107
|
+
@delegate.dig(*keys)
|
108
|
+
end
|
109
|
+
|
102
110
|
# Returns true if the session has the given key or false.
|
103
111
|
def has_key?(key)
|
104
112
|
load_for_read!
|
@@ -214,7 +222,6 @@ module ActionDispatch
|
|
214
222
|
end
|
215
223
|
|
216
224
|
private
|
217
|
-
|
218
225
|
def load_for_read!
|
219
226
|
load! if !loaded? && exists?
|
220
227
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "delegate"
|
4
|
-
require "
|
4
|
+
require "io/console/size"
|
5
5
|
|
6
6
|
module ActionDispatch
|
7
7
|
module Routing
|
@@ -61,11 +61,11 @@ module ActionDispatch
|
|
61
61
|
@routes = routes
|
62
62
|
end
|
63
63
|
|
64
|
-
def format(formatter, filter =
|
64
|
+
def format(formatter, filter = {})
|
65
65
|
routes_to_display = filter_routes(normalize_filter(filter))
|
66
66
|
routes = collect_routes(routes_to_display)
|
67
67
|
if routes.none?
|
68
|
-
formatter.no_routes(collect_routes(@routes))
|
68
|
+
formatter.no_routes(collect_routes(@routes), filter)
|
69
69
|
return formatter.result
|
70
70
|
end
|
71
71
|
|
@@ -81,12 +81,12 @@ module ActionDispatch
|
|
81
81
|
end
|
82
82
|
|
83
83
|
private
|
84
|
-
|
85
84
|
def normalize_filter(filter)
|
86
|
-
if filter
|
85
|
+
if filter[:controller]
|
87
86
|
{ controller: /#{filter[:controller].underscore.sub(/_?controller\z/, "")}/ }
|
88
|
-
elsif filter
|
89
|
-
{ controller: /#{filter}/, action: /#{filter
|
87
|
+
elsif filter[:grep]
|
88
|
+
{ controller: /#{filter[:grep]}/, action: /#{filter[:grep]}/,
|
89
|
+
verb: /#{filter[:grep]}/, name: /#{filter[:grep]}/, path: /#{filter[:grep]}/ }
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -126,62 +126,109 @@ module ActionDispatch
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
129
|
+
module ConsoleFormatter
|
130
|
+
class Base
|
131
|
+
def initialize
|
132
|
+
@buffer = []
|
133
|
+
end
|
133
134
|
|
134
|
-
|
135
|
-
|
136
|
-
|
135
|
+
def result
|
136
|
+
@buffer.join("\n")
|
137
|
+
end
|
137
138
|
|
138
|
-
|
139
|
-
|
140
|
-
end
|
139
|
+
def section_title(title)
|
140
|
+
end
|
141
141
|
|
142
|
-
|
143
|
-
|
144
|
-
end
|
142
|
+
def section(routes)
|
143
|
+
end
|
145
144
|
|
146
|
-
|
147
|
-
|
148
|
-
end
|
145
|
+
def header(routes)
|
146
|
+
end
|
149
147
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
148
|
+
def no_routes(routes, filter)
|
149
|
+
@buffer <<
|
150
|
+
if routes.none?
|
151
|
+
<<~MESSAGE
|
152
|
+
You don't have any routes defined!
|
153
|
+
|
154
|
+
Please add some routes in config/routes.rb.
|
155
|
+
MESSAGE
|
156
|
+
elsif filter.key?(:controller)
|
157
|
+
"No routes were found for this controller."
|
158
|
+
elsif filter.key?(:grep)
|
159
|
+
"No routes were found for this grep pattern."
|
160
|
+
end
|
155
161
|
|
156
|
-
|
157
|
-
MESSAGE
|
158
|
-
else
|
159
|
-
"No routes were found for this controller"
|
162
|
+
@buffer << "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
|
160
163
|
end
|
161
|
-
@buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
|
162
164
|
end
|
163
165
|
|
164
|
-
|
165
|
-
def
|
166
|
-
|
167
|
-
|
166
|
+
class Sheet < Base
|
167
|
+
def section_title(title)
|
168
|
+
@buffer << "\n#{title}:"
|
169
|
+
end
|
168
170
|
|
169
|
-
|
170
|
-
|
171
|
-
|
171
|
+
def section(routes)
|
172
|
+
@buffer << draw_section(routes)
|
173
|
+
end
|
174
|
+
|
175
|
+
def header(routes)
|
176
|
+
@buffer << draw_header(routes)
|
172
177
|
end
|
173
178
|
|
174
|
-
|
175
|
-
|
179
|
+
private
|
180
|
+
def draw_section(routes)
|
181
|
+
header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length)
|
182
|
+
name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
|
183
|
+
|
184
|
+
routes.map do |r|
|
185
|
+
"#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def draw_header(routes)
|
190
|
+
name_width, verb_width, path_width = widths(routes)
|
176
191
|
|
177
|
-
|
192
|
+
"#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action"
|
193
|
+
end
|
194
|
+
|
195
|
+
def widths(routes)
|
196
|
+
[routes.map { |r| r[:name].length }.max || 0,
|
197
|
+
routes.map { |r| r[:verb].length }.max || 0,
|
198
|
+
routes.map { |r| r[:path].length }.max || 0]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class Expanded < Base
|
203
|
+
def section_title(title)
|
204
|
+
@buffer << "\n#{"[ #{title} ]"}"
|
178
205
|
end
|
179
206
|
|
180
|
-
def
|
181
|
-
|
182
|
-
routes.map { |r| r[:verb].length }.max || 0,
|
183
|
-
routes.map { |r| r[:path].length }.max || 0]
|
207
|
+
def section(routes)
|
208
|
+
@buffer << draw_expanded_section(routes)
|
184
209
|
end
|
210
|
+
|
211
|
+
private
|
212
|
+
def draw_expanded_section(routes)
|
213
|
+
routes.map.each_with_index do |r, i|
|
214
|
+
<<~MESSAGE.chomp
|
215
|
+
#{route_header(index: i + 1)}
|
216
|
+
Prefix | #{r[:name]}
|
217
|
+
Verb | #{r[:verb]}
|
218
|
+
URI | #{r[:path]}
|
219
|
+
Controller#Action | #{r[:reqs]}
|
220
|
+
MESSAGE
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def route_header(index:)
|
225
|
+
console_width = IO.console_size.second
|
226
|
+
header_prefix = "--[ Route #{index} ]"
|
227
|
+
dash_remainder = [console_width - header_prefix.size, 0].max
|
228
|
+
|
229
|
+
"#{header_prefix}#{'-' * dash_remainder}"
|
230
|
+
end
|
231
|
+
end
|
185
232
|
end
|
186
233
|
|
187
234
|
class HtmlTableFormatter
|
@@ -203,16 +250,16 @@ module ActionDispatch
|
|
203
250
|
end
|
204
251
|
|
205
252
|
def no_routes(*)
|
206
|
-
@buffer <<
|
253
|
+
@buffer << <<~MESSAGE
|
207
254
|
<p>You don't have any routes defined!</p>
|
208
255
|
<ul>
|
209
256
|
<li>Please add some routes in <tt>config/routes.rb</tt>.</li>
|
210
257
|
<li>
|
211
258
|
For more information about routes, please see the Rails guide
|
212
|
-
<a href="
|
259
|
+
<a href="https://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>.
|
213
260
|
</li>
|
214
261
|
</ul>
|
215
|
-
|
262
|
+
MESSAGE
|
216
263
|
end
|
217
264
|
|
218
265
|
def result
|
@@ -50,7 +50,19 @@ module ActionDispatch
|
|
50
50
|
|
51
51
|
private
|
52
52
|
def constraint_args(constraint, request)
|
53
|
-
|
53
|
+
arity = if constraint.respond_to?(:arity)
|
54
|
+
constraint.arity
|
55
|
+
else
|
56
|
+
constraint.method(:call).arity
|
57
|
+
end
|
58
|
+
|
59
|
+
if arity < 1
|
60
|
+
[]
|
61
|
+
elsif arity == 1
|
62
|
+
[request]
|
63
|
+
else
|
64
|
+
[request.path_parameters, request]
|
65
|
+
end
|
54
66
|
end
|
55
67
|
end
|
56
68
|
|
@@ -58,17 +70,17 @@ module ActionDispatch
|
|
58
70
|
ANCHOR_CHARACTERS_REGEX = %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
|
59
71
|
OPTIONAL_FORMAT_REGEX = %r{(?:\(\.:format\)+|\.:format|/)\Z}
|
60
72
|
|
61
|
-
attr_reader :requirements, :defaults
|
62
|
-
|
63
|
-
attr_reader :required_defaults, :ast
|
73
|
+
attr_reader :requirements, :defaults, :to, :default_controller,
|
74
|
+
:default_action, :required_defaults, :ast, :scope_options
|
64
75
|
|
65
76
|
def self.build(scope, set, ast, controller, default_action, to, via, formatted, options_constraints, anchor, options)
|
66
77
|
options = scope[:options].merge(options) if scope[:options]
|
67
78
|
|
68
79
|
defaults = (scope[:defaults] || {}).dup
|
69
80
|
scope_constraints = scope[:constraints] || {}
|
81
|
+
scope_options = scope[:options] || {}
|
70
82
|
|
71
|
-
new set, ast, defaults, controller, default_action, scope[:module], to, formatted, scope_constraints, scope[:blocks] || [], via, options_constraints, anchor, options
|
83
|
+
new set, ast, defaults, controller, default_action, scope[:module], to, formatted, scope_constraints, scope_options, scope[:blocks] || [], via, options_constraints, anchor, options
|
72
84
|
end
|
73
85
|
|
74
86
|
def self.check_via(via)
|
@@ -99,17 +111,18 @@ module ActionDispatch
|
|
99
111
|
format != false && path !~ OPTIONAL_FORMAT_REGEX
|
100
112
|
end
|
101
113
|
|
102
|
-
def initialize(set, ast, defaults, controller, default_action, modyoule, to, formatted, scope_constraints, blocks, via, options_constraints, anchor, options)
|
114
|
+
def initialize(set, ast, defaults, controller, default_action, modyoule, to, formatted, scope_constraints, scope_options, blocks, via, options_constraints, anchor, options)
|
103
115
|
@defaults = defaults
|
104
116
|
@set = set
|
105
117
|
|
106
|
-
@to = to
|
107
|
-
@default_controller = controller
|
108
|
-
@default_action = default_action
|
118
|
+
@to = intern(to)
|
119
|
+
@default_controller = intern(controller)
|
120
|
+
@default_action = intern(default_action)
|
109
121
|
@ast = ast
|
110
122
|
@anchor = anchor
|
111
123
|
@via = via
|
112
124
|
@internal = options.delete(:internal)
|
125
|
+
@scope_options = scope_options
|
113
126
|
|
114
127
|
path_params = ast.find_all(&:symbol?).map(&:to_sym)
|
115
128
|
|
@@ -148,17 +161,8 @@ module ActionDispatch
|
|
148
161
|
end
|
149
162
|
|
150
163
|
def make_route(name, precedence)
|
151
|
-
|
152
|
-
|
153
|
-
path,
|
154
|
-
conditions,
|
155
|
-
required_defaults,
|
156
|
-
defaults,
|
157
|
-
request_method,
|
158
|
-
precedence,
|
159
|
-
@internal)
|
160
|
-
|
161
|
-
route
|
164
|
+
Journey::Route.new(name, application, path, conditions, required_defaults,
|
165
|
+
defaults, request_method, precedence, scope_options, @internal)
|
162
166
|
end
|
163
167
|
|
164
168
|
def application
|
@@ -219,6 +223,10 @@ module ActionDispatch
|
|
219
223
|
private :build_path
|
220
224
|
|
221
225
|
private
|
226
|
+
def intern(object)
|
227
|
+
object.is_a?(String) ? -object : object
|
228
|
+
end
|
229
|
+
|
222
230
|
def add_wildcard_options(options, formatted, path_ast)
|
223
231
|
# Add a constraint for wildcard route to make it non-greedy and match the
|
224
232
|
# optional format part of the route by default.
|
@@ -279,7 +287,7 @@ module ActionDispatch
|
|
279
287
|
|
280
288
|
def verify_regexp_requirements(requirements)
|
281
289
|
requirements.each do |requirement|
|
282
|
-
if requirement.source
|
290
|
+
if ANCHOR_CHARACTERS_REGEX.match?(requirement.source)
|
283
291
|
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
|
284
292
|
end
|
285
293
|
|
@@ -308,8 +316,8 @@ module ActionDispatch
|
|
308
316
|
def check_controller_and_action(path_params, controller, action)
|
309
317
|
hash = check_part(:controller, controller, path_params, {}) do |part|
|
310
318
|
translate_controller(part) {
|
311
|
-
message = "'#{part}' is not a supported controller name. This can lead to potential routing problems."
|
312
|
-
message << " See
|
319
|
+
message = +"'#{part}' is not a supported controller name. This can lead to potential routing problems."
|
320
|
+
message << " See https://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use"
|
313
321
|
|
314
322
|
raise ArgumentError, message
|
315
323
|
}
|
@@ -333,7 +341,7 @@ module ActionDispatch
|
|
333
341
|
end
|
334
342
|
|
335
343
|
def split_to(to)
|
336
|
-
if to
|
344
|
+
if /#/.match?(to)
|
337
345
|
to.split("#")
|
338
346
|
else
|
339
347
|
[]
|
@@ -342,7 +350,7 @@ module ActionDispatch
|
|
342
350
|
|
343
351
|
def add_controller_module(controller, modyoule)
|
344
352
|
if modyoule && !controller.is_a?(Regexp)
|
345
|
-
if
|
353
|
+
if %r{\A/}.match?(controller)
|
346
354
|
controller[1..-1]
|
347
355
|
else
|
348
356
|
[modyoule, controller].compact.join("/")
|
@@ -354,7 +362,7 @@ module ActionDispatch
|
|
354
362
|
|
355
363
|
def translate_controller(controller)
|
356
364
|
return controller if Regexp === controller
|
357
|
-
return controller.to_s if
|
365
|
+
return controller.to_s if /\A[a-z_0-9][a-z_0-9\/]*\z/.match?(controller)
|
358
366
|
|
359
367
|
yield
|
360
368
|
end
|
@@ -390,7 +398,7 @@ module ActionDispatch
|
|
390
398
|
# for root cases, where the latter is the correct one.
|
391
399
|
def self.normalize_path(path)
|
392
400
|
path = Journey::Router::Utils.normalize_path(path)
|
393
|
-
path.gsub!(%r{/(\(+)/?}, '\1/') unless
|
401
|
+
path.gsub!(%r{/(\(+)/?}, '\1/') unless %r{^/(\(+[^)]+\)){1,}$}.match?(path)
|
394
402
|
path
|
395
403
|
end
|
396
404
|
|
@@ -553,10 +561,10 @@ module ActionDispatch
|
|
553
561
|
#
|
554
562
|
# match 'json_only', constraints: { format: 'json' }, via: :get
|
555
563
|
#
|
556
|
-
# class
|
564
|
+
# class PermitList
|
557
565
|
# def matches?(request) request.remote_ip == '1.2.3.4' end
|
558
566
|
# end
|
559
|
-
# match 'path', to: 'c#a', constraints:
|
567
|
+
# match 'path', to: 'c#a', constraints: PermitList.new, via: :get
|
560
568
|
#
|
561
569
|
# See <tt>Scoping#constraints</tt> for more examples with its scope
|
562
570
|
# equivalent.
|
@@ -611,7 +619,7 @@ module ActionDispatch
|
|
611
619
|
end
|
612
620
|
|
613
621
|
raise ArgumentError, "A rack application must be specified" unless app.respond_to?(:call)
|
614
|
-
raise ArgumentError,
|
622
|
+
raise ArgumentError, <<~MSG unless path
|
615
623
|
Must be called with mount point
|
616
624
|
|
617
625
|
mount SomeRackApp, at: "some_route"
|
@@ -644,7 +652,7 @@ module ActionDispatch
|
|
644
652
|
|
645
653
|
# Query if the following named route was already defined.
|
646
654
|
def has_named_route?(name)
|
647
|
-
@set.named_routes.key?
|
655
|
+
@set.named_routes.key?(name)
|
648
656
|
end
|
649
657
|
|
650
658
|
private
|
@@ -668,7 +676,7 @@ module ActionDispatch
|
|
668
676
|
|
669
677
|
script_namer = ->(options) do
|
670
678
|
prefix_options = options.slice(*_route.segment_keys)
|
671
|
-
prefix_options[:relative_url_root] = ""
|
679
|
+
prefix_options[:relative_url_root] = ""
|
672
680
|
|
673
681
|
if options[:_recall]
|
674
682
|
prefix_options.reverse_merge!(options[:_recall].slice(*_route.segment_keys))
|
@@ -1138,6 +1146,10 @@ module ActionDispatch
|
|
1138
1146
|
attr_reader :controller, :path, :param
|
1139
1147
|
|
1140
1148
|
def initialize(entities, api_only, shallow, options = {})
|
1149
|
+
if options[:param].to_s.include?(":")
|
1150
|
+
raise ArgumentError, ":param option can't contain colons"
|
1151
|
+
end
|
1152
|
+
|
1141
1153
|
@name = entities.to_s
|
1142
1154
|
@path = (options[:path] || @name).to_s
|
1143
1155
|
@controller = (options[:controller] || @name).to_s
|
@@ -1159,10 +1171,16 @@ module ActionDispatch
|
|
1159
1171
|
end
|
1160
1172
|
|
1161
1173
|
def actions
|
1174
|
+
if @except
|
1175
|
+
available_actions - Array(@except).map(&:to_sym)
|
1176
|
+
else
|
1177
|
+
available_actions
|
1178
|
+
end
|
1179
|
+
end
|
1180
|
+
|
1181
|
+
def available_actions
|
1162
1182
|
if @only
|
1163
1183
|
Array(@only).map(&:to_sym)
|
1164
|
-
elsif @except
|
1165
|
-
default_actions - Array(@except).map(&:to_sym)
|
1166
1184
|
else
|
1167
1185
|
default_actions
|
1168
1186
|
end
|
@@ -1389,6 +1407,8 @@ module ActionDispatch
|
|
1389
1407
|
# as a comment on a blog post like <tt>/posts/a-long-permalink/comments/1234</tt>
|
1390
1408
|
# to be shortened to just <tt>/comments/1234</tt>.
|
1391
1409
|
#
|
1410
|
+
# Set <tt>shallow: false</tt> on a child resource to ignore a parent's shallow parameter.
|
1411
|
+
#
|
1392
1412
|
# [:shallow_path]
|
1393
1413
|
# Prefixes nested shallow routes with the specified path.
|
1394
1414
|
#
|
@@ -1431,6 +1451,9 @@ module ActionDispatch
|
|
1431
1451
|
# Allows you to specify the default value for optional +format+
|
1432
1452
|
# segment or disable it by supplying +false+.
|
1433
1453
|
#
|
1454
|
+
# [:param]
|
1455
|
+
# Allows you to override the default param name of +:id+ in the URL.
|
1456
|
+
#
|
1434
1457
|
# === Examples
|
1435
1458
|
#
|
1436
1459
|
# # routes call <tt>Admin::PostsController</tt>
|
@@ -1588,7 +1611,7 @@ module ActionDispatch
|
|
1588
1611
|
when Symbol
|
1589
1612
|
options[:action] = to
|
1590
1613
|
when String
|
1591
|
-
if to
|
1614
|
+
if /#/.match?(to)
|
1592
1615
|
options[:to] = to
|
1593
1616
|
else
|
1594
1617
|
options[:controller] = to
|
@@ -1645,7 +1668,6 @@ module ActionDispatch
|
|
1645
1668
|
end
|
1646
1669
|
|
1647
1670
|
private
|
1648
|
-
|
1649
1671
|
def parent_resource
|
1650
1672
|
@scope[:scope_level_resource]
|
1651
1673
|
end
|
@@ -1656,7 +1678,8 @@ module ActionDispatch
|
|
1656
1678
|
return true
|
1657
1679
|
end
|
1658
1680
|
|
1659
|
-
if options
|
1681
|
+
if options[:shallow]
|
1682
|
+
options.delete(:shallow)
|
1660
1683
|
shallow do
|
1661
1684
|
send(method, resources.pop, options, &block)
|
1662
1685
|
end
|
@@ -1914,7 +1937,7 @@ module ActionDispatch
|
|
1914
1937
|
|
1915
1938
|
default_action = options.delete(:action) || @scope[:action]
|
1916
1939
|
|
1917
|
-
if
|
1940
|
+
if /^[\w\-\/]+$/.match?(action)
|
1918
1941
|
default_action ||= action.tr("-", "_") unless action.include?("/")
|
1919
1942
|
else
|
1920
1943
|
action = nil
|
@@ -1934,9 +1957,7 @@ module ActionDispatch
|
|
1934
1957
|
end
|
1935
1958
|
|
1936
1959
|
def match_root_route(options)
|
1937
|
-
|
1938
|
-
args = ["/", { as: name, via: :get }.merge!(options)]
|
1939
|
-
|
1960
|
+
args = ["/", { as: :root, via: :get }.merge(options)]
|
1940
1961
|
match(*args)
|
1941
1962
|
end
|
1942
1963
|
end
|
@@ -2052,7 +2073,7 @@ module ActionDispatch
|
|
2052
2073
|
# of routing helpers, e.g:
|
2053
2074
|
#
|
2054
2075
|
# direct :homepage do
|
2055
|
-
# "
|
2076
|
+
# "https://rubyonrails.org"
|
2056
2077
|
# end
|
2057
2078
|
#
|
2058
2079
|
# direct :commentable do |model|
|