actionpack 4.2.11.3 → 5.0.7.2
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 +890 -384
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/base.rb +28 -38
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
- data/lib/abstract_controller/caching.rb +62 -0
- data/lib/abstract_controller/callbacks.rb +54 -19
- data/lib/abstract_controller/collector.rb +4 -9
- data/lib/abstract_controller/error.rb +4 -0
- data/lib/abstract_controller/helpers.rb +4 -3
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +28 -18
- data/lib/abstract_controller/translation.rb +8 -7
- data/lib/abstract_controller.rb +6 -2
- data/lib/action_controller/api/api_rendering.rb +14 -0
- data/lib/action_controller/api.rb +147 -0
- data/lib/action_controller/base.rb +14 -11
- data/lib/action_controller/caching.rb +13 -58
- data/lib/action_controller/form_builder.rb +48 -0
- data/lib/action_controller/log_subscriber.rb +3 -10
- data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
- data/lib/action_controller/metal/conditional_get.rb +106 -34
- data/lib/action_controller/metal/cookies.rb +1 -3
- data/lib/action_controller/metal/data_streaming.rb +14 -34
- data/lib/action_controller/metal/etag_with_template_digest.rb +8 -2
- data/lib/action_controller/metal/exceptions.rb +11 -6
- data/lib/action_controller/metal/force_ssl.rb +11 -11
- data/lib/action_controller/metal/head.rb +14 -8
- data/lib/action_controller/metal/helpers.rb +15 -6
- data/lib/action_controller/metal/http_authentication.rb +44 -35
- data/lib/action_controller/metal/implicit_render.rb +61 -6
- data/lib/action_controller/metal/instrumentation.rb +5 -5
- data/lib/action_controller/metal/live.rb +71 -88
- data/lib/action_controller/metal/mime_responds.rb +27 -42
- data/lib/action_controller/metal/params_wrapper.rb +9 -9
- data/lib/action_controller/metal/redirecting.rb +32 -9
- data/lib/action_controller/metal/renderers.rb +83 -40
- data/lib/action_controller/metal/rendering.rb +38 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
- data/lib/action_controller/metal/rescue.rb +3 -12
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +527 -134
- data/lib/action_controller/metal/testing.rb +1 -12
- data/lib/action_controller/metal/url_for.rb +12 -5
- data/lib/action_controller/metal.rb +88 -63
- data/lib/action_controller/railtie.rb +11 -7
- data/lib/action_controller/renderer.rb +113 -0
- data/lib/action_controller/template_assertions.rb +9 -0
- data/lib/action_controller/test_case.rb +311 -374
- data/lib/action_controller.rb +12 -9
- data/lib/action_dispatch/http/cache.rb +73 -34
- data/lib/action_dispatch/http/filter_parameters.rb +16 -12
- data/lib/action_dispatch/http/filter_redirect.rb +7 -8
- data/lib/action_dispatch/http/headers.rb +45 -14
- data/lib/action_dispatch/http/mime_negotiation.rb +42 -23
- data/lib/action_dispatch/http/mime_type.rb +126 -90
- data/lib/action_dispatch/http/mime_types.rb +3 -4
- data/lib/action_dispatch/http/parameter_filter.rb +19 -9
- data/lib/action_dispatch/http/parameters.rb +70 -40
- data/lib/action_dispatch/http/request.rb +144 -89
- data/lib/action_dispatch/http/response.rb +215 -102
- data/lib/action_dispatch/http/upload.rb +6 -2
- data/lib/action_dispatch/http/url.rb +117 -8
- data/lib/action_dispatch/journey/formatter.rb +47 -30
- data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
- data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
- data/lib/action_dispatch/journey/nodes/node.rb +14 -4
- data/lib/action_dispatch/journey/parser.rb +2 -0
- data/lib/action_dispatch/journey/parser_extras.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +38 -42
- data/lib/action_dispatch/journey/route.rb +88 -26
- data/lib/action_dispatch/journey/router/utils.rb +5 -5
- data/lib/action_dispatch/journey/router.rb +8 -10
- data/lib/action_dispatch/journey/routes.rb +14 -15
- data/lib/action_dispatch/journey/visitors.rb +89 -44
- data/lib/action_dispatch/middleware/callbacks.rb +10 -1
- data/lib/action_dispatch/middleware/cookies.rb +188 -134
- data/lib/action_dispatch/middleware/debug_exceptions.rb +128 -49
- data/lib/action_dispatch/middleware/debug_locks.rb +122 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
- data/lib/action_dispatch/middleware/executor.rb +19 -0
- data/lib/action_dispatch/middleware/flash.rb +66 -45
- data/lib/action_dispatch/middleware/params_parser.rb +32 -46
- data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +14 -58
- data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
- data/lib/action_dispatch/middleware/request_id.rb +11 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
- data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
- data/lib/action_dispatch/middleware/ssl.rb +124 -36
- data/lib/action_dispatch/middleware/stack.rb +44 -40
- data/lib/action_dispatch/middleware/static.rb +51 -35
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -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 +59 -63
- data/lib/action_dispatch/railtie.rb +2 -2
- data/lib/action_dispatch/request/session.rb +69 -33
- data/lib/action_dispatch/request/utils.rb +51 -19
- data/lib/action_dispatch/routing/inspector.rb +32 -43
- data/lib/action_dispatch/routing/mapper.rb +515 -348
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
- data/lib/action_dispatch/routing/redirection.rb +5 -4
- data/lib/action_dispatch/routing/route_set.rb +148 -240
- data/lib/action_dispatch/routing/url_for.rb +27 -10
- data/lib/action_dispatch/routing.rb +17 -13
- data/lib/action_dispatch/testing/assertion_response.rb +45 -0
- data/lib/action_dispatch/testing/assertions/response.rb +38 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/integration.rb +377 -149
- data/lib/action_dispatch/testing/request_encoder.rb +53 -0
- data/lib/action_dispatch/testing/test_process.rb +24 -20
- data/lib/action_dispatch/testing/test_request.rb +22 -31
- data/lib/action_dispatch/testing/test_response.rb +12 -4
- data/lib/action_dispatch.rb +4 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +32 -34
- 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/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
- /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
@@ -81,92 +81,87 @@
|
|
81
81
|
</table>
|
82
82
|
|
83
83
|
<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
|
-
}
|
84
|
+
// support forEarch iterator on NodeList
|
85
|
+
NodeList.prototype.forEach = Array.prototype.forEach;
|
96
86
|
|
97
87
|
// Enables path search functionality
|
98
88
|
function setupMatchPaths() {
|
99
|
-
// Check if
|
100
|
-
function
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
showMatch(string, regexp, section, elem);
|
89
|
+
// Check if there are any matched results in a section
|
90
|
+
function checkNoMatch(section, noMatchText) {
|
91
|
+
if (section.children.length <= 1) {
|
92
|
+
section.innerHTML += noMatchText;
|
93
|
+
}
|
105
94
|
}
|
106
95
|
|
107
|
-
//
|
108
|
-
function
|
109
|
-
var
|
110
|
-
|
111
|
-
|
112
|
-
|
96
|
+
// get JSON from url and invoke callback with result
|
97
|
+
function getJSON(url, success) {
|
98
|
+
var xhr = new XMLHttpRequest();
|
99
|
+
xhr.open('GET', url);
|
100
|
+
xhr.onload = function() {
|
101
|
+
if (this.status == 200)
|
102
|
+
success(JSON.parse(this.response));
|
103
|
+
};
|
104
|
+
xhr.send();
|
113
105
|
}
|
114
106
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
107
|
+
function delayedKeyup(input, callback) {
|
108
|
+
var timeout;
|
109
|
+
input.onkeyup = function(){
|
110
|
+
if (timeout) clearTimeout(timeout);
|
111
|
+
timeout = setTimeout(callback, 300);
|
119
112
|
}
|
120
113
|
}
|
121
114
|
|
122
|
-
//
|
123
|
-
function checkNoMatch(section, defaultText, noMatchText) {
|
124
|
-
if (section.innerHTML === defaultText) {
|
125
|
-
setContent(section, defaultText + noMatchText);
|
126
|
-
}
|
127
|
-
}
|
128
|
-
|
129
|
-
// Ensure path always starts with a slash "/" and remove params or fragments
|
115
|
+
// remove params or fragments
|
130
116
|
function sanitizePath(path) {
|
131
|
-
|
132
|
-
return path.replace(/\#.*|\?.*/, '');
|
117
|
+
return path.replace(/[#?].*/, '');
|
133
118
|
}
|
134
119
|
|
135
|
-
var
|
136
|
-
searchElem
|
137
|
-
|
138
|
-
|
120
|
+
var pathElements = document.querySelectorAll('#route_table [data-route-path]'),
|
121
|
+
searchElem = document.querySelector('#search'),
|
122
|
+
exactSection = document.querySelector('#exact_matches'),
|
123
|
+
fuzzySection = document.querySelector('#fuzzy_matches');
|
139
124
|
|
140
125
|
// Remove matches when no search value is present
|
141
126
|
searchElem.onblur = function(e) {
|
142
127
|
if (searchElem.value === "") {
|
143
|
-
|
144
|
-
|
128
|
+
exactSection.innerHTML = "";
|
129
|
+
fuzzySection.innerHTML = "";
|
145
130
|
}
|
146
131
|
}
|
147
132
|
|
148
133
|
// 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 (' +
|
134
|
+
delayedKeyup(searchElem, function() {
|
135
|
+
var path = sanitizePath(searchElem.value),
|
136
|
+
defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + path +'):</th></tr>',
|
137
|
+
defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + path +'):</th></tr>',
|
153
138
|
noExactMatch = '<tr><th colspan="4">No Exact Matches Found</th></tr>',
|
154
139
|
noFuzzyMatch = '<tr><th colspan="4">No Fuzzy Matches Found</th></tr>';
|
155
140
|
|
156
|
-
|
157
|
-
|
158
|
-
setContent(fuzzyMatches, defaultFuzzyMatch);
|
141
|
+
if (!path)
|
142
|
+
return searchElem.onblur();
|
159
143
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
})
|
144
|
+
getJSON('/rails/info/routes?path=' + path, function(matches){
|
145
|
+
// Clear out results section
|
146
|
+
exactSection.innerHTML = defaultExactMatch;
|
147
|
+
fuzzySection.innerHTML = defaultFuzzyMatch;
|
165
148
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
149
|
+
// Display exact matches and fuzzy matches
|
150
|
+
pathElements.forEach(function(elem) {
|
151
|
+
var elemPath = elem.getAttribute('data-route-path');
|
152
|
+
|
153
|
+
if (matches['exact'].indexOf(elemPath) != -1)
|
154
|
+
exactSection.appendChild(elem.parentNode.cloneNode(true));
|
155
|
+
|
156
|
+
if (matches['fuzzy'].indexOf(elemPath) != -1)
|
157
|
+
fuzzySection.appendChild(elem.parentNode.cloneNode(true));
|
158
|
+
})
|
159
|
+
|
160
|
+
// Display 'No Matches' message when no matches are found
|
161
|
+
checkNoMatch(exactSection, noExactMatch);
|
162
|
+
checkNoMatch(fuzzySection, noFuzzyMatch);
|
163
|
+
})
|
164
|
+
})
|
170
165
|
}
|
171
166
|
|
172
167
|
// Enables functionality to toggle between `_path` and `_url` helper suffixes
|
@@ -174,19 +169,20 @@
|
|
174
169
|
|
175
170
|
// Sets content for each element
|
176
171
|
function setValOn(elems, val) {
|
177
|
-
|
178
|
-
|
172
|
+
elems.forEach(function(elem) {
|
173
|
+
elem.innerHTML = val;
|
179
174
|
});
|
180
175
|
}
|
181
176
|
|
182
177
|
// Sets onClick event for each element
|
183
178
|
function onClick(elems, func) {
|
184
|
-
|
179
|
+
elems.forEach(function(elem) {
|
185
180
|
elem.onclick = func;
|
186
181
|
});
|
187
182
|
}
|
188
183
|
|
189
184
|
var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
|
185
|
+
|
190
186
|
onClick(toggleLinks, function(){
|
191
187
|
var helperTxt = this.getAttribute("data-route-helper"),
|
192
188
|
helperElems = document.querySelectorAll('[data-route-name] span.helper');
|
@@ -39,9 +39,9 @@ module ActionDispatch
|
|
39
39
|
config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
|
40
40
|
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
|
41
41
|
|
42
|
-
ActionDispatch.
|
42
|
+
ActionDispatch::Reloader.default_reloader = app.reloader
|
43
43
|
|
44
|
-
ActionDispatch
|
44
|
+
ActionDispatch.test_app = app
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -1,56 +1,56 @@
|
|
1
1
|
require 'rack/session/abstract/id'
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
|
-
class Request
|
4
|
+
class Request
|
5
5
|
# Session is responsible for lazily loading the session from store.
|
6
6
|
class Session # :nodoc:
|
7
|
-
ENV_SESSION_KEY = Rack::
|
8
|
-
ENV_SESSION_OPTIONS_KEY = Rack::
|
7
|
+
ENV_SESSION_KEY = Rack::RACK_SESSION # :nodoc:
|
8
|
+
ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS # :nodoc:
|
9
9
|
|
10
10
|
# Singleton object used to determine if an optional param wasn't specified
|
11
11
|
Unspecified = Object.new
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
# Creates a session hash, merging the properties of the previous session if any
|
14
|
+
def self.create(store, req, default_options)
|
15
|
+
session_was = find req
|
16
|
+
session = Request::Session.new(store, req)
|
16
17
|
session.merge! session_was if session_was
|
17
18
|
|
18
|
-
set(
|
19
|
-
Options.set(
|
19
|
+
set(req, session)
|
20
|
+
Options.set(req, Request::Session::Options.new(store, default_options))
|
20
21
|
session
|
21
22
|
end
|
22
23
|
|
23
|
-
def self.find(
|
24
|
-
|
24
|
+
def self.find(req)
|
25
|
+
req.get_header ENV_SESSION_KEY
|
25
26
|
end
|
26
27
|
|
27
|
-
def self.set(
|
28
|
-
|
28
|
+
def self.set(req, session)
|
29
|
+
req.set_header ENV_SESSION_KEY, session
|
29
30
|
end
|
30
31
|
|
31
32
|
class Options #:nodoc:
|
32
|
-
def self.set(
|
33
|
-
|
33
|
+
def self.set(req, options)
|
34
|
+
req.set_header ENV_SESSION_OPTIONS_KEY, options
|
34
35
|
end
|
35
36
|
|
36
|
-
def self.find(
|
37
|
-
|
37
|
+
def self.find(req)
|
38
|
+
req.get_header ENV_SESSION_OPTIONS_KEY
|
38
39
|
end
|
39
40
|
|
40
|
-
def initialize(by,
|
41
|
+
def initialize(by, default_options)
|
41
42
|
@by = by
|
42
|
-
@env = env
|
43
43
|
@delegate = default_options.dup
|
44
44
|
end
|
45
45
|
|
46
46
|
def [](key)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@
|
53
|
-
|
47
|
+
@delegate[key]
|
48
|
+
end
|
49
|
+
|
50
|
+
def id(req)
|
51
|
+
@delegate.fetch(:id) {
|
52
|
+
@by.send(:extract_session_id, req)
|
53
|
+
}
|
54
54
|
end
|
55
55
|
|
56
56
|
def []=(k,v); @delegate[k] = v; end
|
@@ -58,38 +58,40 @@ module ActionDispatch
|
|
58
58
|
def values_at(*args); @delegate.values_at(*args); end
|
59
59
|
end
|
60
60
|
|
61
|
-
def initialize(by,
|
61
|
+
def initialize(by, req)
|
62
62
|
@by = by
|
63
|
-
@
|
63
|
+
@req = req
|
64
64
|
@delegate = {}
|
65
65
|
@loaded = false
|
66
66
|
@exists = nil # we haven't checked yet
|
67
67
|
end
|
68
68
|
|
69
69
|
def id
|
70
|
-
options
|
70
|
+
options.id(@req)
|
71
71
|
end
|
72
72
|
|
73
73
|
def options
|
74
|
-
Options.find @
|
74
|
+
Options.find @req
|
75
75
|
end
|
76
76
|
|
77
77
|
def destroy
|
78
78
|
clear
|
79
79
|
options = self.options || {}
|
80
|
-
|
81
|
-
options[:id] = new_sid # Reset session id with a new value or nil
|
80
|
+
@by.send(:delete_session, @req, options.id(@req), options)
|
82
81
|
|
83
82
|
# Load the new sid to be written with the response
|
84
83
|
@loaded = false
|
85
84
|
load_for_write!
|
86
85
|
end
|
87
86
|
|
87
|
+
# Returns value of the key stored in the session or
|
88
|
+
# nil if the given key is not found in the session.
|
88
89
|
def [](key)
|
89
90
|
load_for_read!
|
90
91
|
@delegate[key.to_s]
|
91
92
|
end
|
92
93
|
|
94
|
+
# Returns true if the session has the given key or false.
|
93
95
|
def has_key?(key)
|
94
96
|
load_for_read!
|
95
97
|
@delegate.key?(key.to_s)
|
@@ -97,39 +99,69 @@ module ActionDispatch
|
|
97
99
|
alias :key? :has_key?
|
98
100
|
alias :include? :has_key?
|
99
101
|
|
102
|
+
# Returns keys of the session as Array.
|
100
103
|
def keys
|
101
104
|
@delegate.keys
|
102
105
|
end
|
103
106
|
|
107
|
+
# Returns values of the session as Array.
|
104
108
|
def values
|
105
109
|
@delegate.values
|
106
110
|
end
|
107
111
|
|
112
|
+
# Writes given value to given key of the session.
|
108
113
|
def []=(key, value)
|
109
114
|
load_for_write!
|
110
115
|
@delegate[key.to_s] = value
|
111
116
|
end
|
112
117
|
|
118
|
+
# Clears the session.
|
113
119
|
def clear
|
114
120
|
load_for_write!
|
115
121
|
@delegate.clear
|
116
122
|
end
|
117
123
|
|
124
|
+
# Returns the session as Hash.
|
118
125
|
def to_hash
|
119
126
|
load_for_read!
|
120
127
|
@delegate.dup.delete_if { |_,v| v.nil? }
|
121
128
|
end
|
122
129
|
|
130
|
+
# Updates the session with given Hash.
|
131
|
+
#
|
132
|
+
# session.to_hash
|
133
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2"}
|
134
|
+
#
|
135
|
+
# session.update({ "foo" => "bar" })
|
136
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
|
137
|
+
#
|
138
|
+
# session.to_hash
|
139
|
+
# # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
|
123
140
|
def update(hash)
|
124
141
|
load_for_write!
|
125
142
|
@delegate.update stringify_keys(hash)
|
126
143
|
end
|
127
144
|
|
145
|
+
# Deletes given key from the session.
|
128
146
|
def delete(key)
|
129
147
|
load_for_write!
|
130
148
|
@delegate.delete key.to_s
|
131
149
|
end
|
132
150
|
|
151
|
+
# Returns value of the given key from the session, or raises +KeyError+
|
152
|
+
# if can't find the given key and no default value is set.
|
153
|
+
# Returns default value if specified.
|
154
|
+
#
|
155
|
+
# session.fetch(:foo)
|
156
|
+
# # => KeyError: key not found: "foo"
|
157
|
+
#
|
158
|
+
# session.fetch(:foo, :bar)
|
159
|
+
# # => :bar
|
160
|
+
#
|
161
|
+
# session.fetch(:foo) do
|
162
|
+
# :bar
|
163
|
+
# end
|
164
|
+
# # => :bar
|
133
165
|
def fetch(key, default=Unspecified, &block)
|
134
166
|
load_for_read!
|
135
167
|
if default == Unspecified
|
@@ -149,7 +181,7 @@ module ActionDispatch
|
|
149
181
|
|
150
182
|
def exists?
|
151
183
|
return @exists unless @exists.nil?
|
152
|
-
@exists = @by.send(:session_exists?, @
|
184
|
+
@exists = @by.send(:session_exists?, @req)
|
153
185
|
end
|
154
186
|
|
155
187
|
def loaded?
|
@@ -166,6 +198,10 @@ module ActionDispatch
|
|
166
198
|
@delegate.merge!(other)
|
167
199
|
end
|
168
200
|
|
201
|
+
def each(&block)
|
202
|
+
to_hash.each(&block)
|
203
|
+
end
|
204
|
+
|
169
205
|
private
|
170
206
|
|
171
207
|
def load_for_read!
|
@@ -177,7 +213,7 @@ module ActionDispatch
|
|
177
213
|
end
|
178
214
|
|
179
215
|
def load!
|
180
|
-
id, session = @by.load_session @
|
216
|
+
id, session = @by.load_session @req
|
181
217
|
options[:id] = id
|
182
218
|
@delegate.replace(stringify_keys(session))
|
183
219
|
@loaded = true
|
@@ -1,32 +1,64 @@
|
|
1
1
|
module ActionDispatch
|
2
|
-
class Request
|
2
|
+
class Request
|
3
3
|
class Utils # :nodoc:
|
4
4
|
|
5
5
|
mattr_accessor :perform_deep_munge
|
6
6
|
self.perform_deep_munge = true
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def self.normalize_encode_params(params)
|
9
|
+
if perform_deep_munge
|
10
|
+
NoNilParamEncoder.normalize_encode_params params
|
11
|
+
else
|
12
|
+
ParamEncoder.normalize_encode_params params
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.check_param_encoding(params)
|
17
|
+
case params
|
18
|
+
when Array
|
19
|
+
params.each { |element| check_param_encoding(element) }
|
20
|
+
when Hash
|
21
|
+
params.each_value { |value| check_param_encoding(value) }
|
22
|
+
when String
|
23
|
+
unless params.valid_encoding?
|
24
|
+
# Raise Rack::Utils::InvalidParameterError for consistency with Rack.
|
25
|
+
# ActionDispatch::Request#GET will re-raise as a BadRequest error.
|
26
|
+
raise Rack::Utils::InvalidParameterError, "Non UTF-8 value: #{params}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
12
30
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
31
|
+
class ParamEncoder # :nodoc:
|
32
|
+
# Convert nested Hash to HashWithIndifferentAccess.
|
33
|
+
#
|
34
|
+
def self.normalize_encode_params(params)
|
35
|
+
case params
|
36
|
+
when Array
|
37
|
+
handle_array params
|
38
|
+
when Hash
|
39
|
+
if params.has_key?(:tempfile)
|
40
|
+
ActionDispatch::Http::UploadedFile.new(params)
|
41
|
+
else
|
42
|
+
params.each_with_object({}) do |(key, val), new_hash|
|
43
|
+
new_hash[key] = normalize_encode_params(val)
|
44
|
+
end.with_indifferent_access
|
25
45
|
end
|
26
|
-
|
46
|
+
else
|
47
|
+
params
|
27
48
|
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.handle_array(params)
|
52
|
+
params.map! { |el| normalize_encode_params(el) }
|
53
|
+
end
|
54
|
+
end
|
28
55
|
|
29
|
-
|
56
|
+
# Remove nils from the params hash
|
57
|
+
class NoNilParamEncoder < ParamEncoder # :nodoc:
|
58
|
+
def self.handle_array(params)
|
59
|
+
list = super
|
60
|
+
list.compact!
|
61
|
+
list
|
30
62
|
end
|
31
63
|
end
|
32
64
|
end
|
@@ -16,10 +16,6 @@ module ActionDispatch
|
|
16
16
|
app.app
|
17
17
|
end
|
18
18
|
|
19
|
-
def verb
|
20
|
-
super.source.gsub(/[$^]/, '')
|
21
|
-
end
|
22
|
-
|
23
19
|
def path
|
24
20
|
super.spec.to_s
|
25
21
|
end
|
@@ -28,23 +24,6 @@ module ActionDispatch
|
|
28
24
|
super.to_s
|
29
25
|
end
|
30
26
|
|
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
27
|
def reqs
|
49
28
|
@reqs ||= begin
|
50
29
|
reqs = endpoint
|
@@ -54,15 +33,15 @@ module ActionDispatch
|
|
54
33
|
end
|
55
34
|
|
56
35
|
def controller
|
57
|
-
|
36
|
+
parts.include?(:controller) ? ':controller' : requirements[:controller]
|
58
37
|
end
|
59
38
|
|
60
39
|
def action
|
61
|
-
|
40
|
+
parts.include?(:action) ? ':action' : requirements[:action]
|
62
41
|
end
|
63
42
|
|
64
43
|
def internal?
|
65
|
-
|
44
|
+
internal
|
66
45
|
end
|
67
46
|
|
68
47
|
def engine?
|
@@ -72,7 +51,7 @@ module ActionDispatch
|
|
72
51
|
|
73
52
|
##
|
74
53
|
# This class is just used for displaying route information when someone
|
75
|
-
# executes `
|
54
|
+
# executes `rails routes` or looks at the RoutingError page.
|
76
55
|
# People should not use this class.
|
77
56
|
class RoutesInspector # :nodoc:
|
78
57
|
def initialize(routes)
|
@@ -81,12 +60,10 @@ module ActionDispatch
|
|
81
60
|
end
|
82
61
|
|
83
62
|
def format(formatter, filter = nil)
|
84
|
-
routes_to_display = filter_routes(filter)
|
85
|
-
|
63
|
+
routes_to_display = filter_routes(normalize_filter(filter))
|
86
64
|
routes = collect_routes(routes_to_display)
|
87
|
-
|
88
65
|
if routes.none?
|
89
|
-
formatter.no_routes
|
66
|
+
formatter.no_routes(collect_routes(@routes))
|
90
67
|
return formatter.result
|
91
68
|
end
|
92
69
|
|
@@ -103,9 +80,20 @@ module ActionDispatch
|
|
103
80
|
|
104
81
|
private
|
105
82
|
|
83
|
+
def normalize_filter(filter)
|
84
|
+
if filter.is_a?(Hash) && filter[:controller]
|
85
|
+
{ controller: /#{filter[:controller].downcase.sub(/_?controller\z/, '').sub('::', '/')}/ }
|
86
|
+
elsif filter
|
87
|
+
{ controller: /#{filter}/, action: /#{filter}/, verb: /#{filter}/, name: /#{filter}/, path: /#{filter}/ }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
106
91
|
def filter_routes(filter)
|
107
92
|
if filter
|
108
|
-
@routes.select
|
93
|
+
@routes.select do |route|
|
94
|
+
route_wrapper = RouteWrapper.new(route)
|
95
|
+
filter.any? { |default, value| route_wrapper.send(default) =~ value }
|
96
|
+
end
|
109
97
|
else
|
110
98
|
@routes
|
111
99
|
end
|
@@ -114,16 +102,13 @@ module ActionDispatch
|
|
114
102
|
def collect_routes(routes)
|
115
103
|
routes.collect do |route|
|
116
104
|
RouteWrapper.new(route)
|
117
|
-
end.reject do |route|
|
118
|
-
route.internal?
|
119
|
-
end.collect do |route|
|
105
|
+
end.reject(&:internal?).collect do |route|
|
120
106
|
collect_engine_routes(route)
|
121
107
|
|
122
|
-
{ name:
|
123
|
-
verb:
|
124
|
-
path:
|
125
|
-
reqs:
|
126
|
-
regexp: route.json_regexp }
|
108
|
+
{ name: route.name,
|
109
|
+
verb: route.verb,
|
110
|
+
path: route.path,
|
111
|
+
reqs: route.reqs }
|
127
112
|
end
|
128
113
|
end
|
129
114
|
|
@@ -160,14 +145,18 @@ module ActionDispatch
|
|
160
145
|
@buffer << draw_header(routes)
|
161
146
|
end
|
162
147
|
|
163
|
-
def no_routes
|
164
|
-
@buffer <<
|
148
|
+
def no_routes(routes)
|
149
|
+
@buffer <<
|
150
|
+
if routes.none?
|
151
|
+
<<-MESSAGE.strip_heredoc
|
165
152
|
You don't have any routes defined!
|
166
153
|
|
167
154
|
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
155
|
MESSAGE
|
156
|
+
else
|
157
|
+
"No routes were found for this controller"
|
158
|
+
end
|
159
|
+
@buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
|
171
160
|
end
|
172
161
|
|
173
162
|
private
|
@@ -211,7 +200,7 @@ module ActionDispatch
|
|
211
200
|
def header(routes)
|
212
201
|
end
|
213
202
|
|
214
|
-
def no_routes
|
203
|
+
def no_routes(*)
|
215
204
|
@buffer << <<-MESSAGE.strip_heredoc
|
216
205
|
<p>You don't have any routes defined!</p>
|
217
206
|
<ul>
|