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.

Files changed (125) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +379 -462
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller.rb +0 -2
  6. data/lib/abstract_controller/base.rb +17 -32
  7. data/lib/abstract_controller/callbacks.rb +52 -19
  8. data/lib/abstract_controller/collector.rb +4 -9
  9. data/lib/abstract_controller/helpers.rb +2 -2
  10. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  11. data/lib/abstract_controller/rendering.rb +27 -22
  12. data/lib/abstract_controller/translation.rb +8 -7
  13. data/lib/action_controller.rb +4 -3
  14. data/lib/action_controller/api.rb +146 -0
  15. data/lib/action_controller/base.rb +6 -10
  16. data/lib/action_controller/caching.rb +1 -3
  17. data/lib/action_controller/caching/fragments.rb +48 -3
  18. data/lib/action_controller/form_builder.rb +48 -0
  19. data/lib/action_controller/log_subscriber.rb +1 -10
  20. data/lib/action_controller/metal.rb +89 -62
  21. data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
  22. data/lib/action_controller/metal/conditional_get.rb +65 -24
  23. data/lib/action_controller/metal/cookies.rb +0 -2
  24. data/lib/action_controller/metal/data_streaming.rb +2 -22
  25. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  26. data/lib/action_controller/metal/exceptions.rb +11 -6
  27. data/lib/action_controller/metal/force_ssl.rb +6 -6
  28. data/lib/action_controller/metal/head.rb +14 -7
  29. data/lib/action_controller/metal/helpers.rb +9 -5
  30. data/lib/action_controller/metal/http_authentication.rb +37 -38
  31. data/lib/action_controller/metal/implicit_render.rb +23 -6
  32. data/lib/action_controller/metal/instrumentation.rb +0 -1
  33. data/lib/action_controller/metal/live.rb +17 -55
  34. data/lib/action_controller/metal/mime_responds.rb +17 -37
  35. data/lib/action_controller/metal/params_wrapper.rb +8 -8
  36. data/lib/action_controller/metal/redirecting.rb +32 -9
  37. data/lib/action_controller/metal/renderers.rb +10 -8
  38. data/lib/action_controller/metal/rendering.rb +38 -6
  39. data/lib/action_controller/metal/request_forgery_protection.rb +67 -35
  40. data/lib/action_controller/metal/rescue.rb +2 -4
  41. data/lib/action_controller/metal/streaming.rb +4 -4
  42. data/lib/action_controller/metal/strong_parameters.rb +231 -78
  43. data/lib/action_controller/metal/testing.rb +1 -12
  44. data/lib/action_controller/metal/url_for.rb +12 -5
  45. data/lib/action_controller/renderer.rb +111 -0
  46. data/lib/action_controller/template_assertions.rb +9 -0
  47. data/lib/action_controller/test_case.rb +267 -363
  48. data/lib/action_dispatch.rb +2 -1
  49. data/lib/action_dispatch/http/cache.rb +23 -26
  50. data/lib/action_dispatch/http/filter_parameters.rb +6 -8
  51. data/lib/action_dispatch/http/filter_redirect.rb +7 -8
  52. data/lib/action_dispatch/http/headers.rb +28 -11
  53. data/lib/action_dispatch/http/mime_negotiation.rb +40 -26
  54. data/lib/action_dispatch/http/mime_type.rb +92 -61
  55. data/lib/action_dispatch/http/mime_types.rb +1 -4
  56. data/lib/action_dispatch/http/parameter_filter.rb +18 -8
  57. data/lib/action_dispatch/http/parameters.rb +45 -41
  58. data/lib/action_dispatch/http/request.rb +146 -82
  59. data/lib/action_dispatch/http/response.rb +180 -99
  60. data/lib/action_dispatch/http/url.rb +117 -8
  61. data/lib/action_dispatch/journey/formatter.rb +34 -28
  62. data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
  63. data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
  64. data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
  65. data/lib/action_dispatch/journey/nodes/node.rb +14 -4
  66. data/lib/action_dispatch/journey/parser_extras.rb +4 -0
  67. data/lib/action_dispatch/journey/path/pattern.rb +37 -41
  68. data/lib/action_dispatch/journey/route.rb +71 -17
  69. data/lib/action_dispatch/journey/router.rb +5 -6
  70. data/lib/action_dispatch/journey/router/utils.rb +5 -5
  71. data/lib/action_dispatch/journey/routes.rb +14 -15
  72. data/lib/action_dispatch/journey/visitors.rb +86 -43
  73. data/lib/action_dispatch/middleware/cookies.rb +184 -135
  74. data/lib/action_dispatch/middleware/debug_exceptions.rb +115 -45
  75. data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -20
  76. data/lib/action_dispatch/middleware/flash.rb +61 -45
  77. data/lib/action_dispatch/middleware/load_interlock.rb +21 -0
  78. data/lib/action_dispatch/middleware/params_parser.rb +30 -46
  79. data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
  80. data/lib/action_dispatch/middleware/reloader.rb +2 -4
  81. data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
  82. data/lib/action_dispatch/middleware/request_id.rb +11 -6
  83. data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
  84. data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
  85. data/lib/action_dispatch/middleware/session/cookie_store.rb +29 -23
  86. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
  87. data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
  88. data/lib/action_dispatch/middleware/ssl.rb +93 -36
  89. data/lib/action_dispatch/middleware/stack.rb +43 -48
  90. data/lib/action_dispatch/middleware/static.rb +52 -40
  91. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  92. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  95. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  96. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  97. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
  98. data/lib/action_dispatch/railtie.rb +0 -2
  99. data/lib/action_dispatch/request/session.rb +66 -34
  100. data/lib/action_dispatch/request/utils.rb +51 -19
  101. data/lib/action_dispatch/routing.rb +3 -8
  102. data/lib/action_dispatch/routing/inspector.rb +6 -30
  103. data/lib/action_dispatch/routing/mapper.rb +447 -322
  104. data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
  105. data/lib/action_dispatch/routing/redirection.rb +3 -3
  106. data/lib/action_dispatch/routing/route_set.rb +124 -227
  107. data/lib/action_dispatch/routing/url_for.rb +27 -10
  108. data/lib/action_dispatch/testing/assertions.rb +1 -1
  109. data/lib/action_dispatch/testing/assertions/response.rb +27 -9
  110. data/lib/action_dispatch/testing/assertions/routing.rb +9 -9
  111. data/lib/action_dispatch/testing/integration.rb +237 -76
  112. data/lib/action_dispatch/testing/test_process.rb +5 -5
  113. data/lib/action_dispatch/testing/test_request.rb +12 -21
  114. data/lib/action_dispatch/testing/test_response.rb +1 -4
  115. data/lib/action_pack.rb +1 -1
  116. data/lib/action_pack/gem_version.rb +4 -4
  117. metadata +26 -25
  118. data/lib/action_controller/metal/hide_actions.rb +0 -40
  119. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  120. data/lib/action_controller/middleware.rb +0 -39
  121. data/lib/action_controller/model_naming.rb +0 -12
  122. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  123. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  124. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  125. 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
