actionpack 3.2.22.5 → 5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,22 @@
1
- require 'active_support/core_ext/class/attribute'
2
- require 'active_support/core_ext/hash/slice'
3
- require 'active_support/core_ext/hash/except'
4
- require 'active_support/core_ext/array/wrap'
5
- require 'active_support/core_ext/module/anonymous'
6
- require 'action_dispatch/http/mime_types'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/slice"
4
+ require "active_support/core_ext/hash/except"
5
+ require "active_support/core_ext/module/anonymous"
6
+ require "action_dispatch/http/mime_type"
7
7
 
8
8
  module ActionController
9
- # Wraps the parameters hash into a nested hash. This will allow clients to submit
10
- # POST requests without having to specify any root elements.
9
+ # Wraps the parameters hash into a nested hash. This will allow clients to
10
+ # submit requests without having to specify any root elements.
11
11
  #
12
12
  # This functionality is enabled in +config/initializers/wrap_parameters.rb+
13
- # and can be customized. If you are upgrading to \Rails 3.1, this file will
14
- # need to be created for the functionality to be enabled.
13
+ # and can be customized.
15
14
  #
16
15
  # You could also turn it on per controller by setting the format array to
17
16
  # a non-empty array:
18
17
  #
19
18
  # class UsersController < ApplicationController
20
- # wrap_parameters :format => [:json, :xml]
19
+ # wrap_parameters format: [:json, :xml, :url_encoded_form, :multipart_form]
21
20
  # end
22
21
  #
23
22
  # If you enable +ParamsWrapper+ for +:json+ format, instead of having to
@@ -40,16 +39,15 @@ module ActionController
40
39
  # +:exclude+ options like this:
41
40
  #
42
41
  # class UsersController < ApplicationController
43
- # wrap_parameters :person, :include => [:username, :password]
42
+ # wrap_parameters :person, include: [:username, :password]
44
43
  # end
45
44
  #
46
- # On ActiveRecord models with no +:include+ or +:exclude+ option set,
47
- # if attr_accessible is set on that model, it will only wrap the accessible
48
- # parameters, else it will only wrap the parameters returned by the class
49
- # method attribute_names.
45
+ # On Active Record models with no +:include+ or +:exclude+ option set,
46
+ # it will only wrap the parameters returned by the class method
47
+ # <tt>attribute_names</tt>.
50
48
  #
51
49
  # If you're going to pass the parameters to an +ActiveModel+ object (such as
52
- # +User.new(params[:user])+), you might consider passing the model class to
50
+ # <tt>User.new(params[:user])</tt>), you might consider passing the model class to
53
51
  # the method instead. The +ParamsWrapper+ will actually try to determine the
54
52
  # list of attribute names from the model and only wrap those attributes:
55
53
  #
@@ -67,7 +65,7 @@ module ActionController
67
65
  # class Admin::UsersController < ApplicationController
68
66
  # end
69
67
  #
70
- # will try to check if +Admin::User+ or +User+ model exists, and use it to
68
+ # will try to check if <tt>Admin::User</tt> or +User+ model exists, and use it to
71
69
  # determine the wrapper key respectively. If both models don't exist,
72
70
  # it will then fallback to use +user+ as the key.
73
71
  module ParamsWrapper
@@ -75,17 +73,115 @@ module ActionController
75
73
 
76
74
  EXCLUDE_PARAMETERS = %w(authenticity_token _method utf8)
77
75
 
