actionpack 3.2.22.5 → 5.2.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (271) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +279 -603
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -297
  5. data/lib/abstract_controller/asset_paths.rb +4 -2
  6. data/lib/abstract_controller/base.rb +82 -52
  7. data/lib/abstract_controller/caching/fragments.rb +166 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +117 -103
  10. data/lib/abstract_controller/collector.rb +18 -7
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +65 -38
  13. data/lib/abstract_controller/logger.rb +3 -2
  14. data/lib/abstract_controller/railties/routes_helpers.rb +5 -3
  15. data/lib/abstract_controller/rendering.rb +77 -129
  16. data/lib/abstract_controller/translation.rb +21 -3
  17. data/lib/abstract_controller/url_for.rb +9 -7
  18. data/lib/abstract_controller.rb +12 -13
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/base.rb +81 -40
  22. data/lib/action_controller/caching.rb +22 -62
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +30 -18
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +190 -47
  27. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  28. data/lib/action_controller/metal/cookies.rb +3 -3
  29. data/lib/action_controller/metal/data_streaming.rb +40 -65
  30. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  31. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  32. data/lib/action_controller/metal/exceptions.rb +19 -12
  33. data/lib/action_controller/metal/flash.rb +42 -9
  34. data/lib/action_controller/metal/force_ssl.rb +79 -19
  35. data/lib/action_controller/metal/head.rb +35 -10
  36. data/lib/action_controller/metal/helpers.rb +31 -21
  37. data/lib/action_controller/metal/http_authentication.rb +182 -134
  38. data/lib/action_controller/metal/implicit_render.rb +62 -8
  39. data/lib/action_controller/metal/instrumentation.rb +28 -26
  40. data/lib/action_controller/metal/live.rb +312 -0
  41. data/lib/action_controller/metal/mime_responds.rb +159 -163
  42. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  43. data/lib/action_controller/metal/params_wrapper.rb +146 -93
  44. data/lib/action_controller/metal/redirecting.rb +80 -56
  45. data/lib/action_controller/metal/renderers.rb +119 -47
  46. data/lib/action_controller/metal/rendering.rb +89 -32
  47. data/lib/action_controller/metal/request_forgery_protection.rb +373 -41
  48. data/lib/action_controller/metal/rescue.rb +9 -16
  49. data/lib/action_controller/metal/streaming.rb +39 -45
  50. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  51. data/lib/action_controller/metal/testing.rb +8 -29
  52. data/lib/action_controller/metal/url_for.rb +43 -32
  53. data/lib/action_controller/metal.rb +112 -106
  54. data/lib/action_controller/railtie.rb +56 -18
  55. data/lib/action_controller/railties/helpers.rb +24 -0
  56. data/lib/action_controller/renderer.rb +117 -0
  57. data/lib/action_controller/template_assertions.rb +11 -0
  58. data/lib/action_controller/test_case.rb +402 -347
  59. data/lib/action_controller.rb +31 -30
  60. data/lib/action_dispatch/http/cache.rb +133 -34
  61. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +40 -24
  63. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  64. data/lib/action_dispatch/http/headers.rb +117 -16
  65. data/lib/action_dispatch/http/mime_negotiation.rb +98 -33
  66. data/lib/action_dispatch/http/mime_type.rb +198 -146
  67. data/lib/action_dispatch/http/mime_types.rb +22 -7
  68. data/lib/action_dispatch/http/parameter_filter.rb +61 -49
  69. data/lib/action_dispatch/http/parameters.rb +94 -51
  70. data/lib/action_dispatch/http/rack_cache.rb +4 -3
  71. data/lib/action_dispatch/http/request.rb +262 -117
  72. data/lib/action_dispatch/http/response.rb +400 -86
  73. data/lib/action_dispatch/http/upload.rb +66 -29
  74. data/lib/action_dispatch/http/url.rb +232 -60
  75. data/lib/action_dispatch/journey/formatter.rb +189 -0
  76. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  77. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  78. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  79. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  80. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  81. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  82. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  83. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  84. data/lib/action_dispatch/journey/parser.rb +199 -0
  85. data/lib/action_dispatch/journey/parser.y +50 -0
  86. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  87. data/lib/action_dispatch/journey/path/pattern.rb +199 -0
  88. data/lib/action_dispatch/journey/route.rb +203 -0
  89. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  90. data/lib/action_dispatch/journey/router.rb +156 -0
  91. data/lib/action_dispatch/journey/routes.rb +82 -0
  92. data/lib/action_dispatch/journey/scanner.rb +64 -0
  93. data/lib/action_dispatch/journey/visitors.rb +268 -0
  94. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  95. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  96. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  97. data/lib/action_dispatch/journey.rb +7 -0
  98. data/lib/action_dispatch/middleware/callbacks.rb +17 -13
  99. data/lib/action_dispatch/middleware/cookies.rb +494 -162
  100. data/lib/action_dispatch/middleware/debug_exceptions.rb +176 -53
  101. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  102. data/lib/action_dispatch/middleware/exception_wrapper.rb +103 -38
  103. data/lib/action_dispatch/middleware/executor.rb +21 -0
  104. data/lib/action_dispatch/middleware/flash.rb +128 -91
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +43 -16
  106. data/lib/action_dispatch/middleware/reloader.rb +6 -83
  107. data/lib/action_dispatch/middleware/remote_ip.rb +151 -49
  108. data/lib/action_dispatch/middleware/request_id.rb +19 -15
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +38 -34
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -9
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +94 -44
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -4
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +36 -61
  114. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  115. data/lib/action_dispatch/middleware/stack.rb +33 -41
  116. data/lib/action_dispatch/middleware/static.rb +92 -48
  117. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +134 -5
  128. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  136. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  138. data/lib/action_dispatch/railtie.rb +29 -8
  139. data/lib/action_dispatch/request/session.rb +234 -0
  140. data/lib/action_dispatch/request/utils.rb +78 -0
  141. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  142. data/lib/action_dispatch/routing/inspector.rb +225 -0
  143. data/lib/action_dispatch/routing/mapper.rb +1329 -582
  144. data/lib/action_dispatch/routing/polymorphic_routes.rb +237 -94
  145. data/lib/action_dispatch/routing/redirection.rb +120 -50
  146. data/lib/action_dispatch/routing/route_set.rb +545 -322
  147. data/lib/action_dispatch/routing/routes_proxy.rb +37 -7
  148. data/lib/action_dispatch/routing/url_for.rb +103 -34
  149. data/lib/action_dispatch/routing.rb +66 -99
  150. data/lib/action_dispatch/system_test_case.rb +147 -0
  151. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  152. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  153. data/lib/action_dispatch/system_testing/server.rb +31 -0
  154. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  158. data/lib/action_dispatch/testing/assertions/response.rb +53 -42
  159. data/lib/action_dispatch/testing/assertions/routing.rb +79 -74
  160. data/lib/action_dispatch/testing/assertions.rb +15 -9
  161. data/lib/action_dispatch/testing/integration.rb +361 -207
  162. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  163. data/lib/action_dispatch/testing/test_process.rb +28 -19
  164. data/lib/action_dispatch/testing/test_request.rb +30 -33
  165. data/lib/action_dispatch/testing/test_response.rb +35 -11
  166. data/lib/action_dispatch.rb +42 -32
  167. data/lib/action_pack/gem_version.rb +17 -0
  168. data/lib/action_pack/version.rb +7 -7
  169. data/lib/action_pack.rb +4 -2
  170. metadata +116 -175
  171. data/lib/abstract_controller/layouts.rb +0 -423
  172. data/lib/abstract_controller/view_paths.rb +0 -96
  173. data/lib/action_controller/caching/actions.rb +0 -185
  174. data/lib/action_controller/caching/fragments.rb +0 -127
  175. data/lib/action_controller/caching/pages.rb +0 -187
  176. data/lib/action_controller/caching/sweeping.rb +0 -97
  177. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  178. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  179. data/lib/action_controller/deprecated.rb +0 -3
  180. data/lib/action_controller/metal/compatibility.rb +0 -65
  181. data/lib/action_controller/metal/hide_actions.rb +0 -41
  182. data/lib/action_controller/metal/rack_delegation.rb +0 -26
  183. data/lib/action_controller/metal/responder.rb +0 -286
  184. data/lib/action_controller/metal/session_management.rb +0 -14
  185. data/lib/action_controller/middleware.rb +0 -39
  186. data/lib/action_controller/railties/paths.rb +0 -25
  187. data/lib/action_controller/record_identifier.rb +0 -85
  188. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  189. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  190. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  191. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  192. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  193. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  194. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  195. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  196. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  197. data/lib/action_dispatch/middleware/head.rb +0 -18
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -75
  199. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  200. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  201. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  202. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  203. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  204. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  205. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  206. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  207. data/lib/action_dispatch/testing/assertions/dom.rb +0 -37
  208. data/lib/action_dispatch/testing/assertions/selector.rb +0 -435
  209. data/lib/action_dispatch/testing/assertions/tag.rb +0 -138
  210. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  211. data/lib/action_view/asset_paths.rb +0 -142
  212. data/lib/action_view/base.rb +0 -220
  213. data/lib/action_view/buffers.rb +0 -43
  214. data/lib/action_view/context.rb +0 -36
  215. data/lib/action_view/flows.rb +0 -79
  216. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  217. data/lib/action_view/helpers/asset_paths.rb +0 -7
  218. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  219. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  220. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  221. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  222. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  223. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  224. data/lib/action_view/helpers/cache_helper.rb +0 -64
  225. data/lib/action_view/helpers/capture_helper.rb +0 -203
  226. data/lib/action_view/helpers/controller_helper.rb +0 -25
  227. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  228. data/lib/action_view/helpers/date_helper.rb +0 -1062
  229. data/lib/action_view/helpers/debug_helper.rb +0 -40
  230. data/lib/action_view/helpers/form_helper.rb +0 -1486
  231. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  232. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  233. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  234. data/lib/action_view/helpers/number_helper.rb +0 -622
  235. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  236. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  237. data/lib/action_view/helpers/rendering_helper.rb +0 -92
  238. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  239. data/lib/action_view/helpers/tag_helper.rb +0 -167
  240. data/lib/action_view/helpers/text_helper.rb +0 -426
  241. data/lib/action_view/helpers/translation_helper.rb +0 -91
  242. data/lib/action_view/helpers/url_helper.rb +0 -693
  243. data/lib/action_view/helpers.rb +0 -60
  244. data/lib/action_view/locale/en.yml +0 -160
  245. data/lib/action_view/log_subscriber.rb +0 -28
  246. data/lib/action_view/lookup_context.rb +0 -258
  247. data/lib/action_view/path_set.rb +0 -101
  248. data/lib/action_view/railtie.rb +0 -55
  249. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  250. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  251. data/lib/action_view/renderer/renderer.rb +0 -61
  252. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  253. data/lib/action_view/renderer/template_renderer.rb +0 -95
  254. data/lib/action_view/template/error.rb +0 -128
  255. data/lib/action_view/template/handlers/builder.rb +0 -26
  256. data/lib/action_view/template/handlers/erb.rb +0 -125
  257. data/lib/action_view/template/handlers.rb +0 -50
  258. data/lib/action_view/template/resolver.rb +0 -298
  259. data/lib/action_view/template/text.rb +0 -30
  260. data/lib/action_view/template.rb +0 -337
  261. data/lib/action_view/test_case.rb +0 -246
  262. data/lib/action_view/testing/resolvers.rb +0 -49
  263. data/lib/action_view.rb +0 -84
  264. data/lib/sprockets/assets.rake +0 -99
  265. data/lib/sprockets/bootstrap.rb +0 -37
  266. data/lib/sprockets/compressors.rb +0 -83
  267. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  268. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  269. data/lib/sprockets/helpers.rb +0 -6
  270. data/lib/sprockets/railtie.rb +0 -62
  271. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,23 +1,18 @@
