actionpack 4.2.11.3 → 5.0.0.beta1
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 +379 -462
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller.rb +0 -2
- data/lib/abstract_controller/base.rb +17 -32
- data/lib/abstract_controller/callbacks.rb +52 -19
- data/lib/abstract_controller/collector.rb +4 -9
- data/lib/abstract_controller/helpers.rb +2 -2
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +27 -22
- data/lib/abstract_controller/translation.rb +8 -7
- data/lib/action_controller.rb +4 -3
- data/lib/action_controller/api.rb +146 -0
- data/lib/action_controller/base.rb +6 -10
- data/lib/action_controller/caching.rb +1 -3
- data/lib/action_controller/caching/fragments.rb +48 -3
- data/lib/action_controller/form_builder.rb +48 -0
- data/lib/action_controller/log_subscriber.rb +1 -10
- data/lib/action_controller/metal.rb +89 -62
- data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
- data/lib/action_controller/metal/conditional_get.rb +65 -24
- data/lib/action_controller/metal/cookies.rb +0 -2
- data/lib/action_controller/metal/data_streaming.rb +2 -22
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +11 -6
- data/lib/action_controller/metal/force_ssl.rb +6 -6
- data/lib/action_controller/metal/head.rb +14 -7
- data/lib/action_controller/metal/helpers.rb +9 -5
- data/lib/action_controller/metal/http_authentication.rb +37 -38
- data/lib/action_controller/metal/implicit_render.rb +23 -6
- data/lib/action_controller/metal/instrumentation.rb +0 -1
- data/lib/action_controller/metal/live.rb +17 -55
- data/lib/action_controller/metal/mime_responds.rb +17 -37
- data/lib/action_controller/metal/params_wrapper.rb +8 -8
- data/lib/action_controller/metal/redirecting.rb +32 -9
- data/lib/action_controller/metal/renderers.rb +10 -8
- data/lib/action_controller/metal/rendering.rb +38 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +67 -35
- data/lib/action_controller/metal/rescue.rb +2 -4
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +231 -78
- data/lib/action_controller/metal/testing.rb +1 -12
- data/lib/action_controller/metal/url_for.rb +12 -5
- data/lib/action_controller/renderer.rb +111 -0
- data/lib/action_controller/template_assertions.rb +9 -0
- data/lib/action_controller/test_case.rb +267 -363
- data/lib/action_dispatch.rb +2 -1
- data/lib/action_dispatch/http/cache.rb +23 -26
- data/lib/action_dispatch/http/filter_parameters.rb +6 -8
- data/lib/action_dispatch/http/filter_redirect.rb +7 -8
- data/lib/action_dispatch/http/headers.rb +28 -11
- data/lib/action_dispatch/http/mime_negotiation.rb +40 -26
- data/lib/action_dispatch/http/mime_type.rb +92 -61
- data/lib/action_dispatch/http/mime_types.rb +1 -4
- data/lib/action_dispatch/http/parameter_filter.rb +18 -8
- data/lib/action_dispatch/http/parameters.rb +45 -41
- data/lib/action_dispatch/http/request.rb +146 -82
- data/lib/action_dispatch/http/response.rb +180 -99
- data/lib/action_dispatch/http/url.rb +117 -8
- data/lib/action_dispatch/journey/formatter.rb +34 -28
- 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_extras.rb +4 -0
- data/lib/action_dispatch/journey/path/pattern.rb +37 -41
- data/lib/action_dispatch/journey/route.rb +71 -17
- data/lib/action_dispatch/journey/router.rb +5 -6
- data/lib/action_dispatch/journey/router/utils.rb +5 -5
- data/lib/action_dispatch/journey/routes.rb +14 -15
- data/lib/action_dispatch/journey/visitors.rb +86 -43
- data/lib/action_dispatch/middleware/cookies.rb +184 -135
- data/lib/action_dispatch/middleware/debug_exceptions.rb +115 -45
- data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -20
- data/lib/action_dispatch/middleware/flash.rb +61 -45
- data/lib/action_dispatch/middleware/load_interlock.rb +21 -0
- data/lib/action_dispatch/middleware/params_parser.rb +30 -46
- data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +2 -4
- 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 +29 -23
- 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 +93 -36
- data/lib/action_dispatch/middleware/stack.rb +43 -48
- data/lib/action_dispatch/middleware/static.rb +52 -40
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
- 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 +0 -2
- data/lib/action_dispatch/request/session.rb +66 -34
- data/lib/action_dispatch/request/utils.rb +51 -19
- data/lib/action_dispatch/routing.rb +3 -8
- data/lib/action_dispatch/routing/inspector.rb +6 -30
- data/lib/action_dispatch/routing/mapper.rb +447 -322
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
- data/lib/action_dispatch/routing/redirection.rb +3 -3
- data/lib/action_dispatch/routing/route_set.rb +124 -227
- data/lib/action_dispatch/routing/url_for.rb +27 -10
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +27 -9
- data/lib/action_dispatch/testing/assertions/routing.rb +9 -9
- data/lib/action_dispatch/testing/integration.rb +237 -76
- data/lib/action_dispatch/testing/test_process.rb +5 -5
- data/lib/action_dispatch/testing/test_request.rb +12 -21
- data/lib/action_dispatch/testing/test_response.rb +1 -4
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- metadata +26 -25
- 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/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
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'action_dispatch/http/request'
|
2
2
|
require 'action_dispatch/middleware/exception_wrapper'
|
3
3
|
require 'action_dispatch/routing/inspector'
|
4
|
+
require 'action_view'
|
5
|
+
require 'action_view/base'
|
6
|
+
|
7
|
+
require 'pp'
|
4
8
|
|
5
9
|
module ActionDispatch
|
6
10
|
# This middleware is responsible for logging exceptions and
|
@@ -8,12 +12,40 @@ module ActionDispatch
|
|
8
12
|
class DebugExceptions
|
9
13
|
RESCUES_TEMPLATE_PATH = File.expand_path('../templates', __FILE__)
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
class DebugView < ActionView::Base
|
16
|
+
def debug_params(params)
|
17
|
+
clean_params = params.clone
|
18
|
+
clean_params.delete("action")
|
19
|
+
clean_params.delete("controller")
|
20
|
+
|
21
|
+
if clean_params.empty?
|
22
|
+
'None'
|
23
|
+
else
|
24
|
+
PP.pp(clean_params, "", 200)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def debug_headers(headers)
|
29
|
+
if headers.present?
|
30
|
+
headers.inspect.gsub(',', ",\n")
|
31
|
+
else
|
32
|
+
'None'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def debug_hash(object)
|
37
|
+
object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(app, routes_app = nil, response_format = :default)
|
42
|
+
@app = app
|
43
|
+
@routes_app = routes_app
|
44
|
+
@response_format = response_format
|
14
45
|
end
|
15
46
|
|
16
47
|
def call(env)
|
48
|
+
request = ActionDispatch::Request.new env
|
17
49
|
_, headers, body = response = @app.call(env)
|
18
50
|
|
19
51
|
if headers['X-Cascade'] == 'pass'
|
@@ -23,61 +55,99 @@ module ActionDispatch
|
|
23
55
|
|
24
56
|
response
|
25
57
|
rescue Exception => exception
|
26
|
-
raise exception
|
27
|
-
render_exception(
|
58
|
+
raise exception unless request.show_exceptions?
|
59
|
+
render_exception(request, exception)
|
28
60
|
end
|
29
61
|
|
30
62
|
private
|
31
63
|
|
32
|
-
def render_exception(
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
64
|
+
def render_exception(request, exception)
|
65
|
+
backtrace_cleaner = request.get_header('action_dispatch.backtrace_cleaner')
|
66
|
+
wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
|
67
|
+
log_error(request, wrapper)
|
68
|
+
|
69
|
+
if request.get_header('action_dispatch.show_detailed_exceptions')
|
70
|
+
case @response_format
|
71
|
+
when :api
|
72
|
+
render_for_api_application(request, wrapper)
|
73
|
+
when :default
|
74
|
+
render_for_default_application(request, wrapper)
|
43
75
|
end
|
76
|
+
else
|
77
|
+
raise exception
|
78
|
+
end
|
79
|
+
end
|
44
80
|
|
45
|
-
|
46
|
-
|
47
|
-
|
81
|
+
def render_for_default_application(request, wrapper)
|
82
|
+
template = create_template(request, wrapper)
|
83
|
+
file = "rescues/#{wrapper.rescue_template}"
|
48
84
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
traces: traces,
|
53
|
-
show_source_idx: source_to_show_id,
|
54
|
-
trace_to_show: trace_to_show,
|
55
|
-
routes_inspector: routes_inspector(exception),
|
56
|
-
source_extracts: wrapper.source_extracts,
|
57
|
-
line_number: wrapper.line_number,
|
58
|
-
file: wrapper.file
|
59
|
-
)
|
60
|
-
file = "rescues/#{wrapper.rescue_template}"
|
61
|
-
|
62
|
-
if request.xhr?
|
63
|
-
body = template.render(template: file, layout: false, formats: [:text])
|
64
|
-
format = "text/plain"
|
65
|
-
else
|
66
|
-
body = template.render(template: file, layout: 'rescues/layout')
|
67
|
-
format = "text/html"
|
68
|
-
end
|
69
|
-
render(wrapper.status_code, body, format)
|
85
|
+
if request.xhr?
|
86
|
+
body = template.render(template: file, layout: false, formats: [:text])
|
87
|
+
format = "text/plain"
|
70
88
|
else
|
71
|
-
|
89
|
+
body = template.render(template: file, layout: 'rescues/layout')
|
90
|
+
format = "text/html"
|
91
|
+
end
|
92
|
+
render(wrapper.status_code, body, format)
|
93
|
+
end
|
94
|
+
|
95
|
+
def render_for_api_application(request, wrapper)
|
96
|
+
body = {
|
97
|
+
status: wrapper.status_code,
|
98
|
+
error: Rack::Utils::HTTP_STATUS_CODES.fetch(
|
99
|
+
wrapper.status_code,
|
100
|
+
Rack::Utils::HTTP_STATUS_CODES[500]
|
101
|
+
),
|
102
|
+
exception: wrapper.exception.inspect,
|
103
|
+
traces: wrapper.traces
|
104
|
+
}
|
105
|
+
|
106
|
+
content_type = request.formats.first
|
107
|
+
to_format = "to_#{content_type.to_sym}"
|
108
|
+
|
109
|
+
if content_type && body.respond_to?(to_format)
|
110
|
+
formatted_body = body.public_send(to_format)
|
111
|
+
format = content_type
|
112
|
+
else
|
113
|
+
formatted_body = body.to_json
|
114
|
+
format = Mime[:json]
|
72
115
|
end
|
116
|
+
|
117
|
+
render(wrapper.status_code, formatted_body, format)
|
118
|
+
end
|
119
|
+
|
120
|
+
def create_template(request, wrapper)
|
121
|
+
traces = wrapper.traces
|
122
|
+
|
123
|
+
trace_to_show = 'Application Trace'
|
124
|
+
if traces[trace_to_show].empty? && wrapper.rescue_template != 'routing_error'
|
125
|
+
trace_to_show = 'Full Trace'
|
126
|
+
end
|
127
|
+
|
128
|
+
if source_to_show = traces[trace_to_show].first
|
129
|
+
source_to_show_id = source_to_show[:id]
|
130
|
+
end
|
131
|
+
|
132
|
+
DebugView.new([RESCUES_TEMPLATE_PATH],
|
133
|
+
request: request,
|
134
|
+
exception: wrapper.exception,
|
135
|
+
traces: traces,
|
136
|
+
show_source_idx: source_to_show_id,
|
137
|
+
trace_to_show: trace_to_show,
|
138
|
+
routes_inspector: routes_inspector(wrapper.exception),
|
139
|
+
source_extracts: wrapper.source_extracts,
|
140
|
+
line_number: wrapper.line_number,
|
141
|
+
file: wrapper.file
|
142
|
+
)
|
73
143
|
end
|
74
144
|
|
75
145
|
def render(status, body, format)
|
76
146
|
[status, {'Content-Type' => "#{format}; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
|
77
147
|
end
|
78
148
|
|
79
|
-
def log_error(
|
80
|
-
logger = logger(
|
149
|
+
def log_error(request, wrapper)
|
150
|
+
logger = logger(request)
|
81
151
|
return unless logger
|
82
152
|
|
83
153
|
exception = wrapper.exception
|
@@ -93,8 +163,8 @@ module ActionDispatch
|
|
93
163
|
end
|
94
164
|
end
|
95
165
|
|
96
|
-
def logger(
|
97
|
-
|
166
|
+
def logger(request)
|
167
|
+
request.logger || stderr_logger
|
98
168
|
end
|
99
169
|
|
100
170
|
def stderr_logger
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'action_controller/metal/exceptions'
|
2
2
|
require 'active_support/core_ext/module/attribute_accessors'
|
3
|
+
require 'rack/utils'
|
3
4
|
|
4
5
|
module ActionDispatch
|
5
6
|
class ExceptionWrapper
|
@@ -16,7 +17,9 @@ module ActionDispatch
|
|
16
17
|
'ActionController::InvalidCrossOriginRequest' => :unprocessable_entity,
|
17
18
|
'ActionDispatch::ParamsParser::ParseError' => :bad_request,
|
18
19
|
'ActionController::BadRequest' => :bad_request,
|
19
|
-
'ActionController::ParameterMissing' => :bad_request
|
20
|
+
'ActionController::ParameterMissing' => :bad_request,
|
21
|
+
'Rack::Utils::ParameterTypeError' => :bad_request,
|
22
|
+
'Rack::Utils::InvalidParameterError' => :bad_request
|
20
23
|
)
|
21
24
|
|
22
25
|
cattr_accessor :rescue_templates
|
@@ -28,13 +31,13 @@ module ActionDispatch
|
|
28
31
|
'ActionView::Template::Error' => 'template_error'
|
29
32
|
)
|
30
33
|
|
31
|
-
attr_reader :
|
34
|
+
attr_reader :backtrace_cleaner, :exception, :line_number, :file
|
32
35
|
|
33
|
-
def initialize(
|
34
|
-
@
|
36
|
+
def initialize(backtrace_cleaner, exception)
|
37
|
+
@backtrace_cleaner = backtrace_cleaner
|
35
38
|
@exception = original_exception(exception)
|
36
39
|
|
37
|
-
expand_backtrace if exception.is_a?(SyntaxError) || exception.
|
40
|
+
expand_backtrace if exception.is_a?(SyntaxError) || exception.cause.is_a?(SyntaxError)
|
38
41
|
end
|
39
42
|
|
40
43
|
def rescue_template
|
@@ -58,7 +61,7 @@ module ActionDispatch
|
|
58
61
|
end
|
59
62
|
|
60
63
|
def traces
|
61
|
-
|
64
|
+
application_trace_with_ids = []
|
62
65
|
framework_trace_with_ids = []
|
63
66
|
full_trace_with_ids = []
|
64
67
|
|
@@ -66,7 +69,7 @@ module ActionDispatch
|
|
66
69
|
trace_with_id = { id: idx, trace: trace }
|
67
70
|
|
68
71
|
if application_trace.include?(trace)
|
69
|
-
|
72
|
+
application_trace_with_ids << trace_with_id
|
70
73
|
else
|
71
74
|
framework_trace_with_ids << trace_with_id
|
72
75
|
end
|
@@ -75,7 +78,7 @@ module ActionDispatch
|
|
75
78
|
end
|
76
79
|
|
77
80
|
{
|
78
|
-
"Application Trace" =>
|
81
|
+
"Application Trace" => application_trace_with_ids,
|
79
82
|
"Framework Trace" => framework_trace_with_ids,
|
80
83
|
"Full Trace" => full_trace_with_ids
|
81
84
|
}
|
@@ -87,8 +90,7 @@ module ActionDispatch
|
|
87
90
|
|
88
91
|
def source_extracts
|
89
92
|
backtrace.map do |trace|
|
90
|
-
file,
|
91
|
-
line_number = line.to_i
|
93
|
+
file, line_number = extract_file_and_line_number(trace)
|
92
94
|
|
93
95
|
{
|
94
96
|
code: source_fragment(file, line_number),
|
@@ -104,17 +106,13 @@ module ActionDispatch
|
|
104
106
|
end
|
105
107
|
|
106
108
|
def original_exception(exception)
|
107
|
-
if
|
108
|
-
exception.
|
109
|
+
if @@rescue_responses.has_key?(exception.cause.class.name)
|
110
|
+
exception.cause
|
109
111
|
else
|
110
112
|
exception
|
111
113
|
end
|
112
114
|
end
|
113
115
|
|
114
|
-
def registered_original_exception?(exception)
|
115
|
-
exception.respond_to?(:original_exception) && @@rescue_responses.has_key?(exception.original_exception.class.name)
|
116
|
-
end
|
117
|
-
|
118
116
|
def clean_backtrace(*args)
|
119
117
|
if backtrace_cleaner
|
120
118
|
backtrace_cleaner.clean(backtrace, *args)
|
@@ -123,10 +121,6 @@ module ActionDispatch
|
|
123
121
|
end
|
124
122
|
end
|
125
123
|
|
126
|
-
def backtrace_cleaner
|
127
|
-
@backtrace_cleaner ||= @env['action_dispatch.backtrace_cleaner']
|
128
|
-
end
|
129
|
-
|
130
124
|
def source_fragment(path, line)
|
131
125
|
return unless Rails.respond_to?(:root) && Rails.root
|
132
126
|
full_path = Rails.root.join(path)
|
@@ -139,6 +133,13 @@ module ActionDispatch
|
|
139
133
|
end
|
140
134
|
end
|
141
135
|
|
136
|
+
def extract_file_and_line_number(trace)
|
137
|
+
# Split by the first colon followed by some digits, which works for both
|
138
|
+
# Windows and Unix path styles.
|
139
|
+
file, line = trace.match(/^(.+?):(\d+).*$/, &:captures) || trace
|
140
|
+
[file, line.to_i]
|
141
|
+
end
|
142
|
+
|
142
143
|
def expand_backtrace
|
143
144
|
@exception.backtrace.unshift(
|
144
145
|
@exception.to_s.split("\n")
|
@@ -1,15 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/hash/keys'
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
|
-
class Request < Rack::Request
|
5
|
-
# Access the contents of the flash. Use <tt>flash["notice"]</tt> to
|
6
|
-
# read a notice you put there or <tt>flash["notice"] = "hello"</tt>
|
7
|
-
# to put a new one.
|
8
|
-
def flash
|
9
|
-
@env[Flash::KEY] ||= Flash::FlashHash.from_session_value(session["flash"])
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
4
|
# The flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed
|
14
5
|
# to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
|
15
6
|
# action that sets <tt>flash[:notice] = "Post successfully created"</tt> before redirecting to a display action that can
|
@@ -47,6 +38,40 @@ module ActionDispatch
|
|
47
38
|
class Flash
|
48
39
|
KEY = 'action_dispatch.request.flash_hash'.freeze
|
49
40
|
|
41
|
+
module RequestMethods
|
42
|
+
# Access the contents of the flash. Use <tt>flash["notice"]</tt> to
|
43
|
+
# read a notice you put there or <tt>flash["notice"] = "hello"</tt>
|
44
|
+
# to put a new one.
|
45
|
+
def flash
|
46
|
+
flash = flash_hash
|
47
|
+
return flash if flash
|
48
|
+
self.flash = Flash::FlashHash.from_session_value(session["flash"])
|
49
|
+
end
|
50
|
+
|
51
|
+
def flash=(flash)
|
52
|
+
set_header Flash::KEY, flash
|
53
|
+
end
|
54
|
+
|
55
|
+
def flash_hash # :nodoc:
|
56
|
+
get_header Flash::KEY
|
57
|
+
end
|
58
|
+
|
59
|
+
def commit_flash # :nodoc:
|
60
|
+
session = self.session || {}
|
61
|
+
flash_hash = self.flash_hash
|
62
|
+
|
63
|
+
if flash_hash && (flash_hash.present? || session.key?('flash'))
|
64
|
+
session["flash"] = flash_hash.to_session_value
|
65
|
+
self.flash = flash_hash.dup
|
66
|
+
end
|
67
|
+
|
68
|
+
if (!session.respond_to?(:loaded?) || session.loaded?) && # (reset_session uses {}, which doesn't implement #loaded?)
|
69
|
+
session.key?('flash') && session['flash'].nil?
|
70
|
+
session.delete('flash')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
50
75
|
class FlashNow #:nodoc:
|
51
76
|
attr_accessor :flash
|
52
77
|
|
@@ -80,24 +105,30 @@ module ActionDispatch
|
|
80
105
|
include Enumerable
|
81
106
|
|
82
107
|
def self.from_session_value(value) #:nodoc:
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
108
|
+
case value
|
109
|
+
when FlashHash # Rails 3.1, 3.2
|
110
|
+
flashes = value.instance_variable_get(:@flashes)
|
111
|
+
if discard = value.instance_variable_get(:@used)
|
112
|
+
flashes.except!(*discard)
|
113
|
+
end
|
114
|
+
new(flashes, flashes.keys)
|
115
|
+
when Hash # Rails 4.0
|
116
|
+
flashes = value['flashes']
|
117
|
+
if discard = value['discard']
|
118
|
+
flashes.except!(*discard)
|
119
|
+
end
|
120
|
+
new(flashes, flashes.keys)
|
121
|
+
else
|
122
|
+
new
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Builds a hash containing the flashes to keep for the next request.
|
127
|
+
# If there are none to keep, returns nil.
|
98
128
|
def to_session_value #:nodoc:
|
99
|
-
|
100
|
-
|
129
|
+
flashes_to_keep = @flashes.except(*@discard)
|
130
|
+
return nil if flashes_to_keep.empty?
|
131
|
+
{'flashes' => flashes_to_keep}
|
101
132
|
end
|
102
133
|
|
103
134
|
def initialize(flashes = {}, discard = []) #:nodoc:
|
@@ -252,25 +283,10 @@ module ActionDispatch
|
|
252
283
|
end
|
253
284
|
end
|
254
285
|
|
255
|
-
def
|
256
|
-
|
257
|
-
end
|
258
|
-
|
259
|
-
def call(env)
|
260
|
-
@app.call(env)
|
261
|
-
ensure
|
262
|
-
session = Request::Session.find(env) || {}
|
263
|
-
flash_hash = env[KEY]
|
264
|
-
|
265
|
-
if flash_hash && (flash_hash.present? || session.key?('flash'))
|
266
|
-
session["flash"] = flash_hash.to_session_value
|
267
|
-
env[KEY] = flash_hash.dup
|
268
|
-
end
|
286
|
+
def self.new(app) app; end
|
287
|
+
end
|
269
288
|
|
270
|
-
|
271
|
-
|
272
|
-
session.delete('flash')
|
273
|
-
end
|
274
|
-
end
|
289
|
+
class Request
|
290
|
+
prepend Flash::RequestMethods
|
275
291
|
end
|
276
292
|
end
|