76
+ require "mutex_m"
77
+
78
+ class Options < Struct.new(:name, :format, :include, :exclude, :klass, :model) # :nodoc:
79
+ include Mutex_m
80
+
81
+ def self.from_hash(hash)
82
+ name = hash[:name]
83
+ format = Array(hash[:format])
84
+ include = hash[:include] && Array(hash[:include]).collect(&:to_s)
85
+ exclude = hash[:exclude] && Array(hash[:exclude]).collect(&:to_s)
86
+ new name, format, include, exclude, nil, nil
87
+ end
88
+
89
+ def initialize(name, format, include, exclude, klass, model) # :nodoc:
90
+ super
91
+ @include_set = include
92
+ @name_set = name
93
+ end
94
+
95
+ def model
96
+ super || self.model = _default_wrap_model
97
+ end
98
+
99
+ def include
100
+ return super if @include_set
101
+
102
+ m = model
103
+ synchronize do
104
+ return super if @include_set
105
+
106
+ @include_set = true
107
+
108
+ unless super || exclude
109
+ if m.respond_to?(:attribute_names) && m.attribute_names.any?
110
+ if m.respond_to?(:stored_attributes) && !m.stored_attributes.empty?
111
+ self.include = m.attribute_names + m.stored_attributes.values.flatten.map(&:to_s)
112
+ else
113
+ self.include = m.attribute_names
114
+ end
115
+
116
+ if m.respond_to?(:nested_attributes_options) && m.nested_attributes_options.keys.any?
117
+ self.include += m.nested_attributes_options.keys.map do |key|
118
+ key.to_s.dup.concat("_attributes")
119
+ end
120
+ end
121
+
122
+ self.include
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ def name
129
+ return super if @name_set
130
+
131
+ m = model
132
+ synchronize do
133
+ return super if @name_set
134
+
135
+ @name_set = true
136
+
137
+ unless super || klass.anonymous?
138
+ self.name = m ? m.to_s.demodulize.underscore :
139
+ klass.controller_name.singularize
140
+ end
141
+ end
142
+ end
143
+
144
+ private
145
+ # Determine the wrapper model from the controller's name. By convention,
146
+ # this could be done by trying to find the defined model that has the
147
+ # same singular name as the controller. For example, +UsersController+
148
+ # will try to find if the +User+ model exists.
149
+ #
150
+ # This method also does namespace lookup. Foo::Bar::UsersController will
151
+ # try to find Foo::Bar::User, Foo::User and finally User.
152
+ def _default_wrap_model
153
+ return nil if klass.anonymous?
154
+ model_name = klass.name.sub(/Controller$/, "").classify
155
+
156
+ begin
157
+ if model_klass = model_name.safe_constantize
158
+ model_klass
159
+ else
160
+ namespaces = model_name.split("::")
161
+ namespaces.delete_at(-2)
162
+ break if namespaces.last == model_name
163
+ model_name = namespaces.join("::")
164
+ end
165
+ end until model_klass
166
+
167
+ model_klass
168
+ end
169
+ end
170
+
78
171
  included do
79
- class_attribute :_wrapper_options
80
- self._wrapper_options = { :format => [] }
172
+ class_attribute :_wrapper_options, default: Options.from_hash(format: [])
81
173
  end
82
174
 
83
175
  module ClassMethods
176
+ def _set_wrapper_options(options)
177
+ self._wrapper_options = Options.from_hash(options)
178
+ end
179
+
84
180
  # Sets the name of the wrapper key, or the model which +ParamsWrapper+
85
181
  # would use to determine the attribute names from.
86
182
  #
87
183
  # ==== Examples
88
- # wrap_parameters :format => :xml
184
+ # wrap_parameters format: :xml
89
185
  # # enables the parameter wrapper for XML format
90
186
  #
91
187
  # wrap_parameters :person
@@ -95,7 +191,7 @@ module ActionController
95
191
  # # wraps parameters by determining the wrapper key from Person class
96
192
  # (+person+, in this case) and the list of attribute names
97
193
  #
98
- # wrap_parameters :include => [:username, :title]
194
+ # wrap_parameters include: [:username, :title]
99
195
  # # wraps only +:username+ and +:title+ attributes from parameters.
100
196
  #
101
197
  # wrap_parameters false
@@ -115,81 +211,34 @@ module ActionController
115
211
  when Hash
116
212
  options = name_or_model_or_options
117
213
  when false
118
- options = options.merge(:format => [])
214
+ options = options.merge(format: [])
119
215
  when Symbol, String
120
- options = options.merge(:name => name_or_model_or_options)
216
+ options = options.merge(name: name_or_model_or_options)
121
217
  else
122
218
  model = name_or_model_or_options
123
219
  end
124
220
 
125
- _set_wrapper_defaults(_wrapper_options.slice(:format).merge(options), model)
221
+ opts = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options)
222
+ opts.model = model
223
+ opts.klass = self
224
+
225
+ self._wrapper_options = opts
126
226
  end
127
227
 
128
228
  # Sets the default wrapper key or model which will be used to determine
129
- # wrapper key and attribute names. Will be called automatically when the
229
+ # wrapper key and attribute names. Called automatically when the
130
230
  # module is inherited.
131
231
  def inherited(klass)
132
- if klass._wrapper_options[:format].present?
133
- klass._set_wrapper_defaults(klass._wrapper_options.slice(:format))
232
+ if klass._wrapper_options.format.any?
233
+ params = klass._wrapper_options.dup
234
+ params.klass = klass
235
+ klass._wrapper_options = params
134
236
  end