1
- module ActionDispatch
2
- class Request
3
- # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
4
- # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
5
- # to put a new one.
6
- def flash
7
- @env[Flash::KEY] ||= (session["flash"] || Flash::FlashHash.new)
8
- end
9
- end
1
+ # frozen_string_literal: true
10
2
 
11
- # The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
3
+ require "active_support/core_ext/hash/keys"
4
+
5
+ module ActionDispatch
6
+ # The flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed
12
7
  # to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
13
8
  # action that sets <tt>flash[:notice] = "Post successfully created"</tt> before redirecting to a display action that can
14
- # then expose the flash to its template. Actually, that exposure is automatically done. Example:
9
+ # then expose the flash to its template. Actually, that exposure is automatically done.
15
10
  #
16
11
  # class PostsController < ActionController::Base
17
12
  # def create
18
13
  # # save post
19
14
  # flash[:notice] = "Post successfully created"
20
- # redirect_to posts_path(@post)
15
+ # redirect_to @post
21
16
  # end
22
17
  #
23
18
  # def show
@@ -35,12 +30,54 @@ module ActionDispatch
35
30
  # flash.alert = "You must be logged in"
36
31
  # flash.notice = "Post successfully created"
37
32
  #
38
- # This example just places a string in the flash, but you can put any object in there. And of course, you can put as
39
- # many as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
33
+ # This example places a string in the flash. And of course, you can put as many as you like at a time too. If you want to pass
34
+ # non-primitive types, you will have to handle that in your application. Example: To show messages with links, you will have to
35
+ # use sanitize helper.
36
+ #
37
+ # Just remember: They'll be gone by the time the next action has been performed.
40
38
  #
