actionpack 7.0.4 → 7.1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +495 -257
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/lib/abstract_controller/base.rb +20 -11
- data/lib/abstract_controller/caching/fragments.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +31 -6
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/helpers.rb +75 -28
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -16
- data/lib/abstract_controller/rendering.rb +12 -14
- data/lib/abstract_controller/translation.rb +11 -6
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +6 -4
- data/lib/action_controller/base.rb +3 -17
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +16 -4
- data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +121 -123
- data/lib/action_controller/metal/content_security_policy.rb +5 -5
- data/lib/action_controller/metal/data_streaming.rb +20 -18
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +8 -0
- data/lib/action_controller/metal/head.rb +9 -7
- data/lib/action_controller/metal/helpers.rb +3 -14
- data/lib/action_controller/metal/http_authentication.rb +15 -9
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +8 -1
- data/lib/action_controller/metal/live.rb +25 -1
- data/lib/action_controller/metal/mime_responds.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +4 -2
- data/lib/action_controller/metal/permissions_policy.rb +2 -2
- data/lib/action_controller/metal/redirecting.rb +29 -8
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +114 -9
- data/lib/action_controller/metal/request_forgery_protection.rb +144 -53
- data/lib/action_controller/metal/rescue.rb +6 -3
- data/lib/action_controller/metal/streaming.rb +71 -31
- data/lib/action_controller/metal/strong_parameters.rb +200 -103
- data/lib/action_controller/metal/url_for.rb +9 -4
- data/lib/action_controller/metal.rb +79 -21
- data/lib/action_controller/railtie.rb +24 -10
- data/lib/action_controller/renderer.rb +99 -85
- data/lib/action_controller/test_case.rb +18 -8
- data/lib/action_controller.rb +13 -3
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +9 -11
- data/lib/action_dispatch/http/content_security_policy.rb +35 -13
- data/lib/action_dispatch/http/filter_parameters.rb +23 -32
- data/lib/action_dispatch/http/headers.rb +3 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -22
- data/lib/action_dispatch/http/mime_type.rb +37 -11
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +38 -23
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +85 -32
- data/lib/action_dispatch/http/response.rb +80 -63
- data/lib/action_dispatch/http/upload.rb +15 -2
- data/lib/action_dispatch/journey/formatter.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +14 -14
- data/lib/action_dispatch/journey/route.rb +3 -2
- data/lib/action_dispatch/journey/router.rb +9 -8
- data/lib/action_dispatch/journey/routes.rb +2 -2
- data/lib/action_dispatch/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +108 -117
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -25
- data/lib/action_dispatch/middleware/debug_locks.rb +4 -1
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +186 -27
- data/lib/action_dispatch/middleware/executor.rb +7 -1
- data/lib/action_dispatch/middleware/flash.rb +7 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +18 -8
- data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
- data/lib/action_dispatch/middleware/reloader.rb +7 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +21 -20
- data/lib/action_dispatch/middleware/request_id.rb +4 -2
- data/lib/action_dispatch/middleware/server_timing.rb +4 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +5 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -5
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +39 -22
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +7 -2
- data/lib/action_dispatch/middleware/static.rb +14 -10
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -41
- data/lib/action_dispatch/railtie.rb +13 -4
- data/lib/action_dispatch/request/session.rb +16 -6
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +54 -6
- data/lib/action_dispatch/routing/mapper.rb +97 -26
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +15 -6
- data/lib/action_dispatch/routing/route_set.rb +53 -23
- data/lib/action_dispatch/routing/routes_proxy.rb +10 -15
- data/lib/action_dispatch/routing/url_for.rb +26 -22
- data/lib/action_dispatch/routing.rb +7 -7
- data/lib/action_dispatch/system_test_case.rb +3 -3
- data/lib/action_dispatch/system_testing/browser.rb +25 -19
- data/lib/action_dispatch/system_testing/driver.rb +15 -23
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +27 -16
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +14 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +67 -28
- data/lib/action_dispatch/testing/assertions.rb +3 -1
- data/lib/action_dispatch/testing/integration.rb +27 -17
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +4 -3
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -9
- data/lib/action_dispatch.rb +41 -4
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +68 -32
@@ -1,9 +1,9 @@
|
|
1
|
-
<%= @
|
1
|
+
<%= @exception_wrapper.exception_class_name %><%
|
2
2
|
if params_valid? && @request.parameters['controller']
|
3
3
|
%> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
|
4
4
|
<% end %>
|
5
5
|
|
6
|
-
<%= @
|
6
|
+
<%= @exception_wrapper.message %>
|
7
7
|
<%= render template: "rescues/_source" %>
|
8
8
|
<%= render template: "rescues/_trace" %>
|
9
9
|
<%= render template: "rescues/_request_and_response" %>
|
@@ -3,6 +3,7 @@
|
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8" />
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
|
+
<meta name="turbo-visit-control" content="reload">
|
6
7
|
<title>Action Controller: Exception caught</title>
|
7
8
|
<style>
|
8
9
|
body {
|
@@ -148,6 +149,18 @@
|
|
148
149
|
background-color: #FCC;
|
149
150
|
}
|
150
151
|
|
152
|
+
.error_highlight {
|
153
|
+
display: inline-block;
|
154
|
+
background-color: #FF9;
|
155
|
+
text-decoration: #F00 wavy underline;
|
156
|
+
}
|
157
|
+
|
158
|
+
.error_highlight_tip {
|
159
|
+
color: #666;
|
160
|
+
padding: 2px 2px;
|
161
|
+
font-size: 10px;
|
162
|
+
}
|
163
|
+
|
151
164
|
.button_to {
|
152
165
|
display: inline-block;
|
153
166
|
margin-top: 0.75em;
|
@@ -225,6 +238,10 @@
|
|
225
238
|
background-color: #900;
|
226
239
|
}
|
227
240
|
|
241
|
+
.error_highlight {
|
242
|
+
color: #333;
|
243
|
+
}
|
244
|
+
|
228
245
|
input[type="submit"] {
|
229
246
|
box-shadow: 0 3px #800;
|
230
247
|
}
|
@@ -1,19 +1,23 @@
|
|
1
1
|
<header role="banner">
|
2
|
-
<h1>No template for interactive request</h1>
|
2
|
+
<h1>No view template for interactive request</h1>
|
3
3
|
</header>
|
4
4
|
|
5
5
|
<main id="container">
|
6
6
|
<h2><%= h @exception.message %></h2>
|
7
7
|
|
8
|
-
<
|
9
|
-
<
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
<div class="summary">
|
9
|
+
<p>
|
10
|
+
<strong>NOTE:</strong> Rails usually expects a controller action to render a view template with the same name.
|
11
|
+
</p>
|
12
|
+
<p>
|
13
|
+
For example, a <code><%= @exception.controller %>#<%= @exception.action_name %></code> action defined in <code>app/controllers/<%= @exception.controller.controller_path %>_controller.rb</code> should have a corresponding view template
|
14
|
+
in a file named <code>app/views/<%= @exception.controller.controller_path %>/<%= @exception.action_name %>.html.erb</code>.
|
15
|
+
</p>
|
16
|
+
<p>
|
17
|
+
However, if this controller is an API endpoint responding with 204 (No Content), which does not require a view template because it doesn't serve an HTML response, then this error will occur when trying to access it with a browser. In this particular scenario, you can ignore this error.
|
18
|
+
</p>
|
19
|
+
<p>
|
20
|
+
You can find more about view template rendering conventions in the <a href="https://guides.rubyonrails.org/layouts_and_rendering.html#rendering-by-default-convention-over-configuration-in-action">Rails Guides on Layouts and Rendering in Rails</a>.
|
21
|
+
</p>
|
22
|
+
</div>
|
19
23
|
</main>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
</header>
|
4
4
|
|
5
5
|
<main role="main" id="container">
|
6
|
-
<h2><%= h @
|
6
|
+
<h2><%= h @exception_wrapper.message %></h2>
|
7
7
|
|
8
8
|
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
9
9
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
@@ -2,12 +2,12 @@
|
|
2
2
|
<h1>Routing Error</h1>
|
3
3
|
</header>
|
4
4
|
<main role="main" id="container">
|
5
|
-
<h2><%= h @
|
6
|
-
<% unless @
|
5
|
+
<h2><%= h @exception_wrapper.message %></h2>
|
6
|
+
<% unless @exception_wrapper.failures.empty? %>
|
7
7
|
<p>
|
8
8
|
<h2>Failure reasons:</h2>
|
9
9
|
<ol>
|
10
|
-
<% @
|
10
|
+
<% @exception_wrapper.failures.each do |route, reason| %>
|
11
11
|
<li><code><%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %></li>
|
12
12
|
<% end %>
|
13
13
|
</ol>
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<header role="banner">
|
2
2
|
<h1>
|
3
|
-
<%= @
|
3
|
+
<%= @exception_wrapper.exception_name %> in
|
4
4
|
<%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
|
5
5
|
</h1>
|
6
6
|
</header>
|
7
7
|
|
8
8
|
<main role="main" id="container">
|
9
9
|
<p>
|
10
|
-
Showing <i><%= @
|
10
|
+
Showing <i><%= @exception_wrapper.file_name %></i> where line <b>#<%= @exception_wrapper.line_number %></b> raised:
|
11
11
|
</p>
|
12
|
-
<pre><code><%= h @
|
12
|
+
<pre><code><%= h @exception_wrapper.message %></code></pre>
|
13
13
|
|
14
14
|
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
|
15
15
|
|
16
|
-
<p><%= @
|
16
|
+
<p><%= @exception_wrapper.sub_template_message %></p>
|
17
17
|
|
18
18
|
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show %>
|
19
19
|
<%= render template: "rescues/_request_and_response" %>
|
@@ -1,24 +1,45 @@
|
|
1
1
|
<% content_for :style do %>
|
2
|
+
h2, p {
|
3
|
+
padding-left: 30px;
|
4
|
+
}
|
5
|
+
|
2
6
|
#route_table {
|
3
7
|
margin: 0;
|
4
8
|
border-collapse: collapse;
|
9
|
+
word-wrap:break-word;
|
10
|
+
table-layout: fixed;
|
11
|
+
width:100%;
|
5
12
|
}
|
6
13
|
|
7
14
|
#route_table thead tr {
|
8
15
|
border-bottom: 2px solid #ddd;
|
9
16
|
}
|
10
17
|
|
18
|
+
#route_table th {
|
19
|
+
padding-left: 30px;
|
20
|
+
text-align: left;
|
21
|
+
}
|
22
|
+
|
11
23
|
#route_table thead tr.bottom {
|
12
24
|
border-bottom: none;
|
13
25
|
}
|
14
26
|
|
15
27
|
#route_table thead tr.bottom th {
|
16
|
-
padding: 10px
|
28
|
+
padding: 10px 30px;
|
17
29
|
line-height: 15px;
|
18
30
|
}
|
19
31
|
|
20
|
-
#route_table
|
32
|
+
#route_table #search_container {
|
33
|
+
padding: 7px 30px;
|
34
|
+
}
|
35
|
+
|
36
|
+
#route_table thead tr th input#search {
|
21
37
|
-webkit-appearance: textfield;
|
38
|
+
width:100%;
|
39
|
+
}
|
40
|
+
|
41
|
+
#route_table thead th.http-verb {
|
42
|
+
width: 10%;
|
22
43
|
}
|
23
44
|
|
24
45
|
#route_table tbody tr {
|
@@ -45,11 +66,6 @@
|
|
45
66
|
padding: 4px 30px;
|
46
67
|
}
|
47
68
|
|
48
|
-
#path_search {
|
49
|
-
width: 80%;
|
50
|
-
font-size: inherit;
|
51
|
-
}
|
52
|
-
|
53
69
|
@media (prefers-color-scheme: dark) {
|
54
70
|
#route_table tbody tr:nth-child(odd) {
|
55
71
|
background: #282828;
|
@@ -62,28 +78,22 @@
|
|
62
78
|
}
|
63
79
|
<% end %>
|
64
80
|
|
65
|
-
<table id='route_table'
|
81
|
+
<table id='route_table'>
|
66
82
|
<thead>
|
67
83
|
<tr>
|
68
|
-
<th>Helper
|
69
|
-
|
70
|
-
<th>Path</th>
|
71
|
-
<th>Controller#Action</th>
|
72
|
-
</tr>
|
73
|
-
<tr class='bottom'>
|
74
|
-
<th><%# Helper %>
|
75
|
-
<%= link_to "Path", "#", 'data-route-helper' => '_path',
|
84
|
+
<th>Helper
|
85
|
+
(<%= link_to "Path", "#", 'data-route-helper' => '_path',
|
76
86
|
title: "Returns a relative path (without the http or domain)" %> /
|
77
87
|
<%= link_to "Url", "#", 'data-route-helper' => '_url',
|
78
|
-
title: "Returns an absolute URL (with the http and domain)" %>
|
79
|
-
</th>
|
80
|
-
<th><%# HTTP Verb %>
|
81
|
-
</th>
|
82
|
-
<th><%# Path %>
|
83
|
-
<%= search_field(:path, nil, id: 'search', placeholder: "Path Match") %>
|
84
|
-
</th>
|
85
|
-
<th><%# Controller#action %>
|
88
|
+
title: "Returns an absolute URL (with the http and domain)" %>)
|
86
89
|
</th>
|
90
|
+
<th class="http-verb">HTTP Verb</th>
|
91
|
+
<th>Path</th>
|
92
|
+
<th>Controller#Action</th>
|
93
|
+
<th>Source Location</th>
|
94
|
+
</tr>
|
95
|
+
<tr>
|
96
|
+
<th colspan="5" id="search_container"><%= search_field(:query, nil, id: 'search', placeholder: "Search") %></th>
|
87
97
|
</tr>
|
88
98
|
</thead>
|
89
99
|
<tbody class='exact_matches' id='exact_matches'>
|
@@ -99,12 +109,12 @@
|
|
99
109
|
// support forEach iterator on NodeList
|
100
110
|
NodeList.prototype.forEach = Array.prototype.forEach;
|
101
111
|
|
102
|
-
// Enables
|
103
|
-
function
|
112
|
+
// Enables query search functionality
|
113
|
+
function setupMatchingRoutes() {
|
104
114
|
// Check if there are any matched results in a section
|
105
|
-
function checkNoMatch(section,
|
115
|
+
function checkNoMatch(section, trElement) {
|
106
116
|
if (section.children.length <= 1) {
|
107
|
-
section.
|
117
|
+
section.appendChild(trElement);
|
108
118
|
}
|
109
119
|
}
|
110
120
|
|
@@ -128,8 +138,8 @@
|
|
128
138
|
}
|
129
139
|
|
130
140
|
// remove params or fragments
|
131
|
-
function
|
132
|
-
return
|
141
|
+
function sanitizeQuery(query) {
|
142
|
+
return query.replace(/[#?].*/, '');
|
133
143
|
}
|
134
144
|
|
135
145
|
var pathElements = document.querySelectorAll('#route_table [data-route-path]'),
|
@@ -145,26 +155,34 @@
|
|
145
155
|
}
|
146
156
|
}
|
147
157
|
|
158
|
+
function buildTr(string) {
|
159
|
+
var tr = document.createElement('tr');
|
160
|
+
var th = document.createElement('th');
|
161
|
+
th.setAttribute('colspan', 4);
|
162
|
+
tr.appendChild(th);
|
163
|
+
th.innerText = string;
|
164
|
+
return tr;
|
165
|
+
}
|
166
|
+
|
148
167
|
// On key press perform a search for matching paths
|
149
168
|
delayedKeyup(searchElem, function() {
|
150
|
-
var
|
151
|
-
defaultExactMatch =
|
152
|
-
defaultFuzzyMatch =
|
153
|
-
noExactMatch = '
|
154
|
-
noFuzzyMatch = '
|
169
|
+
var query = sanitizeQuery(searchElem.value),
|
170
|
+
defaultExactMatch = buildTr("Routes matching '" + query + "':"),
|
171
|
+
defaultFuzzyMatch = buildTr("Routes containing '" + query + "':"),
|
172
|
+
noExactMatch = buildTr('No exact matches found'),
|
173
|
+
noFuzzyMatch = buildTr('No fuzzy matches found');
|
155
174
|
|
156
|
-
if (!
|
175
|
+
if (!query)
|
157
176
|
return searchElem.onblur();
|
158
177
|
|
159
|
-
getJSON('/rails/info/routes?
|
178
|
+
getJSON('/rails/info/routes?query=' + query, function(matches){
|
160
179
|
// Clear out results section
|
161
|
-
exactSection.
|
162
|
-
fuzzySection.
|
180
|
+
exactSection.replaceChildren(defaultExactMatch);
|
181
|
+
fuzzySection.replaceChildren(defaultFuzzyMatch);
|
163
182
|
|
164
183
|
// Display exact matches and fuzzy matches
|
165
184
|
pathElements.forEach(function(elem) {
|
166
185
|
var elemPath = elem.getAttribute('data-route-path');
|
167
|
-
|
168
186
|
if (matches['exact'].indexOf(elemPath) != -1)
|
169
187
|
exactSection.appendChild(elem.parentNode.cloneNode(true));
|
170
188
|
|
@@ -206,7 +224,7 @@
|
|
206
224
|
});
|
207
225
|
}
|
208
226
|
|
209
|
-
|
227
|
+
setupMatchingRoutes();
|
210
228
|
setupRouteToggleHelperLinks();
|
211
229
|
|
212
230
|
// Focus the search input after page has loaded
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "action_dispatch"
|
4
|
+
require "action_dispatch/log_subscriber"
|
4
5
|
require "active_support/messages/rotation_configuration"
|
5
6
|
|
6
7
|
module ActionDispatch
|
@@ -8,7 +9,7 @@ module ActionDispatch
|
|
8
9
|
config.action_dispatch = ActiveSupport::OrderedOptions.new
|
9
10
|
config.action_dispatch.x_sendfile_header = nil
|
10
11
|
config.action_dispatch.ip_spoofing_check = true
|
11
|
-
config.action_dispatch.show_exceptions =
|
12
|
+
config.action_dispatch.show_exceptions = :all
|
12
13
|
config.action_dispatch.tld_length = 1
|
13
14
|
config.action_dispatch.ignore_accept_header = false
|
14
15
|
config.action_dispatch.rescue_templates = {}
|
@@ -23,9 +24,9 @@ module ActionDispatch
|
|
23
24
|
config.action_dispatch.use_authenticated_cookie_encryption = false
|
24
25
|
config.action_dispatch.use_cookies_with_metadata = false
|
25
26
|
config.action_dispatch.perform_deep_munge = true
|
26
|
-
config.action_dispatch.request_id_header =
|
27
|
-
config.action_dispatch.return_only_request_media_type_on_content_type = true
|
27
|
+
config.action_dispatch.request_id_header = ActionDispatch::Constants::X_REQUEST_ID
|
28
28
|
config.action_dispatch.log_rescued_responses = true
|
29
|
+
config.action_dispatch.debug_exception_log_level = :fatal
|
29
30
|
|
30
31
|
config.action_dispatch.default_headers = {
|
31
32
|
"X-Frame-Options" => "SAMEORIGIN",
|
@@ -40,13 +41,19 @@ module ActionDispatch
|
|
40
41
|
|
41
42
|
config.eager_load_namespaces << ActionDispatch
|
42
43
|
|
44
|
+
initializer "action_dispatch.deprecator", before: :load_environment_config do |app|
|
45
|
+
app.deprecators[:action_dispatch] = ActionDispatch.deprecator
|
46
|
+
end
|
47
|
+
|
43
48
|
initializer "action_dispatch.configure" do |app|
|
44
49
|
ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
|
45
50
|
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
|
46
51
|
|
47
52
|
ActiveSupport.on_load(:action_dispatch_request) do
|
48
53
|
self.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
|
49
|
-
|
54
|
+
unless app.config.action_dispatch.respond_to?(:return_only_request_media_type_on_content_type)
|
55
|
+
self.return_only_media_type_on_content_type = app.config.action_dispatch.return_only_request_media_type_on_content_type
|
56
|
+
end
|
50
57
|
ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
|
51
58
|
end
|
52
59
|
|
@@ -61,6 +68,8 @@ module ActionDispatch
|
|
61
68
|
config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
|
62
69
|
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
|
63
70
|
|
71
|
+
ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
|
72
|
+
|
64
73
|
ActionDispatch.test_app = app
|
65
74
|
end
|
66
75
|
end
|
@@ -78,6 +78,8 @@ module ActionDispatch
|
|
78
78
|
@loaded = false
|
79
79
|
@exists = nil # We haven't checked yet.
|
80
80
|
@enabled = enabled
|
81
|
+
@id_was = nil
|
82
|
+
@id_was_initialized = false
|
81
83
|
end
|
82
84
|
|
83
85
|
def id
|
@@ -176,9 +178,14 @@ module ActionDispatch
|
|
176
178
|
# session.to_hash
|
177
179
|
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
|
178
180
|
def update(hash)
|
181
|
+
unless hash.respond_to?(:to_hash)
|
182
|
+
raise TypeError, "no implicit conversion of #{hash.class.name} into Hash"
|
183
|
+
end
|
184
|
+
|
179
185
|
load_for_write!
|
180
|
-
@delegate.update hash.stringify_keys
|
186
|
+
@delegate.update hash.to_hash.stringify_keys
|
181
187
|
end
|
188
|
+
alias :merge! :update
|
182
189
|
|
183
190
|
# Deletes given key from the session.
|
184
191
|
def delete(key)
|
@@ -232,15 +239,15 @@ module ActionDispatch
|
|
232
239
|
@delegate.empty?
|
233
240
|
end
|
234
241
|
|
235
|
-
def merge!(other)
|
236
|
-
load_for_write!
|
237
|
-
@delegate.merge!(other)
|
238
|
-
end
|
239
|
-
|
240
242
|
def each(&block)
|
241
243
|
to_hash.each(&block)
|
242
244
|
end
|
243
245
|
|
246
|
+
def id_was
|
247
|
+
load_for_read!
|
248
|
+
@id_was
|
249
|
+
end
|
250
|
+
|
244
251
|
private
|
245
252
|
def load_for_read!
|
246
253
|
load! if !loaded? && exists?
|
@@ -260,10 +267,13 @@ module ActionDispatch
|
|
260
267
|
|
261
268
|
def load!
|
262
269
|
if enabled?
|
270
|
+
@id_was_initialized = true unless exists?
|
263
271
|
id, session = @by.load_session @req
|
264
272
|
options[:id] = id
|
265
273
|
@delegate.replace(session.stringify_keys)
|
274
|
+
@id_was = id unless @id_was_initialized
|
266
275
|
end
|
276
|
+
@id_was_initialized = true
|
267
277
|
@loaded = true
|
268
278
|
end
|
269
279
|
end
|
@@ -55,9 +55,11 @@ module ActionDispatch
|
|
55
55
|
if params.has_key?(:tempfile)
|
56
56
|
ActionDispatch::Http::UploadedFile.new(params)
|
57
57
|
else
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
hwia = ActiveSupport::HashWithIndifferentAccess.new
|
59
|
+
params.each_pair do |key, val|
|
60
|
+
hwia[key] = normalize_encode_params(val)
|
61
|
+
end
|
62
|
+
hwia
|
61
63
|
end
|
62
64
|
else
|
63
65
|
params
|
@@ -83,6 +85,9 @@ module ActionDispatch
|
|
83
85
|
return params unless controller && controller.valid_encoding? && encoding_template = action_encoding_template(request, controller, action)
|
84
86
|
params.except(:controller, :action).each do |key, value|
|
85
87
|
ActionDispatch::Request::Utils.each_param_value(value) do |param|
|
88
|
+
# If `param` is frozen, it comes from the router defaults
|
89
|
+
next if param.frozen?
|
90
|
+
|
86
91
|
if encoding_template[key.to_s]
|
87
92
|
param.force_encoding(encoding_template[key.to_s])
|
88
93
|
end
|
@@ -6,8 +6,21 @@ require "io/console/size"
|
|
6
6
|
module ActionDispatch
|
7
7
|
module Routing
|
8
8
|
class RouteWrapper < SimpleDelegator # :nodoc:
|
9
|
+
def matches_filter?(filter, value)
|
10
|
+
return __getobj__.path.match(value) if filter == :exact_path_match
|
11
|
+
|
12
|
+
value.match?(public_send(filter))
|
13
|
+
end
|
14
|
+
|
9
15
|
def endpoint
|
10
|
-
|
16
|
+
case
|
17
|
+
when app.dispatcher?
|
18
|
+
"#{controller}##{action}"
|
19
|
+
when rack_app.is_a?(Proc)
|
20
|
+
"Inline handler (Proc/Lambda)"
|
21
|
+
else
|
22
|
+
rack_app.inspect
|
23
|
+
end
|
11
24
|
end
|
12
25
|
|
13
26
|
def constraints
|
@@ -85,8 +98,18 @@ module ActionDispatch
|
|
85
98
|
if filter[:controller]
|
86
99
|
{ controller: /#{filter[:controller].underscore.sub(/_?controller\z/, "")}/ }
|
87
100
|
elsif filter[:grep]
|
88
|
-
|
89
|
-
|
101
|
+
grep_pattern = Regexp.new(filter[:grep])
|
102
|
+
path = RFC2396_PARSER.escape(filter[:grep])
|
103
|
+
normalized_path = ("/" + path).squeeze("/")
|
104
|
+
|
105
|
+
{
|
106
|
+
controller: grep_pattern,
|
107
|
+
action: grep_pattern,
|
108
|
+
verb: grep_pattern,
|
109
|
+
name: grep_pattern,
|
110
|
+
path: grep_pattern,
|
111
|
+
exact_path_match: normalized_path,
|
112
|
+
}
|
90
113
|
end
|
91
114
|
end
|
92
115
|
|
@@ -94,7 +117,7 @@ module ActionDispatch
|
|
94
117
|
if filter
|
95
118
|
@routes.select do |route|
|
96
119
|
route_wrapper = RouteWrapper.new(route)
|
97
|
-
filter.any? { |
|
120
|
+
filter.any? { |filter_type, value| route_wrapper.matches_filter?(filter_type, value) }
|
98
121
|
end
|
99
122
|
else
|
100
123
|
@routes
|
@@ -110,7 +133,8 @@ module ActionDispatch
|
|
110
133
|
{ name: route.name,
|
111
134
|
verb: route.verb,
|
112
135
|
path: route.path,
|
113
|
-
reqs: route.reqs
|
136
|
+
reqs: route.reqs,
|
137
|
+
source_location: route.source_location }
|
114
138
|
end
|
115
139
|
end
|
116
140
|
|
@@ -216,13 +240,16 @@ module ActionDispatch
|
|
216
240
|
private
|
217
241
|
def draw_expanded_section(routes)
|
218
242
|
routes.map.each_with_index do |r, i|
|
219
|
-
<<~MESSAGE.chomp
|
243
|
+
route_rows = <<~MESSAGE.chomp
|
220
244
|
#{route_header(index: i + 1)}
|
221
245
|
Prefix | #{r[:name]}
|
222
246
|
Verb | #{r[:verb]}
|
223
247
|
URI | #{r[:path]}
|
224
248
|
Controller#Action | #{r[:reqs]}
|
225
249
|
MESSAGE
|
250
|
+
source_location = "\nSource Location | #{r[:source_location]}"
|
251
|
+
route_rows += source_location if r[:source_location].present?
|
252
|
+
route_rows
|
226
253
|
end
|
227
254
|
end
|
228
255
|
|
@@ -230,6 +257,27 @@ module ActionDispatch
|
|
230
257
|
"--[ Route #{index} ]".ljust(@width, "-")
|
231
258
|
end
|
232
259
|
end
|
260
|
+
|
261
|
+
class Unused < Sheet
|
262
|
+
def header(routes)
|
263
|
+
@buffer << <<~MSG
|
264
|
+
Found #{routes.count} unused #{"route".pluralize(routes.count)}:
|
265
|
+
MSG
|
266
|
+
|
267
|
+
super
|
268
|
+
end
|
269
|
+
|
270
|
+
def no_routes(routes, filter)
|
271
|
+
@buffer <<
|
272
|
+
if filter.none?
|
273
|
+
"No unused routes found."
|
274
|
+
elsif filter.key?(:controller)
|
275
|
+
"No unused routes found for this controller."
|
276
|
+
elsif filter.key?(:grep)
|
277
|
+
"No unused routes found for this grep pattern."
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
233
281
|
end
|
234
282
|
|
235
283
|
class HtmlTableFormatter
|