135
237
  super
136
238
  end
137
-
138
- protected
139
-
140
- # Determine the wrapper model from the controller's name. By convention,
141
- # this could be done by trying to find the defined model that has the
142
- # same singularize name as the controller. For example, +UsersController+
143
- # will try to find if the +User+ model exists.
144
- #
145
- # This method also does namespace lookup. Foo::Bar::UsersController will
146
- # try to find Foo::Bar::User, Foo::User and finally User.
147
- def _default_wrap_model #:nodoc:
148
- return nil if self.anonymous?
149
- model_name = self.name.sub(/Controller$/, '').classify
150
-
151
- begin
152
- if model_klass = model_name.safe_constantize
153
- model_klass
154
- else
155
- namespaces = model_name.split("::")
156
- namespaces.delete_at(-2)
157
- break if namespaces.last == model_name
158
- model_name = namespaces.join("::")
159
- end
160
- end until model_klass
161
-
162
- model_klass
163
- end
164
-
165
- def _set_wrapper_defaults(options, model=nil)
166
- options = options.dup
167
-
168
- unless options[:include] || options[:exclude]
169
- model ||= _default_wrap_model
170
- role = options.has_key?(:as) ? options[:as] : :default
171
- if model.respond_to?(:accessible_attributes) && model.accessible_attributes(role).present?
172
- options[:include] = model.accessible_attributes(role).to_a
173
- elsif model.respond_to?(:attribute_names) && model.attribute_names.present?
174
- options[:include] = model.attribute_names
175
- end
176
- end
177
-
178
- unless options[:name] || self.anonymous?
179
- model ||= _default_wrap_model
180
- options[:name] = model ? model.to_s.demodulize.underscore :
181
- controller_name.singularize
182
- end
183
-
184
- options[:include] = Array.wrap(options[:include]).collect(&:to_s) if options[:include]
185
- options[:exclude] = Array.wrap(options[:exclude]).collect(&:to_s) if options[:exclude]
186
- options[:format] = Array.wrap(options[:format])
187
-
188
- self._wrapper_options = options
189
- end
190
239
  end
191
240
 
192
- # Performs parameters wrapping upon the request. Will be called automatically
241
+ # Performs parameters wrapping upon the request. Called automatically
193
242
  # by the metal call stack.
194
243
  def process_action(*args)
195
244
  if _wrapper_enabled?
@@ -197,11 +246,11 @@ module ActionController
197
246
  wrapped_keys = request.request_parameters.keys
198
247
  wrapped_filtered_hash = _wrap_parameters request.filtered_parameters.slice(*wrapped_keys)
199
248
 
200
- # This will make the wrapped hash accessible from controller and view
249
+ # This will make the wrapped hash accessible from controller and view.
201
250
  request.parameters.merge! wrapped_hash
202
251
  request.request_parameters.merge! wrapped_hash
203
252
 
204
- # This will make the wrapped hash displayed in the log file
253
+ # This will display the wrapped hash in the log file.
205
254
  request.filtered_parameters.merge! wrapped_filtered_hash
206
255
  end
207
256
  super
@@ -209,32 +258,36 @@ module ActionController
209
258
 
210
259
  private
211
260
 
212
- # Returns the wrapper key which will use to stored wrapped parameters.
261
+ # Returns the wrapper key which will be used to store wrapped parameters.
213
262
  def _wrapper_key
214
- _wrapper_options[:name]
263
+ _wrapper_options.name
215
264
  end
216
265
 
217
266
  # Returns the list of enabled formats.
218
267
  def _wrapper_formats
219
- _wrapper_options[:format]
268
+ _wrapper_options.format
220
269
  end
221
270
 
222
271
  # Returns the list of parameters which will be selected for wrapped.
223
272
  def _wrap_parameters(parameters)
224
- value = if include_only = _wrapper_options[:include]
273
+ { _wrapper_key => _extract_parameters(parameters) }
274
+ end
275
+
276
+ def _extract_parameters(parameters)
277
+ if include_only = _wrapper_options.include
225
278
  parameters.slice(*include_only)
226
279
  else
227
- exclude = _wrapper_options[:exclude] || []
280
+ exclude = _wrapper_options.exclude || []
228
281
  parameters.except(*(exclude + EXCLUDE_PARAMETERS))
229
282
  end
230
-
231
- { _wrapper_key => value }
232
283
  end
233
284
 
234
285
  # Checks if we should perform parameters wrapping.