41
39
  # See docs on the FlashHash class for more details about the flash.
42
40
  class Flash
43
- KEY = 'action_dispatch.request.flash_hash'.freeze
41
+ KEY = "action_dispatch.request.flash_hash".freeze
42
+
43
+ module RequestMethods
44
+ # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
45
+ # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
46
+ # to put a new one.
47
+ def flash
48
+ flash = flash_hash
49
+ return flash if flash
50
+ self.flash = Flash::FlashHash.from_session_value(session["flash"])
51
+ end
52
+
53
+ def flash=(flash)
54
+ set_header Flash::KEY, flash
55
+ end
56
+
57
+ def flash_hash # :nodoc:
58
+ get_header Flash::KEY
59
+ end
60
+
61
+ def commit_flash # :nodoc:
62
+ session = self.session || {}
63
+ flash_hash = self.flash_hash
64
+
65
+ if flash_hash && (flash_hash.present? || session.key?("flash"))
66
+ session["flash"] = flash_hash.to_session_value
67
+ self.flash = flash_hash.dup
68
+ end
69
+
70
+ if (!session.respond_to?(:loaded?) || session.loaded?) && # reset_session uses {}, which doesn't implement #loaded?
71
+ session.key?("flash") && session["flash"].nil?
72
+ session.delete("flash")
73
+ end
74
+ end
75
+
76
+ def reset_session # :nodoc:
77
+ super
78
+ self.flash = nil
79
+ end
80
+ end
44
81
 
