actionpack 3.2.19 → 4.0.0

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 (263) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +850 -401
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +39 -37
  7. data/lib/abstract_controller/callbacks.rb +101 -82
  8. data/lib/abstract_controller/collector.rb +7 -3
  9. data/lib/abstract_controller/helpers.rb +25 -13
  10. data/lib/abstract_controller/layouts.rb +74 -74
  11. data/lib/abstract_controller/logger.rb +1 -2
  12. data/lib/abstract_controller/rendering.rb +30 -13
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +6 -6
  15. data/lib/abstract_controller/view_paths.rb +1 -1
  16. data/lib/abstract_controller.rb +1 -8
  17. data/lib/action_controller/base.rb +46 -22
  18. data/lib/action_controller/caching/fragments.rb +23 -53
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/log_subscriber.rb +16 -8
  23. data/lib/action_controller/metal/conditional_get.rb +76 -32
  24. data/lib/action_controller/metal/data_streaming.rb +20 -26
  25. data/lib/action_controller/metal/exceptions.rb +19 -6
  26. data/lib/action_controller/metal/flash.rb +24 -9
  27. data/lib/action_controller/metal/force_ssl.rb +70 -12
  28. data/lib/action_controller/metal/head.rb +25 -4
  29. data/lib/action_controller/metal/helpers.rb +5 -9
  30. data/lib/action_controller/metal/hide_actions.rb +0 -1
  31. data/lib/action_controller/metal/http_authentication.rb +107 -83
  32. data/lib/action_controller/metal/implicit_render.rb +1 -1
  33. data/lib/action_controller/metal/instrumentation.rb +2 -1
  34. data/lib/action_controller/metal/live.rb +175 -0
  35. data/lib/action_controller/metal/mime_responds.rb +161 -47
  36. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  37. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  38. data/lib/action_controller/metal/redirecting.rb +15 -20
  39. data/lib/action_controller/metal/renderers.rb +11 -9
  40. data/lib/action_controller/metal/rendering.rb +9 -1
  41. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  42. data/lib/action_controller/metal/responder.rb +20 -19
  43. data/lib/action_controller/metal/streaming.rb +12 -18
  44. data/lib/action_controller/metal/strong_parameters.rb +520 -0
  45. data/lib/action_controller/metal/testing.rb +13 -18
  46. data/lib/action_controller/metal/url_for.rb +28 -25
  47. data/lib/action_controller/metal.rb +17 -32
  48. data/lib/action_controller/model_naming.rb +12 -0
  49. data/lib/action_controller/railtie.rb +33 -17
  50. data/lib/action_controller/railties/helpers.rb +22 -0
  51. data/lib/action_controller/record_identifier.rb +18 -72
  52. data/lib/action_controller/test_case.rb +251 -131
  53. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  54. data/lib/action_controller.rb +15 -6
  55. data/lib/action_dispatch/http/cache.rb +63 -11
  56. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  57. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  58. data/lib/action_dispatch/http/headers.rb +49 -17
  59. data/lib/action_dispatch/http/mime_negotiation.rb +24 -1
  60. data/lib/action_dispatch/http/mime_type.rb +154 -100
  61. data/lib/action_dispatch/http/mime_types.rb +1 -1
  62. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  63. data/lib/action_dispatch/http/parameters.rb +28 -28
  64. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  65. data/lib/action_dispatch/http/request.rb +64 -18
  66. data/lib/action_dispatch/http/response.rb +130 -35
  67. data/lib/action_dispatch/http/upload.rb +63 -20
  68. data/lib/action_dispatch/http/url.rb +98 -35
  69. data/lib/action_dispatch/journey/backwards.rb +5 -0
  70. data/lib/action_dispatch/journey/formatter.rb +146 -0
  71. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  72. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  73. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  74. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  75. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  76. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  77. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  78. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  79. data/lib/action_dispatch/journey/parser.rb +206 -0
  80. data/lib/action_dispatch/journey/parser.y +47 -0
  81. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  82. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  83. data/lib/action_dispatch/journey/route.rb +124 -0
  84. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  85. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  86. data/lib/action_dispatch/journey/router.rb +166 -0
  87. data/lib/action_dispatch/journey/routes.rb +75 -0
  88. data/lib/action_dispatch/journey/scanner.rb +61 -0
  89. data/lib/action_dispatch/journey/visitors.rb +197 -0
  90. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  91. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  92. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  93. data/lib/action_dispatch/journey.rb +5 -0
  94. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  95. data/lib/action_dispatch/middleware/cookies.rb +259 -114
  96. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  97. data/lib/action_dispatch/middleware/exception_wrapper.rb +29 -3
  98. data/lib/action_dispatch/middleware/flash.rb +58 -58
  99. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  100. data/lib/action_dispatch/middleware/public_exceptions.rb +30 -14
  101. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  102. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  103. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  104. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  105. data/lib/action_dispatch/middleware/session/cookie_store.rb +82 -28
  106. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  107. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  108. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  109. data/lib/action_dispatch/middleware/stack.rb +6 -1
  110. data/lib/action_dispatch/middleware/static.rb +2 -1
  111. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  112. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +7 -9
  114. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  115. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +127 -5
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  118. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  119. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  120. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  121. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  122. data/lib/action_dispatch/railtie.rb +16 -6
  123. data/lib/action_dispatch/request/session.rb +181 -0
  124. data/lib/action_dispatch/routing/inspector.rb +240 -0
  125. data/lib/action_dispatch/routing/mapper.rb +540 -291
  126. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  127. data/lib/action_dispatch/routing/redirection.rb +46 -29
  128. data/lib/action_dispatch/routing/route_set.rb +207 -164
  129. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  130. data/lib/action_dispatch/routing/url_for.rb +48 -33
  131. data/lib/action_dispatch/routing.rb +48 -83
  132. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  133. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  134. data/lib/action_dispatch/testing/assertions/routing.rb +42 -41
  135. data/lib/action_dispatch/testing/assertions/selector.rb +17 -22
  136. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  137. data/lib/action_dispatch/testing/integration.rb +65 -51
  138. data/lib/action_dispatch/testing/test_process.rb +9 -6
  139. data/lib/action_dispatch/testing/test_request.rb +7 -3
  140. data/lib/action_dispatch.rb +21 -15
  141. data/lib/action_pack/version.rb +7 -6
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_view/base.rb +15 -34
  144. data/lib/action_view/buffers.rb +7 -1
  145. data/lib/action_view/context.rb +4 -4
  146. data/lib/action_view/dependency_tracker.rb +93 -0
  147. data/lib/action_view/digestor.rb +85 -0
  148. data/lib/action_view/flows.rb +1 -4
  149. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  150. data/lib/action_view/helpers/asset_tag_helper.rb +215 -352
  151. data/lib/action_view/helpers/asset_url_helper.rb +355 -0
  152. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  153. data/lib/action_view/helpers/cache_helper.rb +150 -18
  154. data/lib/action_view/helpers/capture_helper.rb +44 -31
  155. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  156. data/lib/action_view/helpers/date_helper.rb +269 -248
  157. data/lib/action_view/helpers/debug_helper.rb +10 -11
  158. data/lib/action_view/helpers/form_helper.rb +931 -537
  159. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  160. data/lib/action_view/helpers/form_tag_helper.rb +190 -90
  161. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  162. data/lib/action_view/helpers/number_helper.rb +148 -329
  163. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  164. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  165. data/lib/action_view/helpers/rendering_helper.rb +2 -2
  166. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  167. data/lib/action_view/helpers/tag_helper.rb +46 -33
  168. data/lib/action_view/helpers/tags/base.rb +147 -0
  169. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  170. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  171. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  172. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  173. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  174. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  175. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  176. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  177. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  178. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  179. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  180. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  181. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  182. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  183. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  184. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  185. data/lib/action_view/helpers/tags/label.rb +65 -0
  186. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  187. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  188. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  189. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  190. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  191. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  192. data/lib/action_view/helpers/tags/select.rb +40 -0
  193. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  194. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  195. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  196. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  197. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  198. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  199. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  200. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  201. data/lib/action_view/helpers/tags.rb +39 -0
  202. data/lib/action_view/helpers/text_helper.rb +130 -114
  203. data/lib/action_view/helpers/translation_helper.rb +32 -16
  204. data/lib/action_view/helpers/url_helper.rb +211 -270
  205. data/lib/action_view/helpers.rb +2 -4
  206. data/lib/action_view/locale/en.yml +1 -105
  207. data/lib/action_view/log_subscriber.rb +6 -4
  208. data/lib/action_view/lookup_context.rb +15 -28
  209. data/lib/action_view/model_naming.rb +12 -0
  210. data/lib/action_view/path_set.rb +8 -20
  211. data/lib/action_view/railtie.rb +6 -22
  212. data/lib/action_view/record_identifier.rb +84 -0
  213. data/lib/action_view/renderer/abstract_renderer.rb +25 -19
  214. data/lib/action_view/renderer/partial_renderer.rb +158 -81
  215. data/lib/action_view/renderer/renderer.rb +8 -12
  216. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  217. data/lib/action_view/renderer/template_renderer.rb +12 -10
  218. data/lib/action_view/routing_url_for.rb +107 -0
  219. data/lib/action_view/template/error.rb +22 -12
  220. data/lib/action_view/template/handlers/builder.rb +1 -1
  221. data/lib/action_view/template/handlers/erb.rb +40 -19
  222. data/lib/action_view/template/handlers/raw.rb +11 -0
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/resolver.rb +107 -53
  225. data/lib/action_view/template/text.rb +12 -8
  226. data/lib/action_view/template/types.rb +57 -0
  227. data/lib/action_view/template.rb +25 -23
  228. data/lib/action_view/test_case.rb +67 -42
  229. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  230. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  231. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +13 -2
  232. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +9 -9
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  235. data/lib/action_view/vendor/html-scanner.rb +20 -0
  236. data/lib/action_view.rb +17 -8
  237. metadata +184 -214
  238. data/lib/action_controller/caching/actions.rb +0 -185
  239. data/lib/action_controller/caching/pages.rb +0 -187
  240. data/lib/action_controller/caching/sweeping.rb +0 -97
  241. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  242. data/lib/action_controller/metal/compatibility.rb +0 -65
  243. data/lib/action_controller/metal/session_management.rb +0 -14
  244. data/lib/action_controller/railties/paths.rb +0 -25
  245. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  246. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  247. data/lib/action_dispatch/middleware/head.rb +0 -18
  248. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  249. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  250. data/lib/action_view/asset_paths.rb +0 -142
  251. data/lib/action_view/helpers/asset_paths.rb +0 -7
  252. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  253. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  254. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  255. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  256. data/lib/sprockets/assets.rake +0 -99
  257. data/lib/sprockets/bootstrap.rb +0 -37
  258. data/lib/sprockets/compressors.rb +0 -83
  259. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  260. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/railtie.rb +0 -62
  263. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,5 +1,8 @@