235
286
  def _wrapper_enabled?
236
- ref = request.content_mime_type.try(:ref)
237
- _wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters[_wrapper_key]
287
+ return false unless request.has_content_type?
288
+
289
+ ref = request.content_mime_type.ref
290
+ _wrapper_formats.include?(ref) && _wrapper_key && !request.parameters.key?(_wrapper_key)
238
291
  end
239
292
  end
240
293
  end
@@ -1,80 +1,118 @@
1
- module ActionController
2
- class RedirectBackError < AbstractController::Error #:nodoc:
3
- DEFAULT_MESSAGE = 'No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].'
4
-
5
- def initialize(message = nil)
6
- super(message || DEFAULT_MESSAGE)
7
- end
8
- end
1
+ # frozen_string_literal: true
9
2
 
3
+ module ActionController
10
4
  module Redirecting
11
5
  extend ActiveSupport::Concern
12
6
 
13
7
  include AbstractController::Logger
14
- include ActionController::RackDelegation
15
8
  include ActionController::UrlFor
16
9
 
17
- # Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
10
+ # Redirects the browser to the target specified in +options+. This parameter can be any one of:
18
11
  #
19
12
  # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
20
13
  # * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
21
14
  # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) or a protocol relative reference (like <tt>//</tt>) - Is passed straight through as the target for redirection.
22
15
  # * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
23
16
  # * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+.
24
- # * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
25
- # Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
26
17
  #
27
- # Examples:
28
- # redirect_to :action => "show", :id => 5
29
- # redirect_to post
18
+ # === Examples:
19
+ #
20
+ # redirect_to action: "show", id: 5
21
+ # redirect_to @post
30
22
  # redirect_to "http://www.rubyonrails.org"
31
23
  # redirect_to "/images/screenshot.jpg"
32
- # redirect_to articles_url
33
- # redirect_to :back
24
+ # redirect_to posts_url
34
25
  # redirect_to proc { edit_post_url(@post) }
35
26
  #
36
- # The redirection happens as a "302 Moved" header unless otherwise specified.
27
+ # The redirection happens as a <tt>302 Found</tt> header unless otherwise specified using the <tt>:status</tt> option:
37
28
  #
38
- # Examples:
39
- # redirect_to post_url(@post), :status => :found
40
- # redirect_to :action=>'atom', :status => :moved_permanently
41
- # redirect_to post_url(@post), :status => 301
42
- # redirect_to :action=>'atom', :status => 302
29
+ # redirect_to post_url(@post), status: :found
30
+ # redirect_to action: 'atom', status: :moved_permanently
31
+ # redirect_to post_url(@post), status: 301
32
+ # redirect_to action: 'atom', status: 302
43
33
  #
44
- # The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an
34
+ # The status code can either be a standard {HTTP Status code}[https://www.iana.org/assignments/http-status-codes] as an
45
35
  # integer, or a symbol representing the downcased, underscored and symbolized description.
46
36
  # Note that the status code must be a 3xx HTTP code, or redirection will not occur.
47
37
  #
48
38
  # If you are using XHR requests other than GET or POST and redirecting after the
49
39
  # request then some browsers will follow the redirect using the original request
50
40
  # method. This may lead to undesirable behavior such as a double DELETE. To work
51
- # around this you can return a <tt>303 See Other</tt> status code which will be
41
+ # around this you can return a <tt>303 See Other</tt> status code which will be
52
42
  # followed using a GET request.
53
43
  #
54
- # Examples:
55
- # redirect_to posts_url, :status => :see_other
56
- # redirect_to :action => 'index', :status => 303
44
+ # redirect_to posts_url, status: :see_other
45
+ # redirect_to action: 'index', status: 303
57
46
  #
58
47
  # It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names
59
48
  # +alert+ and +notice+ as well as a general purpose +flash+ bucket.
60
49
  #
61
- # Examples:
62
- # redirect_to post_url(@post), :alert => "Watch it, mister!"
63
- # redirect_to post_url(@post), :status=> :found, :notice => "Pay attention to the road"
64
- # redirect_to post_url(@post), :status => 301, :flash => { :updated_post_id => @post.id }
65
- # redirect_to { :action=>'atom' }, :alert => "Something serious happened"
50
+ # redirect_to post_url(@post), alert: "Watch it, mister!"
51
+ # redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
52
+ # redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
53
+ # redirect_to({ action: 'atom' }, alert: "Something serious happened")
66
54
  #