45
82
  class FlashNow #:nodoc:
46
83
  attr_accessor :flash
@@ -50,37 +87,60 @@ module ActionDispatch
50
87
  end
51
88
 
52
89
  def []=(k, v)
90
+ k = k.to_s
53
91
  @flash[k] = v
54
92
  @flash.discard(k)
55
93
  v
56
94
  end
57
95
 
58
96
  def [](k)
59
- @flash[k]
97
+ @flash[k.to_s]
60
98
  end
61
99
 
62
- # Convenience accessor for flash.now[:alert]=
100
+ # Convenience accessor for <tt>flash.now[:alert]=</tt>.
63
101
  def alert=(message)
64
102
  self[:alert] = message
65
103
  end
66
104
 
67
- # Convenience accessor for flash.now[:notice]=
105
+ # Convenience accessor for <tt>flash.now[:notice]=</tt>.
68
106
  def notice=(message)
69
107
  self[:notice] = message
70
108
  end
71
109
  end
72
110
 
73
- # Implementation detail: please do not change the signature of the
74
- # FlashHash class. Doing that will likely affect all Rails apps in
75
- # production as the FlashHash currently stored in their sessions will
76
- # become invalid.
77
111
  class FlashHash
78
112
  include Enumerable
79
113
 
80
- def initialize #:nodoc:
81
- @used = Set.new
82
- @closed = false
83
- @flashes = {}
114
+ def self.from_session_value(value) #:nodoc:
115
+ case value
116
+ when FlashHash # Rails 3.1, 3.2
117
+ flashes = value.instance_variable_get(:@flashes)
118
+ if discard = value.instance_variable_get(:@used)
119
+ flashes.except!(*discard)
120
+ end
121
+ new(flashes, flashes.keys)
122
+ when Hash # Rails 4.0
123
+ flashes = value["flashes"]
124
+ if discard = value["discard"]
125
+ flashes.except!(*discard)
126
+ end
127
+ new(flashes, flashes.keys)
128
+ else
129
+ new
130
+ end
131
+ end
132
+
133
+ # Builds a hash containing the flashes to keep for the next request.
134
+ # If there are none to keep, returns +nil+.
135
+ def to_session_value #:nodoc:
136
+ flashes_to_keep = @flashes.except(*@discard)
137
+ return nil if flashes_to_keep.empty?
138
+ { "discard" => [], "flashes" => flashes_to_keep }
139
+ end
140
+
141
+ def initialize(flashes = {}, discard = []) #:nodoc:
142
+ @discard = Set.new(stringify_array(discard))
143
+ @flashes = flashes.stringify_keys
84
144
  @now = nil