1
+ require 'active_support/rails'
1
2
  require 'abstract_controller'
2
3
  require 'action_dispatch'
4
+ require 'action_controller/metal/live'
5
+ require 'action_controller/metal/strong_parameters'
3
6
 
4
7
  module ActionController
5
8
  extend ActiveSupport::Autoload
@@ -31,16 +34,14 @@ module ActionController
31
34
  autoload :RequestForgeryProtection
32
35
  autoload :Rescue
33
36
  autoload :Responder
34
- autoload :SessionManagement
35
37
  autoload :Streaming
38
+ autoload :StrongParameters
36
39
  autoload :Testing
37
40
  autoload :UrlFor
38
41
  end
39
42
 
40
43
  autoload :Integration, 'action_controller/deprecated/integration_test'
41
44
  autoload :IntegrationTest, 'action_controller/deprecated/integration_test'
42
- autoload :PerformanceTest, 'action_controller/deprecated/performance_test'
43
- autoload :UrlWriter, 'action_controller/deprecated'
44
45
  autoload :Routing, 'action_controller/deprecated'
45
46
  autoload :TestCase, 'action_controller/test_case'
46
47
  autoload :TemplateAssertions, 'action_controller/test_case'
@@ -48,18 +49,26 @@ module ActionController
48
49
  eager_autoload do