- def initialize(app, routes_app = nil)
12
- @app = app
13
- @routes_app = routes_app
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 if env['action_dispatch.show_exceptions'] == false
27
- render_exception(env, 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(env, exception)
33
- wrapper = ExceptionWrapper.new(env, exception)
34
- log_error(env, wrapper)
35
-
36
- if env['action_dispatch.show_detailed_exceptions']
37
- request = Request.new(env)
38
- traces = wrapper.traces
39
-
40
- trace_to_show = 'Application Trace'
41
- if traces[trace_to_show].empty? && wrapper.rescue_template != 'routing_error'
42
- trace_to_show = 'Full Trace'
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
- if source_to_show = traces[trace_to_show].first
46
- source_to_show_id = source_to_show[:id]
47
- end
81
+ def render_for_default_application(request, wrapper)
82
+ template = create_template(request, wrapper)
83
+ file = "rescues/#{wrapper.rescue_template}"
48
84
 
49
- template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
50
- request: request,
51
- exception: wrapper.exception,
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
- raise exception
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(env, wrapper)
80
- logger = logger(env)
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(env)
97
- env['action_dispatch.logger'] || stderr_logger
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 :env, :exception, :line_number, :file
34
+ attr_reader :backtrace_cleaner, :exception, :line_number, :file
32
35
 
33
- def initialize(env, exception)
34
- @env = env
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.try(:original_exception).try(:is_a?, SyntaxError)
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
- appplication_trace_with_ids = []
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
- appplication_trace_with_ids << trace_with_id
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" => appplication_trace_with_ids,
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, line = trace.split(":")
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 registered_original_exception?(exception)
108
- exception.original_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
- flash = case value
84
- when FlashHash # Rails 3.1, 3.2
85
- new(value.instance_variable_get(:@flashes), value.instance_variable_get(:@used))
86
- when Hash # Rails 4.0
87
- new(value['flashes'], value['discard'])
88
- else
89
- new
90
- end
91
-
92
- flash.tap(&:sweep)
93
- end
94
-
95
- # Builds a hash containing the discarded values and the hashes
96
- # representing the flashes.
97
- # If there are no values in @flashes, returns nil.
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
- return nil if empty?
100
- {'discard' => @discard.to_a, 'flashes' => @flashes}
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 initialize(app)
256
- @app = app
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
- if (!session.respond_to?(:loaded?) || session.loaded?) && # (reset_session uses {}, which doesn't implement #loaded?)
271
- session.key?('flash') && session['flash'].nil?
272
- session.delete('flash')
273
- end
274
- end
289
+ class Request
290
+ prepend Flash::RequestMethods
275
291
  end
276
292
  end