85
145
  end
86
146
 
@@ -92,18 +152,19 @@ module ActionDispatch
92
152
  super
93
153
  end
94
154
 
95
- def []=(k, v) #:nodoc:
96
- keep(k)
155
+ def []=(k, v)
156
+ k = k.to_s
157
+ @discard.delete k
97
158
  @flashes[k] = v
98
159
  end
99
160
 
100
161
  def [](k)
101
- @flashes[k]
162
+ @flashes[k.to_s]
102
163
  end
103
164
 
104
165
  def update(h) #:nodoc:
105
- h.keys.each { |k| keep(k) }
106
- @flashes.update h
166
+ @discard.subtract stringify_array(h.keys)
167
+ @flashes.update h.stringify_keys
107
168
  self
108
169
  end
109
170
 
@@ -112,10 +173,12 @@ module ActionDispatch
112
173
  end
113
174
 
114
175
  def key?(name)
115
- @flashes.key? name
176
+ @flashes.key? name.to_s
116
177
  end
117
178
 
118
179
  def delete(key)
180
+ key = key.to_s
181
+ @discard.delete key
119
182
  @flashes.delete key
120
183
  self
121
184
  end
@@ -129,6 +192,7 @@ module ActionDispatch
129
192
  end
130
193
 
131
194
  def clear
195
+ @discard.clear
132
196
  @flashes.clear
133
197
  end
134
198
 
@@ -139,8 +203,8 @@ module ActionDispatch
139
203
  alias :merge! :update
140
204
 
141
205
  def replace(h) #:nodoc:
142
- @used = Set.new
143
- @flashes.replace h
206
+ @discard.clear
207
+ @flashes.replace h.stringify_keys
144
208
  self
145
209
  end
146
210
 
@@ -154,6 +218,14 @@ module ActionDispatch
154
218
  # vanish when the current action is done.
155
219
  #
156
220
  # Entries set via <tt>now</tt> are accessed the same way as standard entries: <tt>flash['my-key']</tt>.
221
+ #
222
+ # Also, brings two convenience accessors:
223
+ #
224
+ # flash.now.alert = "Beware now!"
225
+ # # Equivalent to flash.now[:alert] = "Beware now!"
226
+ #
227
+ # flash.now.notice = "Good luck now!"
228
+ # # Equivalent to flash.now[:notice] = "Good luck now!"
157
229
  def now
158
230
  @now ||= FlashNow.new(self)
159
231
  end
@@ -163,7 +235,9 @@ module ActionDispatch
163
235
  # flash.keep # keeps the entire flash
164
236
  # flash.keep(:notice) # keeps only the "notice" entry, the rest of the flash is discarded
165
237
  def keep(k = nil)
166
- use(k, false)
238
+ k = k.to_s if k
239
+ @discard.subtract Array(k || keys)
240
+ k ? self[k] : self
167
241
  end
168
242
 
169
243
  # Marks the entire flash or a single flash entry to be discarded by the end of the current action:
@@ -171,93 +245,56 @@ module ActionDispatch
171
245
  # flash.discard # discard the entire flash at the end of the current action
172
246
  # flash.discard(:warning) # discard only the "warning" entry at the end of the current action
173
247
  def discard(k = nil)
174
- use(k)
248
+ k = k.to_s if k
249
+ @discard.merge Array(k || keys)
250
+ k ? self[k] : self
175
251
  end
176
252
 
177
253
  # Mark for removal entries that were kept, and delete unkept ones.
178
254
  #
179
255
  # This method is called automatically by filters, so you generally don't need to care about it.
180
256
  def sweep #:nodoc:
181
- keys.each do |k|
182
- unless @used.include?(k)
183
- @used << k
184
- else
185
- delete(k)
186
- @used.delete(k)
187
- end
188
- end
189
-
190
- # clean up after keys that could have been left over by calling reject! or shift on the flash
191
- (@used - keys).each{ |k| @used.delete(k) }
257
+ @discard.each { |k| @flashes.delete k }
258
+ @discard.replace @flashes.keys
192
259
  end
193
260
 