49
50
  autoload :RecordIdentifier
50
51
  end
52
+
53
+ def self.eager_load!
54
+ super
55
+ ActionController::Caching.eager_load!
56
+ HTML.eager_load!
57
+ end
51
58
  end
52
59
 
53
60
  # All of these simply register additional autoloads
54
61
  require 'action_view'
55
- require 'action_controller/vendor/html-scanner'
62
+ require 'action_view/vendor/html-scanner'
63
+
64
+ ActiveSupport.on_load(:action_view) do
65
+ ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
66
+ end
56
67
 
57
68
  # Common Active Support usage in Action Controller
58
- require 'active_support/concern'
59
69
  require 'active_support/core_ext/class/attribute_accessors'
60
70
  require 'active_support/core_ext/load_error'
61
71
  require 'active_support/core_ext/module/attr_internal'
62
- require 'active_support/core_ext/module/delegation'
63
72
  require 'active_support/core_ext/name_error'
64
73
  require 'active_support/core_ext/uri'
65
74
  require 'active_support/inflector'
@@ -1,4 +1,3 @@
1
- require 'active_support/core_ext/object/blank'
2
1
 
3
2
  module ActionDispatch
4
3
  module Http
@@ -18,12 +17,21 @@ module ActionDispatch
18
17
  env[HTTP_IF_NONE_MATCH]
