actionpack 6.1.3.1 → 7.0.0.alpha1
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 +102 -370
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +7 -21
- data/lib/abstract_controller/caching/fragments.rb +2 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +9 -8
- data/lib/abstract_controller/collector.rb +4 -2
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +3 -2
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/translation.rb +0 -2
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +38 -1
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -13
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +19 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +16 -16
- data/lib/action_controller/metal/instrumentation.rb +55 -52
- data/lib/action_controller/metal/live.rb +52 -3
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/params_wrapper.rb +10 -9
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/query_tags.rb +16 -0
- data/lib/action_controller/metal/redirecting.rb +50 -16
- data/lib/action_controller/metal/rendering.rb +7 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +64 -20
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +1 -3
- data/lib/action_controller/metal/strong_parameters.rb +24 -28
- data/lib/action_controller/metal/testing.rb +0 -2
- data/lib/action_controller/metal.rb +7 -10
- data/lib/action_controller/railtie.rb +42 -5
- data/lib/action_controller/test_case.rb +9 -2
- data/lib/action_controller.rb +2 -5
- data/lib/action_dispatch/http/cache.rb +18 -12
- data/lib/action_dispatch/http/content_security_policy.rb +39 -35
- data/lib/action_dispatch/http/filter_parameters.rb +5 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -3
- data/lib/action_dispatch/http/mime_type.rb +9 -11
- data/lib/action_dispatch/http/parameters.rb +4 -4
- data/lib/action_dispatch/http/permissions_policy.rb +1 -1
- data/lib/action_dispatch/http/request.rb +10 -19
- data/lib/action_dispatch/http/response.rb +3 -3
- data/lib/action_dispatch/http/url.rb +9 -10
- data/lib/action_dispatch/journey/formatter.rb +2 -2
- data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
- data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
- data/lib/action_dispatch/journey/nodes/node.rb +70 -5
- data/lib/action_dispatch/journey/path/pattern.rb +22 -13
- data/lib/action_dispatch/journey/route.rb +5 -12
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +1 -1
- data/lib/action_dispatch/journey/routes.rb +3 -3
- data/lib/action_dispatch/journey/visitors.rb +1 -1
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
- data/lib/action_dispatch/middleware/cookies.rb +7 -3
- data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
- data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
- data/lib/action_dispatch/middleware/flash.rb +9 -11
- data/lib/action_dispatch/middleware/host_authorization.rb +10 -18
- data/lib/action_dispatch/middleware/remote_ip.rb +16 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +7 -9
- data/lib/action_dispatch/middleware/stack.rb +50 -9
- data/lib/action_dispatch/middleware/static.rb +2 -5
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +5 -14
- data/lib/action_dispatch/railtie.rb +8 -2
- data/lib/action_dispatch/request/session.rb +43 -13
- data/lib/action_dispatch/routing/mapper.rb +44 -72
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -4
- data/lib/action_dispatch/routing/redirection.rb +0 -2
- data/lib/action_dispatch/routing/route_set.rb +9 -6
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +1 -2
- data/lib/action_dispatch/routing.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +5 -5
- data/lib/action_dispatch/system_testing/driver.rb +24 -4
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +10 -6
- data/lib/action_dispatch/testing/assertions.rb +2 -5
- data/lib/action_dispatch/testing/integration.rb +6 -8
- data/lib/action_dispatch/testing/test_process.rb +12 -9
- data/lib/action_dispatch.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +18 -17
@@ -4,15 +4,16 @@ module ActionDispatch
|
|
4
4
|
module Journey # :nodoc:
|
5
5
|
module Path # :nodoc:
|
6
6
|
class Pattern # :nodoc:
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :ast, :names, :requirements, :anchored, :spec
|
8
8
|
|
9
9
|
def initialize(ast, requirements, separators, anchored)
|
10
|
-
@
|
10
|
+
@ast = ast
|
11
|
+
@spec = ast.root
|
11
12
|
@requirements = requirements
|
12
13
|
@separators = separators
|
13
14
|
@anchored = anchored
|
14
15
|
|
15
|
-
@names =
|
16
|
+
@names = ast.names
|
16
17
|
@optional_names = nil
|
17
18
|
@required_names = nil
|
18
19
|
@re = nil
|
@@ -27,20 +28,28 @@ module ActionDispatch
|
|
27
28
|
required_names
|
28
29
|
offsets
|
29
30
|
to_regexp
|
30
|
-
nil
|
31
|
+
@ast = nil
|
31
32
|
end
|
32
33
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
node.regexp = re if re
|
37
|
-
end
|
34
|
+
def requirements_anchored?
|
35
|
+
# each required param must not be surrounded by a literal, otherwise it isn't simple to chunk-match the url piecemeal
|
36
|
+
terminals = ast.terminals
|
38
37
|
|
39
|
-
|
40
|
-
|
38
|
+
terminals.each_with_index { |s, index|
|
39
|
+
next if index < 1
|
40
|
+
next if s.type == :DOT || s.type == :SLASH
|
41
|
+
|
42
|
+
back = terminals[index - 1]
|
43
|
+
fwd = terminals[index + 1]
|
44
|
+
|
45
|
+
# we also don't support this yet, constraints must be regexps
|
46
|
+
return false if s.symbol? && s.regexp.is_a?(Array)
|
47
|
+
|
48
|
+
return false if back.literal?
|
49
|
+
return false if !fwd.nil? && fwd.literal?
|
50
|
+
}
|
41
51
|
|
42
|
-
|
43
|
-
@names ||= spec.find_all(&:symbol?).map(&:name)
|
52
|
+
true
|
44
53
|
end
|
45
54
|
|
46
55
|
def required_names
|
@@ -5,7 +5,7 @@ module ActionDispatch
|
|
5
5
|
module Journey
|
6
6
|
class Route
|
7
7
|
attr_reader :app, :path, :defaults, :name, :precedence, :constraints,
|
8
|
-
:internal, :scope_options
|
8
|
+
:internal, :scope_options, :ast
|
9
9
|
|
10
10
|
alias :conditions :constraints
|
11
11
|
|
@@ -65,29 +65,22 @@ module ActionDispatch
|
|
65
65
|
@_required_defaults = required_defaults
|
66
66
|
@required_parts = nil
|
67
67
|
@parts = nil
|
68
|
-
@decorated_ast = nil
|
69
68
|
@precedence = precedence
|
70
69
|
@path_formatter = @path.build_formatter
|
71
70
|
@scope_options = scope_options
|
72
71
|
@internal = internal
|
72
|
+
|
73
|
+
@ast = @path.ast.root
|
74
|
+
@path.ast.route = self
|
73
75
|
end
|
74
76
|
|
75
77
|
def eager_load!
|
76
78
|
path.eager_load!
|
77
|
-
ast
|
78
79
|
parts
|
79
80
|
required_defaults
|
80
81
|
nil
|
81
82
|
end
|
82
83
|
|
83
|
-
def ast
|
84
|
-
@decorated_ast ||= begin
|
85
|
-
decorated_ast = path.ast
|
86
|
-
decorated_ast.find_all(&:terminal?).each { |n| n.memo = self }
|
87
|
-
decorated_ast
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
84
|
# Needed for `bin/rails routes`. Picks up succinctly defined requirements
|
92
85
|
# for a route, for example route
|
93
86
|
#
|
@@ -142,7 +135,7 @@ module ActionDispatch
|
|
142
135
|
end
|
143
136
|
|
144
137
|
def glob?
|
145
|
-
path.
|
138
|
+
path.ast.glob?
|
146
139
|
end
|
147
140
|
|
148
141
|
def dispatcher?
|
@@ -35,7 +35,7 @@ module ActionDispatch
|
|
35
35
|
US_ASCII = Encoding::US_ASCII
|
36
36
|
UTF_8 = Encoding::UTF_8
|
37
37
|
EMPTY = (+"").force_encoding(US_ASCII).freeze
|
38
|
-
DEC2HEX = (0..255).
|
38
|
+
DEC2HEX = (0..255).map { |i| (ENCODE % i).force_encoding(US_ASCII) }
|
39
39
|
|
40
40
|
ALPHA = "a-zA-Z"
|
41
41
|
DIGIT = "0-9"
|
@@ -44,7 +44,7 @@ module ActionDispatch
|
|
44
44
|
|
45
45
|
ESCAPED = /%[a-zA-Z0-9]{2}/.freeze
|
46
46
|
|
47
|
-
FRAGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}
|
47
|
+
FRAGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/?]/.freeze
|
48
48
|
SEGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@]/.freeze
|
49
49
|
PATH = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/]/.freeze
|
50
50
|
|
@@ -41,7 +41,7 @@ module ActionDispatch
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def partition_route(route)
|
44
|
-
if route.path.anchored && route.
|
44
|
+
if route.path.anchored && route.path.requirements_anchored?
|
45
45
|
anchored_routes << route
|
46
46
|
else
|
47
47
|
custom_routes << route
|
@@ -50,8 +50,8 @@ module ActionDispatch
|
|
50
50
|
|
51
51
|
def ast
|
52
52
|
@ast ||= begin
|
53
|
-
|
54
|
-
Nodes::Or.new(
|
53
|
+
nodes = anchored_routes.map(&:ast)
|
54
|
+
Nodes::Or.new(nodes)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -68,7 +68,7 @@ function highlight_state(index, color) {
|
|
68
68
|
}
|
69
69
|
|
70
70
|
function highlight_finish(index) {
|
71
|
-
svg_nodes[index].select('
|
71
|
+
svg_nodes[index].select('ellipse')
|
72
72
|
.style("fill", "while")
|
73
73
|
.transition().duration(500)
|
74
74
|
.style("fill", "blue");
|
@@ -76,54 +76,79 @@ function highlight_finish(index) {
|
|
76
76
|
|
77
77
|
function match(input) {
|
78
78
|
reset_graph();
|
79
|
-
var table
|
80
|
-
var states
|
81
|
-
var regexp_states
|
82
|
-
var string_states
|
83
|
-
var
|
79
|
+
var table = tt();
|
80
|
+
var states = [[0, null]];
|
81
|
+
var regexp_states = table['regexp_states'];
|
82
|
+
var string_states = table['string_states'];
|
83
|
+
var stdparam_states = table['stdparam_states'];
|
84
|
+
var accepting = table['accepting'];
|
85
|
+
var default_re = new RegExp("^[^.\/?]+$");
|
86
|
+
var start_index = 0;
|
84
87
|
|
85
88
|
highlight_state(0);
|
86
89
|
|
87
90
|
tokenize(input, function(token) {
|
91
|
+
var end_index = start_index + token.length;
|
92
|
+
|
88
93
|
var new_states = [];
|
89
94
|
for(var key in states) {
|
90
|
-
var
|
95
|
+
var state_parts = states[key];
|
96
|
+
var state = state_parts[0];
|
97
|
+
var previous_start = state_parts[1];
|
98
|
+
|
99
|
+
if(previous_start == null) {
|
100
|
+
if(string_states[state] && string_states[state][token]) {
|
101
|
+
var new_state = string_states[state][token];
|
102
|
+
highlight_edge(state, new_state);
|
103
|
+
highlight_state(new_state);
|
104
|
+
new_states.push([new_state, null]);
|
105
|
+
}
|
91
106
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
107
|
+
if(stdparam_states[state] && default_re.test(token)) {
|
108
|
+
for(var key in stdparam_states[state]) {
|
109
|
+
var new_state = stdparam_states[state][key];
|
110
|
+
highlight_edge(state, new_state);
|
111
|
+
highlight_state(new_state);
|
112
|
+
new_states.push([new_state, null]);
|
113
|
+
}
|
114
|
+
}
|
97
115
|
}
|
98
116
|
|
99
117
|
if(regexp_states[state]) {
|
118
|
+
var slice_start = previous_start != null ? previous_start : start_index;
|
119
|
+
|
100
120
|
for(var key in regexp_states[state]) {
|
101
121
|
var re = new RegExp("^" + key + "$");
|
102
|
-
|
122
|
+
|
123
|
+
var accumulation = input.slice(slice_start, end_index);
|
124
|
+
|
125
|
+
if(re.test(accumulation)) {
|
103
126
|
var new_state = regexp_states[state][key];
|
104
127
|
highlight_edge(state, new_state);
|
105
128
|
highlight_state(new_state);
|
106
|
-
new_states.push(new_state);
|
129
|
+
new_states.push([new_state, null]);
|
107
130
|
}
|
131
|
+
|
132
|
+
// retry the same regexp with the accumulated data either way
|
133
|
+
new_states.push([state, slice_start]);
|
108
134
|
}
|
109
135
|
}
|
110
136
|
}
|
111
137
|
|
112
|
-
if(new_states.length == 0) {
|
113
|
-
return;
|
114
|
-
}
|
115
138
|
states = new_states;
|
139
|
+
start_index = end_index;
|
116
140
|
});
|
117
141
|
|
118
142
|
for(var key in states) {
|
119
|
-
var
|
143
|
+
var state_parts = states[key];
|
144
|
+
var state = state_parts[0];
|
145
|
+
var slice_start = state_parts[1];
|
146
|
+
|
147
|
+
// we must ignore ones that are still accepting more data
|
148
|
+
if (slice_start != null) continue;
|
149
|
+
|
120
150
|
if(accepting[state]) {
|
121
|
-
|
122
|
-
if(!regexp_states[mkey] && !string_states[mkey]) {
|
123
|
-
highlight_edge(state, mkey);
|
124
|
-
highlight_finish(mkey);
|
125
|
-
}
|
126
|
-
}
|
151
|
+
highlight_finish(state);
|
127
152
|
} else {
|
128
153
|
highlight_state(state, "red");
|
129
154
|
}
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<%= style %>
|
9
9
|
<% end %>
|
10
10
|
</style>
|
11
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"
|
11
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script>
|
12
12
|
</head>
|
13
13
|
<body>
|
14
14
|
<div id="wrapper">
|
@@ -7,7 +7,7 @@ require "active_support/json"
|
|
7
7
|
require "rack/utils"
|
8
8
|
|
9
9
|
module ActionDispatch
|
10
|
-
|
10
|
+
module RequestCookieMethods
|
11
11
|
def cookie_jar
|
12
12
|
fetch_header("action_dispatch.cookies") do
|
13
13
|
self.cookie_jar = Cookies::CookieJar.build(self, cookies)
|
@@ -88,6 +88,10 @@ module ActionDispatch
|
|
88
88
|
# :startdoc:
|
89
89
|
end
|
90
90
|
|
91
|
+
ActiveSupport.on_load(:action_dispatch_request) do
|
92
|
+
include RequestCookieMethods
|
93
|
+
end
|
94
|
+
|
91
95
|
# Read and write data to cookies through ActionController#cookies.
|
92
96
|
#
|
93
97
|
# When reading cookie data, the data is read from the HTTP request header, Cookie.
|
@@ -99,7 +103,7 @@ module ActionDispatch
|
|
99
103
|
# # This cookie will be deleted when the user's browser is closed.
|
100
104
|
# cookies[:user_name] = "david"
|
101
105
|
#
|
102
|
-
# # Cookie values are String
|
106
|
+
# # Cookie values are String-based. Other data types need to be serialized.
|
103
107
|
# cookies[:lat_lon] = JSON.generate([47.68, -122.37])
|
104
108
|
#
|
105
109
|
# # Sets a cookie that expires in 1 hour.
|
@@ -280,7 +284,7 @@ module ActionDispatch
|
|
280
284
|
end
|
281
285
|
end
|
282
286
|
|
283
|
-
class CookieJar
|
287
|
+
class CookieJar # :nodoc:
|
284
288
|
include Enumerable, ChainedCookieJars
|
285
289
|
|
286
290
|
# This regular expression is used to split the levels of a domain.
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "action_dispatch/http/request"
|
4
3
|
require "action_dispatch/middleware/exception_wrapper"
|
5
4
|
require "action_dispatch/routing/inspector"
|
6
5
|
|
@@ -135,6 +134,7 @@ module ActionDispatch
|
|
135
134
|
logger = logger(request)
|
136
135
|
|
137
136
|
return unless logger
|
137
|
+
return if !log_rescued_responses?(request) && wrapper.rescue_response?
|
138
138
|
|
139
139
|
exception = wrapper.exception
|
140
140
|
trace = wrapper.exception_trace
|
@@ -149,9 +149,7 @@ module ActionDispatch
|
|
149
149
|
log_array(logger, message)
|
150
150
|
end
|
151
151
|
|
152
|
-
def log_array(logger,
|
153
|
-
lines = Array(array)
|
154
|
-
|
152
|
+
def log_array(logger, lines)
|
155
153
|
return if lines.empty?
|
156
154
|
|
157
155
|
if logger.formatter && logger.formatter.respond_to?(:tags_text)
|
@@ -178,5 +176,9 @@ module ActionDispatch
|
|
178
176
|
def api_request?(content_type)
|
179
177
|
@response_format == :api && !content_type.html?
|
180
178
|
end
|
179
|
+
|
180
|
+
def log_rescued_responses?(request)
|
181
|
+
request.get_header("action_dispatch.log_rescued_responses")
|
182
|
+
end
|
181
183
|
end
|
182
184
|
end
|
@@ -9,9 +9,9 @@ module ActionDispatch
|
|
9
9
|
# config.middleware.insert_before Rack::Sendfile, ActionDispatch::DebugLocks
|
10
10
|
#
|
11
11
|
# After restarting the application and re-triggering the deadlock condition,
|
12
|
-
# <tt>/rails/locks</tt> will show a summary of all threads currently
|
13
|
-
# the interlock, which lock level they are holding or awaiting, and
|
14
|
-
# current backtrace.
|
12
|
+
# the route <tt>/rails/locks</tt> will show a summary of all threads currently
|
13
|
+
# known to the interlock, which lock level they are holding or awaiting, and
|
14
|
+
# their current backtrace.
|
15
15
|
#
|
16
16
|
# Generally a deadlock will be caused by the interlock conflicting with some
|
17
17
|
# other external lock or blocking I/O call. These cannot be automatically
|
@@ -118,6 +118,10 @@ module ActionDispatch
|
|
118
118
|
Rack::Utils.status_code(@@rescue_responses[class_name])
|
119
119
|
end
|
120
120
|
|
121
|
+
def rescue_response?
|
122
|
+
@@rescue_responses.key?(exception.class.name)
|
123
|
+
end
|
124
|
+
|
121
125
|
def source_extracts
|
122
126
|
backtrace.map do |trace|
|
123
127
|
file, line_number = extract_file_and_line_number(trace)
|
@@ -59,16 +59,14 @@ module ActionDispatch
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def commit_flash # :nodoc:
|
62
|
-
session
|
63
|
-
flash_hash = self.flash_hash
|
62
|
+
return unless session.enabled?
|
64
63
|
|
65
64
|
if flash_hash && (flash_hash.present? || session.key?("flash"))
|
66
65
|
session["flash"] = flash_hash.to_session_value
|
67
66
|
self.flash = flash_hash.dup
|
68
67
|
end
|
69
68
|
|
70
|
-
if
|
71
|
-
session.key?("flash") && session["flash"].nil?
|
69
|
+
if session.loaded? && session.key?("flash") && session["flash"].nil?
|
72
70
|
session.delete("flash")
|
73
71
|
end
|
74
72
|
end
|
@@ -79,7 +77,7 @@ module ActionDispatch
|
|
79
77
|
end
|
80
78
|
end
|
81
79
|
|
82
|
-
class FlashNow
|
80
|
+
class FlashNow # :nodoc:
|
83
81
|
attr_accessor :flash
|
84
82
|
|
85
83
|
def initialize(flash)
|
@@ -111,7 +109,7 @@ module ActionDispatch
|
|
111
109
|
class FlashHash
|
112
110
|
include Enumerable
|
113
111
|
|
114
|
-
def self.from_session_value(value)
|
112
|
+
def self.from_session_value(value) # :nodoc:
|
115
113
|
case value
|
116
114
|
when FlashHash # Rails 3.1, 3.2
|
117
115
|
flashes = value.instance_variable_get(:@flashes)
|
@@ -132,13 +130,13 @@ module ActionDispatch
|
|
132
130
|
|
133
131
|
# Builds a hash containing the flashes to keep for the next request.
|
134
132
|
# If there are none to keep, returns +nil+.
|
135
|
-
def to_session_value
|
133
|
+
def to_session_value # :nodoc:
|
136
134
|
flashes_to_keep = @flashes.except(*@discard)
|
137
135
|
return nil if flashes_to_keep.empty?
|
138
136
|
{ "discard" => [], "flashes" => flashes_to_keep }
|
139
137
|
end
|
140
138
|
|
141
|
-
def initialize(flashes = {}, discard = [])
|
139
|
+
def initialize(flashes = {}, discard = []) # :nodoc:
|
142
140
|
@discard = Set.new(stringify_array(discard))
|
143
141
|
@flashes = flashes.stringify_keys
|
144
142
|
@now = nil
|
@@ -162,7 +160,7 @@ module ActionDispatch
|
|
162
160
|
@flashes[k.to_s]
|
163
161
|
end
|
164
162
|
|
165
|
-
def update(h)
|
163
|
+
def update(h) # :nodoc:
|
166
164
|
@discard.subtract stringify_array(h.keys)
|
167
165
|
@flashes.update h.stringify_keys
|
168
166
|
self
|
@@ -202,7 +200,7 @@ module ActionDispatch
|
|
202
200
|
|
203
201
|
alias :merge! :update
|
204
202
|
|
205
|
-
def replace(h)
|
203
|
+
def replace(h) # :nodoc:
|
206
204
|
@discard.clear
|
207
205
|
@flashes.replace h.stringify_keys
|
208
206
|
self
|
@@ -253,7 +251,7 @@ module ActionDispatch
|
|
253
251
|
# Mark for removal entries that were kept, and delete unkept ones.
|
254
252
|
#
|
255
253
|
# This method is called automatically by filters, so you generally don't need to care about it.
|
256
|
-
def sweep
|
254
|
+
def sweep # :nodoc:
|
257
255
|
@discard.each { |k| @flashes.delete k }
|
258
256
|
@discard.replace @flashes.keys
|
259
257
|
end
|