194
- # Convenience accessor for flash[:alert]
261
+ # Convenience accessor for <tt>flash[:alert]</tt>.
195
262
  def alert
196
263
  self[:alert]
197
264
  end
198
265
 
199
- # Convenience accessor for flash[:alert]=
266
+ # Convenience accessor for <tt>flash[:alert]=</tt>.
200
267
  def alert=(message)
201
268
  self[:alert] = message
202
269
  end
203
270
 
204
- # Convenience accessor for flash[:notice]
271
+ # Convenience accessor for <tt>flash[:notice]</tt>.
205
272
  def notice
206
273
  self[:notice]
207
274
  end
208
275
 
209
- # Convenience accessor for flash[:notice]=
276
+ # Convenience accessor for <tt>flash[:notice]=</tt>.
210
277
  def notice=(message)
211
278
  self[:notice] = message
212
279
  end
213
280
 
214
281
  protected
215
-
216
282
  def now_is_loaded?
217
- !!@now
283
+ @now
218
284
  end
219
285
 
220
- # Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
221
- # use() # marks the entire flash as used
222
- # use('msg') # marks the "msg" entry as used
223
- # use(nil, false) # marks the entire flash as unused (keeps it around for one more action)
224
- # use('msg', false) # marks the "msg" entry as unused (keeps it around for one more action)
225
- # Returns the single value for the key you asked to be marked (un)used or the FlashHash itself
226
- # if no key is passed.
227
- def use(key = nil, used = true)
228
- Array(key || keys).each { |k| used ? @used << k : @used.delete(k) }
229
- return key ? self[key] : self
286
+ private
287
+ def stringify_array(array) # :doc:
288
+ array.map do |item|
289
+ item.kind_of?(Symbol) ? item.to_s : item
290
+ end
230
291
  end
231
292
  end
232
293
 
233
- def initialize(app)
234
- @app = app
235
- end
236
-
237
- def call(env)
238
- if (session = env['rack.session']) && (flash = session['flash'])
239
- flash.sweep
240
- end
241
-
242
- @app.call(env)
243
- ensure
244
- session = env['rack.session'] || {}
245
- flash_hash = env[KEY]
246
-
247
- if flash_hash
248
- if !flash_hash.empty? || session.key?('flash')
249
- session["flash"] = flash_hash
250
- new_hash = flash_hash.dup
251
- else
252
- new_hash = flash_hash
253
- end
254
-
255
- env[KEY] = new_hash
256
- end
294
+ def self.new(app) app; end
295
+ end
257
296
 
258
- if session.key?('flash') && session['flash'].empty?
259
- session.delete('flash')
260
- end
261
- end
297
+ class Request
298
+ prepend Flash::RequestMethods
262
299
  end
263
300
  end
@@ -1,5 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
- # A simple Rack application that renders exceptions in the given public path.
4
+ # When called, this middleware renders an error page. By default if an HTML
5
+ # response is expected it will render static error pages from the <tt>/public</tt>
6
+ # directory. For example when this middleware receives a 500 response it will
7
+ # render the template found in <tt>/public/500.html</tt>.
8
+ # If an internationalized locale is set, this middleware will attempt to render
9
+ # the template in <tt>/public/500.<locale>.html</tt>. If an internationalized template
10
+ # is not found it will fall back on <tt>/public/500.html</tt>.
11
+ #
12
+ # When a request with a content type other than HTML is made, this middleware
13
+ # will attempt to convert error information into the appropriate response type.
3
14
  class PublicExceptions
4
15
  attr_accessor :public_path
5
16
 
@@ -8,23 +19,39 @@ module ActionDispatch
8
19
  end
9
20
 
10
21
  def call(env)
11
- status = env["PATH_INFO"][1..-1]
12
- locale_path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale
13
- path = "#{public_path}/#{status}.html"
14
-
15
- if locale_path && File.exist?(locale_path)
16
- render(status, File.read(locale_path))
17
- elsif File.exist?(path)
18
- render(status, File.read(path))
19
- else
20
- [404, { "X-Cascade" => "pass" }, []]
21
- end
22
+ request = ActionDispatch::Request.new(env)
23
+ status = request.path_info[1..-1].to_i
24
+ content_type = request.formats.first
25
+ body = { status: status, error: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500]) }
26
+
27
+ render(status, content_type, body)
22
28
  end
23
29
 
24
30
  private
25
31
 