67
- # When using <tt>redirect_to :back</tt>, if there is no referrer, ActionController::RedirectBackError will be raised. You may specify some fallback
68
- # behavior for this case by rescuing ActionController::RedirectBackError.
69
- def redirect_to(options = {}, response_status = {}) #:doc:
55
+ # Statements after +redirect_to+ in our controller get executed, so +redirect_to+ doesn't stop the execution of the function.
56
+ # To terminate the execution of the function immediately after the +redirect_to+, use return.
57
+ # redirect_to post_url(@post) and return
58
+ def redirect_to(options = {}, response_status = {})
70
59
  raise ActionControllerError.new("Cannot redirect to nil!") unless options
71
60
  raise AbstractController::DoubleRenderError if response_body
72
61
 
73
62
  self.status = _extract_redirect_to_status(options, response_status)
74
- self.location = _compute_redirect_to_location(options)
75
- self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.h(location)}\">redirected</a>.</body></html>"
63
+ self.location = _compute_redirect_to_location(request, options)
64
+ self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
76
65
  end
77
66
 
67
+ # Redirects the browser to the page that issued the request (the referrer)
68
+ # if possible, otherwise redirects to the provided default fallback
69
+ # location.
70
+ #
71
+ # The referrer information is pulled from the HTTP +Referer+ (sic) header on
72
+ # the request. This is an optional header and its presence on the request is
73
+ # subject to browser security settings and user preferences. If the request
74
+ # is missing this header, the <tt>fallback_location</tt> will be used.
75
+ #
76
+ # redirect_back fallback_location: { action: "show", id: 5 }
77
+ # redirect_back fallback_location: @post
78
+ # redirect_back fallback_location: "http://www.rubyonrails.org"
79
+ # redirect_back fallback_location: "/images/screenshot.jpg"
80
+ # redirect_back fallback_location: posts_url
81
+ # redirect_back fallback_location: proc { edit_post_url(@post) }
82
+ # redirect_back fallback_location: '/', allow_other_host: false
83
+ #
84
+ # ==== Options
85
+ # * <tt>:fallback_location</tt> - The default fallback location that will be used on missing +Referer+ header.
86
+ # * <tt>:allow_other_host</tt> - Allow or disallow redirection to the host that is different to the current host, defaults to true.
87
+ #
88
+ # All other options that can be passed to <tt>redirect_to</tt> are accepted as
89
+ # options and the behavior is identical.
90
+ def redirect_back(fallback_location:, allow_other_host: true, **args)
91
+ referer = request.headers["Referer"]
92
+ redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
93
+ redirect_to redirect_to_referer ? referer : fallback_location, **args
94
+ end
95
+
96
+ def _compute_redirect_to_location(request, options) #:nodoc:
97
+ case options
98
+ # The scheme name consist of a letter followed by any combination of
99
+ # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
100
+ # characters; and is terminated by a colon (":").
101
+ # See https://tools.ietf.org/html/rfc3986#section-3.1
102
+ # The protocol relative scheme starts with a double slash "//".
103
+ when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
104
+ options
105
+ when String
106
+ request.protocol + request.host_with_port + options
107
+ when Proc
108
+ _compute_redirect_to_location request, instance_eval(&options)
109
+ else
110
+ url_for(options)
111
+ end.delete("\0\r\n")
112
+ end
113
+ module_function :_compute_redirect_to_location
114
+ public :_compute_redirect_to_location
115
+
78
116
  private
79
117
  def _extract_redirect_to_status(options, response_status)
80
118
  if options.is_a?(Hash) && options.key?(:status)
@@ -86,24 +124,10 @@ module ActionController
86
124
  end
87
125
  end
88
126
 
89
- def _compute_redirect_to_location(options)
90
- case options
91
- # The scheme name consist of a letter followed by any combination of
92
- # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
93
- # characters; and is terminated by a colon (":").
94
- # The protocol relative scheme starts with a double slash "//"
95
- when %r{^(\w[\w+.-]*:|//).*}
96
- options
97
- when String
98
- request.protocol + request.host_with_port + options
99
- when :back
100
- raise RedirectBackError unless refer = request.headers["Referer"]
101
- refer
102
- when Proc
103
- _compute_redirect_to_location options.call
104
- else
105
- url_for(options)
106
- end.gsub(/[\0\r\n]/, '')
127
+ def _url_host_allowed?(url)
128
+ URI(url.to_s).host == request.host
129
+ rescue ArgumentError, URI::Error
130
+ false
107
131
  end
108
132
  end
109
133
  end