19
18
  end
20
19
 
20
+ def if_none_match_etags
21
+ (if_none_match ? if_none_match.split(/\s*,\s*/) : []).collect do |etag|
22
+ etag.gsub(/^\"|\"$/, "")
23
+ end
24
+ end
25
+
21
26
  def not_modified?(modified_at)
22
27
  if_modified_since && modified_at && if_modified_since >= modified_at
23
28
  end
24
29
 
25
30
  def etag_matches?(etag)
26
- if_none_match && if_none_match == etag
31
+ if etag
32
+ etag = etag.gsub(/^\"|\"$/, "")
33
+ if_none_match_etags.include?(etag)
34
+ end
27
35
  end
28
36
 
29
37
  # Check response freshness (Last-Modified and ETag) against request
@@ -60,6 +68,20 @@ module ActionDispatch
60
68
  headers[LAST_MODIFIED] = utc_time.httpdate
61
69
  end
62
70
 
71
+ def date
72
+ if date_header = headers['Date']
73
+ Time.httpdate(date_header)
74
+ end
75
+ end
76
+
77
+ def date?
78
+ headers.include?('Date')
79
+ end
80
+
81
+ def date=(utc_time)
82
+ headers['Date'] = utc_time.httpdate
83
+ end
84
+
63
85
  def etag=(etag)
64
86
  key = ActiveSupport::Cache.expand_cache_key(etag)
65
87
  @etag = self[ETAG] = %("#{Digest::MD5.hexdigest(key)}")
@@ -70,17 +92,37 @@ module ActionDispatch
70
92
  LAST_MODIFIED = "Last-Modified".freeze
71
93
  ETAG = "ETag".freeze
72
94
  CACHE_CONTROL = "Cache-Control".freeze
95
+ SPECIAL_KEYS = %w[extras no-cache max-age public must-revalidate]
73
96
 
74
- def prepare_cache_control!
75
- @cache_control = {}
76
- @etag = self[ETAG]
77
-
97
+ def cache_control_segments
78
98
  if cache_control = self[CACHE_CONTROL]
79
- cache_control.split(/,\s*/).each do |segment|
80
- first, last = segment.split("=")
81
- @cache_control[first.to_sym] = last || true
99
+ cache_control.delete(' ').split(',')
100
+ else
101
+ []
102
+ end
103
+ end
104
+
105
+ def cache_control_headers
106
+ cache_control = {}
107
+
108
+ cache_control_segments.each do |segment|
109
+ directive, argument = segment.split('=', 2)
110
+
111
+ if SPECIAL_KEYS.include? directive
112
+ key = directive.tr('-', '_')
113
+ cache_control[key.to_sym] = argument || true
114
+ else
115
+ cache_control[:extras] ||= []
116
+ cache_control[:extras] << segment
82
117
  end
83
118
  end
119
+
120
+ cache_control
121
+ end
122
+
123
+ def prepare_cache_control!
124
+ @cache_control = cache_control_headers
125
+ @etag = self[ETAG]
84
126
  end
85
127
 
86
128
  def handle_conditional_get!
@@ -96,14 +138,24 @@ module ActionDispatch
96
138
  MUST_REVALIDATE = "must-revalidate".freeze
97
139
 
98
140
  def set_conditional_cache_control!
99
- return if self[CACHE_CONTROL].present?
141
+ control = {}
142
+ cc_headers = cache_control_headers
143
+ if extras = cc_headers.delete(:extras)
144
+ @cache_control[:extras] ||= []
145
+ @cache_control[:extras] += extras
146
+ @cache_control[:extras].uniq!
147
+ end
100
148
 
101
- control = @cache_control
149
+ control.merge! cc_headers
150
+ control.merge! @cache_control
102
151
 
103
152
  if control.empty?
104
153
  headers[CACHE_CONTROL] = DEFAULT_CACHE_CONTROL
105
154
  elsif control[:no_cache]
106
155
  headers[CACHE_CONTROL] = NO_CACHE
156
+ if control[:extras]
157
+ headers[CACHE_CONTROL] += ", #{control[:extras].join(', ')}"
158
+ end
107
159
  else
108
160
  extras = control[:extras]
109
161
  max_age = control[:max_age]
@@ -1,6 +1,6 @@
1
- require 'active_support/core_ext/object/blank'
2
1
  require 'active_support/core_ext/hash/keys'
3
2
  require 'active_support/core_ext/object/duplicable'
3
+ require 'action_dispatch/http/parameter_filter'
4
4
 
5
5
  module ActionDispatch
6
6
  module Http
@@ -10,8 +10,6 @@ module ActionDispatch
10
10
  # value of the params hash and all subhashes is passed to it, the value
11
11
  # or key can be replaced using String#replace or similar method.
12
12
  #
13
- # Examples:
14
- #
15
13
  # env["action_dispatch.parameter_filter"] = [:password]
16
14
  # => replaces the value to all keys matching /password/i with "[FILTERED]"
17
15
  #
@@ -22,9 +20,17 @@ module ActionDispatch
22
20
  # v.reverse! if k =~ /secret/i
23
21
  # end
24
22
  # => reverses the value to all keys matching /secret/i
25
- #
26
23
  module FilterParameters
27
- extend ActiveSupport::Concern
24
+ ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
25
+ NULL_PARAM_FILTER = ParameterFilter.new # :nodoc:
26
+ NULL_ENV_FILTER = ParameterFilter.new ENV_MATCH # :nodoc:
27
+
28
+ def initialize(env)
29
+ super
30
+ @filtered_parameters = nil
31
+ @filtered_env = nil
32
+ @filtered_path = nil
33
+ end
28
34
 
29
35
  # Return a hash of parameters with all sensitive data replaced.
30
36
  def filtered_parameters
@@ -44,11 +50,16 @@ module ActionDispatch
44
50
  protected
45
51
 
46
52
  def parameter_filter
47
- parameter_filter_for(@env["action_dispatch.parameter_filter"])
53
+ parameter_filter_for @env.fetch("action_dispatch.parameter_filter") {
54
+ return NULL_PARAM_FILTER
55
+ }
48
56
  end
49
57
 
50
58
  def env_filter
51
- parameter_filter_for(Array.wrap(@env["action_dispatch.parameter_filter"]) << /RAW_POST_DATA/)
59
+ user_key = @env.fetch("action_dispatch.parameter_filter") {
60
+ return NULL_ENV_FILTER
61
+ }
62
+ parameter_filter_for(Array(user_key) + ENV_MATCH)
52
63
  end
53
64
 
54
65
  def parameter_filter_for(filters)
@@ -62,7 +73,6 @@ module ActionDispatch
62
73
  parameter_filter.filter([[$1, $2]]).first.join("=")
63
74
  end
64
75
  end
65
-
66
76
  end
67
77
  end
68
78
  end
@@ -0,0 +1,37 @@
1
+ module ActionDispatch
2
+ module Http
3
+ module FilterRedirect
4
+
5
+ FILTERED = '[FILTERED]'.freeze # :nodoc:
6
+
7
+ def filtered_location
8
+ if !location_filter.empty? && location_filter_match?
9
+ FILTERED
10
+ else
11
+ location
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def location_filter
18
+ if request.present?
19
+ request.env['action_dispatch.redirect_filter'] || []
20
+ else
21
+ []
22
+ end
23
+ end
24
+
25
+ def location_filter_match?
26
+ location_filter.any? do |filter|
27
+ if String === filter
28
+ location.include?(filter)
29
+ elsif Regexp === filter
30
+ location.match(filter)
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -1,31 +1,63 @@
1
1
  module ActionDispatch
2
2
  module Http
3
- class Headers < ::Hash
4
- @@env_cache = Hash.new { |h,k| h[k] = "HTTP_#{k.upcase.gsub(/-/, '_')}" }
3
+ class Headers
4
+ CGI_VARIABLES = %w(
5
+ CONTENT_TYPE CONTENT_LENGTH
6
+ HTTPS AUTH_TYPE GATEWAY_INTERFACE
7
+ PATH_INFO PATH_TRANSLATED QUERY_STRING
8
+ REMOTE_ADDR REMOTE_HOST REMOTE_IDENT REMOTE_USER
9
+ REQUEST_METHOD SCRIPT_NAME
10
+ SERVER_NAME SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE
11
+ )
12
+ HTTP_HEADER = /\A[A-Za-z0-9-]+\z/
5
13
 
6
- def initialize(*args)
14
+ include Enumerable
15
+ attr_reader :env
7
16
 
8
- if args.size == 1 && args[0].is_a?(Hash)
9
- super()
10
- update(args[0])
11
- else
12
- super
13
- end
17
+ def initialize(env = {})
18
+ @env = env
19
+ end
20
+
21
+ def [](key)
22
+ @env[env_name(key)]
14
23
  end
15
24
 
16
- def [](header_name)
17
- if include?(header_name)
18
- super
19
- else
20
- super(env_name(header_name))
25
+ def []=(key, value)
26
+ @env[env_name(key)] = value
27
+ end
28
+
29
+ def key?(key); @env.key? key; end
30
+ alias :include? :key?
31
+
32
+ def fetch(key, *args, &block)
33
+ @env.fetch env_name(key), *args, &block
34
+ end
35
+
36
+ def each(&block)
37
+ @env.each(&block)
38
+ end
39
+
40
+ def merge(headers_or_env)
41
+ headers = Http::Headers.new(env.dup)
42
+ headers.merge!(headers_or_env)
43
+ headers
44
+ end
45
+
46
+ def merge!(headers_or_env)
47
+ headers_or_env.each do |key, value|
48
+ self[env_name(key)] = value
21
49
  end
22
50
  end
23
51
 
24
52
  private
25
- # Converts a HTTP header name to an environment variable name.
26
- def env_name(header_name)
27
- @@env_cache[header_name]
53
+ def env_name(key)
54
+ key = key.to_s
55
+ if key =~ HTTP_HEADER
56
+ key = key.upcase.tr('-', '_')
57
+ key = "HTTP_" + key unless CGI_VARIABLES.include?(key)
28
58
  end
59
+ key
60
+ end
29
61
  end
30
62
  end
31
63
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+
1
3
  module ActionDispatch
2
4
  module Http
3
5
  module MimeNegotiation
@@ -66,7 +68,7 @@ module ActionDispatch
66
68
  # that are not controlled by the extension.
67
69
  #
68
70
  # class ApplicationController < ActionController::Base
69
- # before_filter :adjust_format_for_iphone
71
+ # before_action :adjust_format_for_iphone
70
72
  #
71
73
  # private
72
74
  # def adjust_format_for_iphone
@@ -78,6 +80,27 @@ module ActionDispatch
78
80
  @env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])]
79
81
  end
80
82
 
83
+ # Sets the \formats by string extensions. This differs from #format= by allowing you
84
+ # to set multiple, ordered formats, which is useful when you want to have a fallback.
85
+ #
86
+ # In this example, the :iphone format will be used if it's available, otherwise it'll fallback
87
+ # to the :html format.
88
+ #
89
+ # class ApplicationController < ActionController::Base
90
+ # before_action :adjust_format_for_iphone_with_html_fallback
91
+ #
92
+ # private
93
+ # def adjust_format_for_iphone_with_html_fallback
94
+ # request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
95
+ # end
96
+ # end
97
+ def formats=(extensions)
98
+ parameters[:format] = extensions.first.to_s
99
+ @env["action_dispatch.request.formats"] = extensions.collect do |extension|
100
+ Mime::Type.lookup_by_extension(extension)
101
+ end
102
+ end
103
+
81
104
  # Receives an array of mimes and return the first user sent mime that
82
105
  # matches the order array.
83
106
  #