26
- def render(status, body)
27
- [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
28
- end
32
+ def render(status, content_type, body)
33
+ format = "to_#{content_type.to_sym}" if content_type
34
+ if format && body.respond_to?(format)
35
+ render_format(status, content_type, body.public_send(format))
36
+ else
37
+ render_html(status)
38
+ end
39
+ end
40
+
41
+ def render_format(status, content_type, body)
42
+ [status, { "Content-Type" => "#{content_type}; charset=#{ActionDispatch::Response.default_charset}",
43
+ "Content-Length" => body.bytesize.to_s }, [body]]
44
+ end
45
+
46
+ def render_html(status)
47
+ path = "#{public_path}/#{status}.#{I18n.locale}.html"
48
+ path = "#{public_path}/#{status}.html" unless (found = File.exist?(path))
49
+
50
+ if found || File.exist?(path)
51
+ render_format(status, "text/html", File.read(path))
52
+ else
53
+ [404, { "X-Cascade" => "pass" }, []]
54
+ end
55
+ end
29
56
  end
30
- end
57
+ end
@@ -1,89 +1,12 @@
1
- require 'action_dispatch/middleware/body_proxy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActionDispatch
4
- # ActionDispatch::Reloader provides prepare and cleanup callbacks,
5
- # intended to assist with code reloading during development.
6
- #
7
- # Prepare callbacks are run before each request, and cleanup callbacks
8
- # after each request. In this respect they are analogs of ActionDispatch::Callback's
9
- # before and after callbacks. However, cleanup callbacks are not called until the
10
- # request is fully complete -- that is, after #close has been called on
11
- # the response body. This is important for streaming responses such as the
12
- # following:
13
- #
14
- # self.response_body = lambda { |response, output|
15
- # # code here which refers to application models
16
- # }
17
- #
18
- # Cleanup callbacks will not be called until after the response_body lambda
19
- # is evaluated, ensuring that it can refer to application models and other
20
- # classes before they are unloaded.
4
+ # ActionDispatch::Reloader wraps the request with callbacks provided by ActiveSupport::Reloader
5
+ # callbacks, intended to assist with code reloading during development.
21
6
  #
22
7
  # By default, ActionDispatch::Reloader is included in the middleware stack
23
- # only in the development environment; specifically, when config.cache_classes
24
- # is false. Callbacks may be registered even when it is not included in the
25
- # middleware stack, but are executed only when +ActionDispatch::Reloader.prepare!+
26
- # or +ActionDispatch::Reloader.cleanup!+ are called manually.
27
- #
28
- class Reloader
29
- include ActiveSupport::Callbacks
30
-
31
- define_callbacks :prepare, :scope => :name
32
- define_callbacks :cleanup, :scope => :name
33
-
34
- # Add a prepare callback. Prepare callbacks are run before each request, prior
35
- # to ActionDispatch::Callback's before callbacks.
36
- def self.to_prepare(*args, &block)
37
- set_callback(:prepare, *args, &block)
38
- end
39
-
40
- # Add a cleanup callback. Cleanup callbacks are run after each request is
41
- # complete (after #close is called on the response body).
42
- def self.to_cleanup(*args, &block)
43
- set_callback(:cleanup, *args, &block)
44
- end
45
-
46
- # Execute all prepare callbacks.
47
- def self.prepare!
48
- new(nil).prepare!
49
- end
50
-
51
- # Execute all cleanup callbacks.
52
- def self.cleanup!
53
- new(nil).cleanup!
54
- end
55
-
56
- def initialize(app, condition=nil)
57
- @app = app
58
- @condition = condition || lambda { true }
59
- @validated = true
60
- end
61
-
62
- def call(env)
63
- @validated = @condition.call
64
- prepare!
65
- response = @app.call(env)
66
- response[2] = ActionDispatch::BodyProxy.new(response[2]) { cleanup! }
67
- response
68
- rescue Exception
69
- cleanup!
70
- raise
71
- end
72
-
73
- def prepare! #:nodoc:
74
- run_callbacks :prepare if validated?
75
- end
76
-
77
- def cleanup! #:nodoc:
78
- run_callbacks :cleanup if validated?
79
- ensure
80
- @validated = true
81
- end
82
-
83
- private
84
-
85
- def validated? #:nodoc:
86
- @validated
87
- end
8
+ # only in the development environment; specifically, when +config.cache_classes+
9
+ # is false.
10
+ class Reloader < Executor
88
11
  end
89
12
  end