actionpack 4.2.10 → 6.1.4
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 +5 -5
- data/CHANGELOG.md +311 -461
- data/MIT-LICENSE +1 -1
- data/README.rdoc +9 -9
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +81 -51
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +61 -33
- data/lib/abstract_controller/collector.rb +9 -13
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +115 -99
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
- data/lib/abstract_controller/rendering.rb +48 -47
- data/lib/abstract_controller/translation.rb +17 -8
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +13 -5
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/api.rb +150 -0
- data/lib/action_controller/base.rb +29 -24
- data/lib/action_controller/caching.rb +12 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +17 -19
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +134 -46
- data/lib/action_controller/metal/content_security_policy.rb +51 -0
- data/lib/action_controller/metal/cookies.rb +6 -4
- data/lib/action_controller/metal/data_streaming.rb +30 -50
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
- data/lib/action_controller/metal/exceptions.rb +63 -15
- data/lib/action_controller/metal/flash.rb +9 -8
- data/lib/action_controller/metal/head.rb +26 -21
- data/lib/action_controller/metal/helpers.rb +37 -18
- data/lib/action_controller/metal/http_authentication.rb +81 -73
- data/lib/action_controller/metal/implicit_render.rb +53 -9
- data/lib/action_controller/metal/instrumentation.rb +32 -35
- data/lib/action_controller/metal/live.rb +110 -119
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +49 -47
- data/lib/action_controller/metal/parameter_encoding.rb +82 -0
- data/lib/action_controller/metal/params_wrapper.rb +84 -66
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +53 -32
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +77 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
- data/lib/action_controller/metal/rescue.rb +10 -17
- data/lib/action_controller/metal/streaming.rb +12 -11
- data/lib/action_controller/metal/strong_parameters.rb +714 -186
- 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 +104 -87
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +3 -1
- data/lib/action_controller/renderer.rb +141 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +298 -421
- data/lib/action_controller.rb +34 -23
- data/lib/action_dispatch/http/cache.rb +108 -58
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +286 -0
- data/lib/action_dispatch/http/filter_parameters.rb +32 -25
- data/lib/action_dispatch/http/filter_redirect.rb +10 -12
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +82 -50
- data/lib/action_dispatch/http/mime_type.rb +153 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameters.rb +90 -40
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +226 -121
- data/lib/action_dispatch/http/response.rb +248 -113
- data/lib/action_dispatch/http/upload.rb +21 -7
- data/lib/action_dispatch/http/url.rb +182 -100
- data/lib/action_dispatch/journey/formatter.rb +91 -44
- data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
- data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
- data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
- data/lib/action_dispatch/journey/nodes/node.rb +29 -15
- data/lib/action_dispatch/journey/parser.rb +17 -16
- data/lib/action_dispatch/journey/parser.y +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +58 -54
- data/lib/action_dispatch/journey/route.rb +100 -32
- data/lib/action_dispatch/journey/router/utils.rb +29 -18
- data/lib/action_dispatch/journey/router.rb +55 -51
- data/lib/action_dispatch/journey/routes.rb +17 -17
- data/lib/action_dispatch/journey/scanner.rb +26 -17
- data/lib/action_dispatch/journey/visitors.rb +98 -54
- data/lib/action_dispatch/journey.rb +5 -5
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +3 -6
- data/lib/action_dispatch/middleware/cookies.rb +347 -217
- data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
- data/lib/action_dispatch/middleware/request_id.rb +17 -10
- data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
- data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
- data/lib/action_dispatch/middleware/ssl.rb +118 -35
- data/lib/action_dispatch/middleware/stack.rb +82 -41
- data/lib/action_dispatch/middleware/static.rb +156 -89
- 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/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- 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 +23 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
- 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 +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.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 +87 -64
- data/lib/action_dispatch/railtie.rb +27 -13
- data/lib/action_dispatch/request/session.rb +109 -61
- data/lib/action_dispatch/request/utils.rb +90 -23
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +141 -102
- data/lib/action_dispatch/routing/mapper.rb +811 -473
- data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
- data/lib/action_dispatch/routing/redirection.rb +37 -27
- data/lib/action_dispatch/routing/route_set.rb +363 -331
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +66 -26
- data/lib/action_dispatch/routing.rb +36 -36
- data/lib/action_dispatch/system_test_case.rb +190 -0
- data/lib/action_dispatch/system_testing/browser.rb +86 -0
- data/lib/action_dispatch/system_testing/driver.rb +67 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
- data/lib/action_dispatch/testing/assertion_response.rb +46 -0
- data/lib/action_dispatch/testing/assertions/response.rb +44 -22
- data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +391 -220
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +53 -22
- data/lib/action_dispatch/testing/test_request.rb +27 -34
- data/lib/action_dispatch/testing/test_response.rb +11 -11
- data/lib/action_dispatch.rb +35 -21
- 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 +75 -46
- data/lib/action_controller/metal/force_ssl.rb +0 -97
- 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/http/parameter_filter.rb +0 -72
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
- 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
@@ -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
|
}
|
@@ -45,6 +49,26 @@
|
|
45
49
|
width: 80%;
|
46
50
|
font-size: inherit;
|
47
51
|
}
|
52
|
+
|
53
|
+
@media (prefers-color-scheme: dark) {
|
54
|
+
body {
|
55
|
+
background-color: #222;
|
56
|
+
color: #ECECEC;
|
57
|
+
}
|
58
|
+
|
59
|
+
#route_table tbody tr:nth-child(odd) {
|
60
|
+
background: #333;
|
61
|
+
}
|
62
|
+
|
63
|
+
#route_table tbody tr:nth-child(even) {
|
64
|
+
background: #444;
|
65
|
+
}
|
66
|
+
|
67
|
+
#route_table tbody.exact_matches,
|
68
|
+
#route_table tbody.fuzzy_matches {
|
69
|
+
color: #333;
|
70
|
+
}
|
71
|
+
}
|
48
72
|
<% end %>
|
49
73
|
|
50
74
|
<table id='route_table' class='route_table'>
|
@@ -60,7 +84,7 @@
|
|
60
84
|
<%= link_to "Path", "#", 'data-route-helper' => '_path',
|
61
85
|
title: "Returns a relative path (without the http or domain)" %> /
|
62
86
|
<%= link_to "Url", "#", 'data-route-helper' => '_url',
|
63
|
-
title: "Returns an absolute
|
87
|
+
title: "Returns an absolute URL (with the http and domain)" %>
|
64
88
|
</th>
|
65
89
|
<th><%# HTTP Verb %>
|
66
90
|
</th>
|
@@ -81,92 +105,87 @@
|
|
81
105
|
</table>
|
82
106
|
|
83
107
|
<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
|
-
}
|
108
|
+
// support forEach iterator on NodeList
|
109
|
+
NodeList.prototype.forEach = Array.prototype.forEach;
|
96
110
|
|
97
111
|
// Enables path search functionality
|
98
112
|
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);
|
113
|
+
// Check if there are any matched results in a section
|
114
|
+
function checkNoMatch(section, noMatchText) {
|
115
|
+
if (section.children.length <= 1) {
|
116
|
+
section.innerHTML += noMatchText;
|
117
|
+
}
|
113
118
|
}
|
114
119
|
|
115
|
-
//
|
116
|
-
function
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
+
// get JSON from URL and invoke callback with result
|
121
|
+
function getJSON(url, success) {
|
122
|
+
var xhr = new XMLHttpRequest();
|
123
|
+
xhr.open('GET', url);
|
124
|
+
xhr.onload = function() {
|
125
|
+
if (this.status == 200)
|
126
|
+
success(JSON.parse(this.response));
|
127
|
+
};
|
128
|
+
xhr.send();
|
120
129
|
}
|
121
130
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
131
|
+
function delayedKeyup(input, callback) {
|
132
|
+
var timeout;
|
133
|
+
input.onkeyup = function(){
|
134
|
+
if (timeout) clearTimeout(timeout);
|
135
|
+
timeout = setTimeout(callback, 300);
|
126
136
|
}
|
127
137
|
}
|
128
138
|
|
129
|
-
//
|
139
|
+
// remove params or fragments
|
130
140
|
function sanitizePath(path) {
|
131
|
-
|
132
|
-
return path.replace(/\#.*|\?.*/, '');
|
141
|
+
return path.replace(/[#?].*/, '');
|
133
142
|
}
|
134
143
|
|
135
|
-
var
|
136
|
-
searchElem
|
137
|
-
|
138
|
-
|
144
|
+
var pathElements = document.querySelectorAll('#route_table [data-route-path]'),
|
145
|
+
searchElem = document.querySelector('#search'),
|
146
|
+
exactSection = document.querySelector('#exact_matches'),
|
147
|
+
fuzzySection = document.querySelector('#fuzzy_matches');
|
139
148
|
|
140
149
|
// Remove matches when no search value is present
|
141
150
|
searchElem.onblur = function(e) {
|
142
151
|
if (searchElem.value === "") {
|
143
|
-
|
144
|
-
|
152
|
+
exactSection.innerHTML = "";
|
153
|
+
fuzzySection.innerHTML = "";
|
145
154
|
}
|
146
155
|
}
|
147
156
|
|
148
157
|
// 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 (' +
|
158
|
+
delayedKeyup(searchElem, function() {
|
159
|
+
var path = sanitizePath(searchElem.value),
|
160
|
+
defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + path +'):</th></tr>',
|
161
|
+
defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + path +'):</th></tr>',
|
153
162
|
noExactMatch = '<tr><th colspan="4">No Exact Matches Found</th></tr>',
|
154
163
|
noFuzzyMatch = '<tr><th colspan="4">No Fuzzy Matches Found</th></tr>';
|
155
164
|
|
156
|
-
|
157
|
-
|
158
|
-
setContent(fuzzyMatches, defaultFuzzyMatch);
|
165
|
+
if (!path)
|
166
|
+
return searchElem.onblur();
|
159
167
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
})
|
168
|
+
getJSON('/rails/info/routes?path=' + path, function(matches){
|
169
|
+
// Clear out results section
|
170
|
+
exactSection.innerHTML = defaultExactMatch;
|
171
|
+
fuzzySection.innerHTML = defaultFuzzyMatch;
|
165
172
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
173
|
+
// Display exact matches and fuzzy matches
|
174
|
+
pathElements.forEach(function(elem) {
|
175
|
+
var elemPath = elem.getAttribute('data-route-path');
|
176
|
+
|
177
|
+
if (matches['exact'].indexOf(elemPath) != -1)
|
178
|
+
exactSection.appendChild(elem.parentNode.cloneNode(true));
|
179
|
+
|
180
|
+
if (matches['fuzzy'].indexOf(elemPath) != -1)
|
181
|
+
fuzzySection.appendChild(elem.parentNode.cloneNode(true));
|
182
|
+
})
|
183
|
+
|
184
|
+
// Display 'No Matches' message when no matches are found
|
185
|
+
checkNoMatch(exactSection, noExactMatch);
|
186
|
+
checkNoMatch(fuzzySection, noFuzzyMatch);
|
187
|
+
})
|
188
|
+
})
|
170
189
|
}
|
171
190
|
|
172
191
|
// Enables functionality to toggle between `_path` and `_url` helper suffixes
|
@@ -174,19 +193,20 @@
|
|
174
193
|
|
175
194
|
// Sets content for each element
|
176
195
|
function setValOn(elems, val) {
|
177
|
-
|
178
|
-
|
196
|
+
elems.forEach(function(elem) {
|
197
|
+
elem.innerHTML = val;
|
179
198
|
});
|
180
199
|
}
|
181
200
|
|
182
201
|
// Sets onClick event for each element
|
183
202
|
function onClick(elems, func) {
|
184
|
-
|
203
|
+
elems.forEach(function(elem) {
|
185
204
|
elem.onclick = func;
|
186
205
|
});
|
187
206
|
}
|
188
207
|
|
189
208
|
var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
|
209
|
+
|
190
210
|
onClick(toggleLinks, function(){
|
191
211
|
var helperTxt = this.getAttribute("data-route-helper"),
|
192
212
|
helperElems = document.querySelectorAll('[data-route-name] span.helper');
|
@@ -197,4 +217,7 @@
|
|
197
217
|
|
198
218
|
setupMatchPaths();
|
199
219
|
setupRouteToggleHelperLinks();
|
220
|
+
|
221
|
+
// Focus the search input after page has loaded
|
222
|
+
document.getElementById('search').focus();
|
200
223
|
</script>
|
@@ -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,30 +11,43 @@ 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
|
24
|
+
config.action_dispatch.use_cookies_with_metadata = false
|
19
25
|
config.action_dispatch.perform_deep_munge = true
|
26
|
+
config.action_dispatch.request_id_header = "X-Request-Id"
|
20
27
|
|
21
28
|
config.action_dispatch.default_headers = {
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
"X-Frame-Options" => "SAMEORIGIN",
|
30
|
+
"X-XSS-Protection" => "1; mode=block",
|
31
|
+
"X-Content-Type-Options" => "nosniff",
|
32
|
+
"X-Download-Options" => "noopen",
|
33
|
+
"X-Permitted-Cross-Domain-Policies" => "none",
|
34
|
+
"Referrer-Policy" => "strict-origin-when-cross-origin"
|
25
35
|
}
|
26
36
|
|
37
|
+
config.action_dispatch.cookies_rotations = ActiveSupport::Messages::RotationConfiguration.new
|
38
|
+
|
27
39
|
config.eager_load_namespaces << ActionDispatch
|
28
40
|
|
29
41
|
initializer "action_dispatch.configure" do |app|
|
42
|
+
ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
|
30
43
|
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
|
31
44
|
ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
|
32
45
|
ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
|
33
|
-
|
34
|
-
|
46
|
+
|
47
|
+
ActiveSupport.on_load(:action_dispatch_response) do
|
48
|
+
self.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
|
49
|
+
self.default_headers = app.config.action_dispatch.default_headers
|
50
|
+
end
|
35
51
|
|
36
52
|
ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
|
37
53
|
ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)
|
@@ -40,8 +56,6 @@ module ActionDispatch
|
|
40
56
|
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
|
41
57
|
|
42
58
|
ActionDispatch.test_app = app
|
43
|
-
|
44
|
-
ActionDispatch::Routing::RouteSet.relative_url_root = app.config.relative_url_root
|
45
59
|
end
|
46
60
|
end
|
47
61
|
end
|
@@ -1,95 +1,113 @@
|
|
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 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
|
+
|
110
|
+
# Returns true if the session has the given key or false.
|
93
111
|
def has_key?(key)
|
94
112
|
load_for_read!
|
95
113
|
@delegate.key?(key.to_s)
|
@@ -97,40 +115,73 @@ module ActionDispatch
|
|
97
115
|
alias :key? :has_key?
|
98
116
|
alias :include? :has_key?
|
99
117
|
|
118
|
+
# Returns keys of the session as Array.
|
100
119
|
def keys
|
120
|
+
load_for_read!
|
101
121
|
@delegate.keys
|
102
122
|
end
|
103
123
|
|
124
|
+
# Returns values of the session as Array.
|
104
125
|
def values
|
126
|
+
load_for_read!
|
105
127
|
@delegate.values
|
106
128
|
end
|
107
129
|
|
130
|
+
# Writes given value to given key of the session.
|
108
131
|
def []=(key, value)
|
109
132
|
load_for_write!
|
110
133
|
@delegate[key.to_s] = value
|
111
134
|
end
|
112
135
|
|
136
|
+
# Clears the session.
|
113
137
|
def clear
|
114
138
|
load_for_write!
|
115
139
|
@delegate.clear
|
116
140
|
end
|
117
141
|
|
142
|
+
# Returns the session as Hash.
|
118
143
|
def to_hash
|
119
144
|
load_for_read!
|
120
|
-
@delegate.dup.delete_if { |_,v| v.nil? }
|
121
|
-
end
|
122
|
-
|
145
|
+
@delegate.dup.delete_if { |_, v| v.nil? }
|
146
|
+
end
|
147
|
+
alias :to_h :to_hash
|
148
|
+
|
149
|
+
# Updates the session with given Hash.
|
150
|
+
#
|
151
|
+
# session.to_hash
|
152
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2"}
|
153
|
+
#
|
154
|
+
# session.update({ "foo" => "bar" })
|
155
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
|
156
|
+
#
|
157
|
+
# session.to_hash
|
158
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
|
123
159
|
def update(hash)
|
124
160
|
load_for_write!
|
125
|
-
@delegate.update stringify_keys
|
161
|
+
@delegate.update hash.stringify_keys
|
126
162
|
end
|
127
163
|
|
164
|
+
# Deletes given key from the session.
|
128
165
|
def delete(key)
|
129
166
|
load_for_write!
|
130
167
|
@delegate.delete key.to_s
|
131
168
|
end
|
132
169
|
|
133
|
-
|
170
|
+
# Returns value of the given key from the session, or raises +KeyError+
|
171
|
+
# if can't find the given key and no default value is set.
|
172
|
+
# Returns default value if specified.
|
173
|
+
#
|
174
|
+
# session.fetch(:foo)
|
175
|
+
# # => KeyError: key not found: "foo"
|
176
|
+
#
|
177
|
+
# session.fetch(:foo, :bar)
|
178
|
+
# # => :bar
|
179
|
+
#
|
180
|
+
# session.fetch(:foo) do
|
181
|
+
# :bar
|
182
|
+
# end
|
183
|
+
# # => :bar
|
184
|
+
def fetch(key, default = Unspecified, &block)
|
134
185
|
load_for_read!
|
135
186
|
if default == Unspecified
|
136
187
|
@delegate.fetch(key.to_s, &block)
|
@@ -149,7 +200,7 @@ module ActionDispatch
|
|
149
200
|
|
150
201
|
def exists?
|
151
202
|
return @exists unless @exists.nil?
|
152
|
-
@exists = @by.send(:session_exists?, @
|
203
|
+
@exists = @by.send(:session_exists?, @req)
|
153
204
|
end
|
154
205
|
|
155
206
|
def loaded?
|
@@ -166,28 +217,25 @@ module ActionDispatch
|
|
166
217
|
@delegate.merge!(other)
|
167
218
|
end
|
168
219
|
|
169
|
-
|
170
|
-
|
171
|
-
def load_for_read!
|
172
|
-
load! if !loaded? && exists?
|
220
|
+
def each(&block)
|
221
|
+
to_hash.each(&block)
|
173
222
|
end
|
174
223
|
|
175
|
-
|
176
|
-
|
177
|
-
|
224
|
+
private
|
225
|
+
def load_for_read!
|
226
|
+
load! if !loaded? && exists?
|
227
|
+
end
|
178
228
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
@delegate.replace(stringify_keys(session))
|
183
|
-
@loaded = true
|
184
|
-
end
|
229
|
+
def load_for_write!
|
230
|
+
load! unless loaded?
|
231
|
+
end
|
185
232
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
233
|
+
def load!
|
234
|
+
id, session = @by.load_session @req
|
235
|
+
options[:id] = id
|
236
|
+
@delegate.replace(session.stringify_keys)
|
237
|
+
@loaded = true
|
238
|
+
end
|
191
239
|
end
|
192
240
|
end
|
193
241
|
end
|