actionpack 3.2.19 → 4.2.11.3

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 (244) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +412 -503
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +11 -294
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +52 -18
  7. data/lib/abstract_controller/callbacks.rb +87 -89
  8. data/lib/abstract_controller/collector.rb +17 -3
  9. data/lib/abstract_controller/helpers.rb +41 -14
  10. data/lib/abstract_controller/logger.rb +1 -2
  11. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  12. data/lib/abstract_controller/rendering.rb +65 -118
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +7 -7
  15. data/lib/abstract_controller.rb +2 -10
  16. data/lib/action_controller/base.rb +61 -28
  17. data/lib/action_controller/caching/fragments.rb +30 -54
  18. data/lib/action_controller/caching.rb +38 -35
  19. data/lib/action_controller/log_subscriber.rb +35 -18
  20. data/lib/action_controller/metal/conditional_get.rb +103 -34
  21. data/lib/action_controller/metal/data_streaming.rb +20 -26
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  23. data/lib/action_controller/metal/exceptions.rb +19 -6
  24. data/lib/action_controller/metal/flash.rb +41 -9
  25. data/lib/action_controller/metal/force_ssl.rb +70 -12
  26. data/lib/action_controller/metal/head.rb +30 -7
  27. data/lib/action_controller/metal/helpers.rb +11 -11
  28. data/lib/action_controller/metal/hide_actions.rb +0 -1
  29. data/lib/action_controller/metal/http_authentication.rb +140 -94
  30. data/lib/action_controller/metal/implicit_render.rb +1 -1
  31. data/lib/action_controller/metal/instrumentation.rb +11 -7
  32. data/lib/action_controller/metal/live.rb +328 -0
  33. data/lib/action_controller/metal/mime_responds.rb +161 -152
  34. data/lib/action_controller/metal/params_wrapper.rb +126 -81
  35. data/lib/action_controller/metal/rack_delegation.rb +10 -4
  36. data/lib/action_controller/metal/redirecting.rb +44 -41
  37. data/lib/action_controller/metal/renderers.rb +48 -19
  38. data/lib/action_controller/metal/rendering.rb +46 -11
  39. data/lib/action_controller/metal/request_forgery_protection.rb +250 -29
  40. data/lib/action_controller/metal/streaming.rb +30 -38
  41. data/lib/action_controller/metal/strong_parameters.rb +669 -0
  42. data/lib/action_controller/metal/testing.rb +12 -18
  43. data/lib/action_controller/metal/url_for.rb +31 -29
  44. data/lib/action_controller/metal.rb +31 -40
  45. data/lib/action_controller/model_naming.rb +12 -0
  46. data/lib/action_controller/railtie.rb +38 -18
  47. data/lib/action_controller/railties/helpers.rb +22 -0
  48. data/lib/action_controller/test_case.rb +359 -173
  49. data/lib/action_controller.rb +9 -16
  50. data/lib/action_dispatch/http/cache.rb +64 -11
  51. data/lib/action_dispatch/http/filter_parameters.rb +20 -10
  52. data/lib/action_dispatch/http/filter_redirect.rb +38 -0
  53. data/lib/action_dispatch/http/headers.rb +85 -17
  54. data/lib/action_dispatch/http/mime_negotiation.rb +55 -5
  55. data/lib/action_dispatch/http/mime_type.rb +167 -114
  56. data/lib/action_dispatch/http/mime_types.rb +2 -1
  57. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  58. data/lib/action_dispatch/http/parameters.rb +30 -46
  59. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  60. data/lib/action_dispatch/http/request.rb +108 -45
  61. data/lib/action_dispatch/http/response.rb +247 -48
  62. data/lib/action_dispatch/http/upload.rb +60 -29
  63. data/lib/action_dispatch/http/url.rb +135 -45
  64. data/lib/action_dispatch/journey/backwards.rb +5 -0
  65. data/lib/action_dispatch/journey/formatter.rb +166 -0
  66. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  67. data/lib/action_dispatch/journey/gtg/simulator.rb +47 -0
  68. data/lib/action_dispatch/journey/gtg/transition_table.rb +157 -0
  69. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  70. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  71. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  72. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  73. data/lib/action_dispatch/journey/nodes/node.rb +128 -0
  74. data/lib/action_dispatch/journey/parser.rb +198 -0
  75. data/lib/action_dispatch/journey/parser.y +49 -0
  76. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  77. data/lib/action_dispatch/journey/path/pattern.rb +193 -0
  78. data/lib/action_dispatch/journey/route.rb +125 -0
  79. data/lib/action_dispatch/journey/router/strexp.rb +27 -0
  80. data/lib/action_dispatch/journey/router/utils.rb +93 -0
  81. data/lib/action_dispatch/journey/router.rb +144 -0
  82. data/lib/action_dispatch/journey/routes.rb +80 -0
  83. data/lib/action_dispatch/journey/scanner.rb +61 -0
  84. data/lib/action_dispatch/journey/visitors.rb +221 -0
  85. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  86. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  87. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  88. data/lib/action_dispatch/journey.rb +5 -0
  89. data/lib/action_dispatch/middleware/callbacks.rb +16 -11
  90. data/lib/action_dispatch/middleware/cookies.rb +346 -125
  91. data/lib/action_dispatch/middleware/debug_exceptions.rb +52 -24
  92. data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -9
  93. data/lib/action_dispatch/middleware/flash.rb +85 -72
  94. data/lib/action_dispatch/middleware/params_parser.rb +16 -31
  95. data/lib/action_dispatch/middleware/public_exceptions.rb +39 -14
  96. data/lib/action_dispatch/middleware/reloader.rb +16 -7
  97. data/lib/action_dispatch/middleware/remote_ip.rb +132 -40
  98. data/lib/action_dispatch/middleware/request_id.rb +3 -7
  99. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  100. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  101. data/lib/action_dispatch/middleware/session/cookie_store.rb +84 -29
  102. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  103. data/lib/action_dispatch/middleware/show_exceptions.rb +15 -44
  104. data/lib/action_dispatch/middleware/ssl.rb +72 -0
  105. data/lib/action_dispatch/middleware/stack.rb +6 -1
  106. data/lib/action_dispatch/middleware/static.rb +80 -23
  107. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +34 -0
  108. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  109. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +27 -0
  110. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  111. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  112. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  114. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +133 -5
  115. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  125. data/lib/action_dispatch/railtie.rb +19 -6
  126. data/lib/action_dispatch/request/session.rb +193 -0
  127. data/lib/action_dispatch/request/utils.rb +35 -0
  128. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  129. data/lib/action_dispatch/routing/inspector.rb +234 -0
  130. data/lib/action_dispatch/routing/mapper.rb +897 -436
  131. data/lib/action_dispatch/routing/polymorphic_routes.rb +213 -92
  132. data/lib/action_dispatch/routing/redirection.rb +97 -37
  133. data/lib/action_dispatch/routing/route_set.rb +432 -239
  134. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  135. data/lib/action_dispatch/routing/url_for.rb +63 -34
  136. data/lib/action_dispatch/routing.rb +57 -89
  137. data/lib/action_dispatch/testing/assertions/dom.rb +2 -36
  138. data/lib/action_dispatch/testing/assertions/response.rb +24 -38
  139. data/lib/action_dispatch/testing/assertions/routing.rb +55 -54
  140. data/lib/action_dispatch/testing/assertions/selector.rb +2 -434
  141. data/lib/action_dispatch/testing/assertions/tag.rb +2 -137
  142. data/lib/action_dispatch/testing/assertions.rb +11 -7
  143. data/lib/action_dispatch/testing/integration.rb +88 -72
  144. data/lib/action_dispatch/testing/test_process.rb +9 -6
  145. data/lib/action_dispatch/testing/test_request.rb +13 -9
  146. data/lib/action_dispatch/testing/test_response.rb +1 -5
  147. data/lib/action_dispatch.rb +24 -21
  148. data/lib/action_pack/gem_version.rb +15 -0
  149. data/lib/action_pack/version.rb +5 -7
  150. data/lib/action_pack.rb +1 -1
  151. metadata +181 -292
  152. data/lib/abstract_controller/layouts.rb +0 -423
  153. data/lib/abstract_controller/view_paths.rb +0 -96
  154. data/lib/action_controller/caching/actions.rb +0 -185
  155. data/lib/action_controller/caching/pages.rb +0 -187
  156. data/lib/action_controller/caching/sweeping.rb +0 -97
  157. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  158. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  159. data/lib/action_controller/deprecated.rb +0 -3
  160. data/lib/action_controller/metal/compatibility.rb +0 -65
  161. data/lib/action_controller/metal/responder.rb +0 -286
  162. data/lib/action_controller/metal/session_management.rb +0 -14
  163. data/lib/action_controller/railties/paths.rb +0 -25
  164. data/lib/action_controller/record_identifier.rb +0 -85
  165. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  166. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  167. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  168. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  169. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  170. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  171. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  172. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  173. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  174. data/lib/action_dispatch/middleware/head.rb +0 -18
  175. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  176. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  177. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  178. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  179. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  180. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  181. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  182. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  183. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  184. data/lib/action_view/asset_paths.rb +0 -142
  185. data/lib/action_view/base.rb +0 -220
  186. data/lib/action_view/buffers.rb +0 -43
  187. data/lib/action_view/context.rb +0 -36
  188. data/lib/action_view/flows.rb +0 -79
  189. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  190. data/lib/action_view/helpers/asset_paths.rb +0 -7
  191. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  192. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  193. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  194. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  195. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  196. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  197. data/lib/action_view/helpers/cache_helper.rb +0 -64
  198. data/lib/action_view/helpers/capture_helper.rb +0 -203
  199. data/lib/action_view/helpers/controller_helper.rb +0 -25
  200. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  201. data/lib/action_view/helpers/date_helper.rb +0 -1062
  202. data/lib/action_view/helpers/debug_helper.rb +0 -40
  203. data/lib/action_view/helpers/form_helper.rb +0 -1486
  204. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  205. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  206. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  207. data/lib/action_view/helpers/number_helper.rb +0 -622
  208. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  209. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  210. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  211. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  212. data/lib/action_view/helpers/tag_helper.rb +0 -160
  213. data/lib/action_view/helpers/text_helper.rb +0 -426
  214. data/lib/action_view/helpers/translation_helper.rb +0 -91
  215. data/lib/action_view/helpers/url_helper.rb +0 -693
  216. data/lib/action_view/helpers.rb +0 -60
  217. data/lib/action_view/locale/en.yml +0 -160
  218. data/lib/action_view/log_subscriber.rb +0 -28
  219. data/lib/action_view/lookup_context.rb +0 -254
  220. data/lib/action_view/path_set.rb +0 -89
  221. data/lib/action_view/railtie.rb +0 -55
  222. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  223. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  224. data/lib/action_view/renderer/renderer.rb +0 -54
  225. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  226. data/lib/action_view/renderer/template_renderer.rb +0 -94
  227. data/lib/action_view/template/error.rb +0 -128
  228. data/lib/action_view/template/handlers/builder.rb +0 -26
  229. data/lib/action_view/template/handlers/erb.rb +0 -125
  230. data/lib/action_view/template/handlers.rb +0 -50
  231. data/lib/action_view/template/resolver.rb +0 -272
  232. data/lib/action_view/template/text.rb +0 -30
  233. data/lib/action_view/template.rb +0 -337
  234. data/lib/action_view/test_case.rb +0 -245
  235. data/lib/action_view/testing/resolvers.rb +0 -50
  236. data/lib/action_view.rb +0 -84
  237. data/lib/sprockets/assets.rake +0 -99
  238. data/lib/sprockets/bootstrap.rb +0 -37
  239. data/lib/sprockets/compressors.rb +0 -83
  240. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  241. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  242. data/lib/sprockets/helpers.rb +0 -6
  243. data/lib/sprockets/railtie.rb +0 -62
  244. 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
@@ -14,6 +17,7 @@ module ActionController
14
17
  autoload :ConditionalGet
15
18
  autoload :Cookies
16
19
  autoload :DataStreaming
20
+ autoload :EtagWithTemplateDigest
17
21
  autoload :Flash
18
22
  autoload :ForceSSL
19
23
  autoload :Head
@@ -30,36 +34,25 @@ module ActionController
30
34
  autoload :Rendering
31
35
  autoload :RequestForgeryProtection
32
36
  autoload :Rescue
33
- 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
- autoload :Integration, 'action_controller/deprecated/integration_test'
41
- autoload :IntegrationTest, 'action_controller/deprecated/integration_test'
42
- autoload :PerformanceTest, 'action_controller/deprecated/performance_test'
43
- autoload :UrlWriter, 'action_controller/deprecated'
44
- autoload :Routing, 'action_controller/deprecated'
45
43
  autoload :TestCase, 'action_controller/test_case'
46
44
  autoload :TemplateAssertions, 'action_controller/test_case'
47
45
 
48
- eager_autoload do
49
- autoload :RecordIdentifier
46
+ def self.eager_load!
47
+ super
48
+ ActionController::Caching.eager_load!
50
49
  end
51
50
  end
52
51
 
53
- # All of these simply register additional autoloads
54
- require 'action_view'
55
- require 'action_controller/vendor/html-scanner'
56
-
57
52
  # Common Active Support usage in Action Controller
58
- require 'active_support/concern'
59
- require 'active_support/core_ext/class/attribute_accessors'
53
+ require 'active_support/core_ext/module/attribute_accessors'
60
54
  require 'active_support/core_ext/load_error'
61
55
  require 'active_support/core_ext/module/attr_internal'
62
- require 'active_support/core_ext/module/delegation'
63
56
  require 'active_support/core_ext/name_error'
64
57
  require 'active_support/core_ext/uri'
65
58
  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)}")
@@ -67,20 +89,41 @@ module ActionDispatch
67
89
 
68
90
  private
69
91
 
92
+ DATE = 'Date'.freeze
70
93
  LAST_MODIFIED = "Last-Modified".freeze
71
94
  ETAG = "ETag".freeze
72
95
  CACHE_CONTROL = "Cache-Control".freeze
96
+ SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate])
73
97
 
74
- def prepare_cache_control!
75
- @cache_control = {}
76
- @etag = self[ETAG]
77
-
98
+ def cache_control_segments
78
99
  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
100
+ cache_control.delete(' ').split(',')
101
+ else
102
+ []
103
+ end
104
+ end
105
+
106
+ def cache_control_headers
107
+ cache_control = {}
108
+
109
+ cache_control_segments.each do |segment|
110
+ directive, argument = segment.split('=', 2)
111
+
112
+ if SPECIAL_KEYS.include? directive
113
+ key = directive.tr('-', '_')
114
+ cache_control[key.to_sym] = argument || true
115
+ else
116
+ cache_control[:extras] ||= []
117
+ cache_control[:extras] << segment
82
118
  end
83
119
  end
120
+
121
+ cache_control
122
+ end
123
+
124
+ def prepare_cache_control!
125
+ @cache_control = cache_control_headers
126
+ @etag = self[ETAG]
84
127
  end
85
128
 
86
129
  def handle_conditional_get!
@@ -96,14 +139,24 @@ module ActionDispatch
96
139
  MUST_REVALIDATE = "must-revalidate".freeze
97
140
 
98
141
  def set_conditional_cache_control!
99
- return if self[CACHE_CONTROL].present?
142
+ control = {}
143
+ cc_headers = cache_control_headers
144
+ if extras = cc_headers.delete(:extras)
145
+ @cache_control[:extras] ||= []
146
+ @cache_control[:extras] += extras
147
+ @cache_control[:extras].uniq!
148
+ end
100
149
 
101
- control = @cache_control
150
+ control.merge! cc_headers
151
+ control.merge! @cache_control
102
152
 
103
153
  if control.empty?
104
154
  headers[CACHE_CONTROL] = DEFAULT_CACHE_CONTROL
105
155
  elsif control[:no_cache]
106
156
  headers[CACHE_CONTROL] = NO_CACHE
157
+ if control[:extras]
158
+ headers[CACHE_CONTROL] += ", #{control[:extras].join(', ')}"
159
+ end
107
160
  else
108
161
  extras = control[:extras]
109
162
  max_age = control[:max_age]
@@ -1,17 +1,15 @@
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
7
7
  # Allows you to specify sensitive parameters which will be replaced from
8
8
  # the request log by looking in the query string of the request and all
9
- # subhashes of the params hash to filter. If a block is given, each key and
10
- # value of the params hash and all subhashes is passed to it, the value
9
+ # sub-hashes of the params hash to filter. If a block is given, each key and
10
+ # value of the params hash and all sub-hashes 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,38 @@
1
+ module ActionDispatch
2
+ module Http
3
+ module FilterRedirect
4
+
5
+ FILTERED = '[FILTERED]'.freeze # :nodoc:
6
+
7
+ def filtered_location
8
+ filters = location_filter
9
+ if !filters.empty? && location_filter_match?(filters)
10
+ FILTERED
11
+ else
12
+ location
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def location_filter
19
+ if request
20
+ request.env['action_dispatch.redirect_filter'] || []
21
+ else
22
+ []
23
+ end
24
+ end
25
+
26
+ def location_filter_match?(filters)
27
+ filters.any? do |filter|
28
+ if String === filter
29
+ location.include?(filter)
30
+ elsif Regexp === filter
31
+ location.match(filter)
32
+ end
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -1,31 +1,99 @@
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
+ # Provides access to the request's HTTP headers from the environment.
4
+ #
5
+ # env = { "CONTENT_TYPE" => "text/plain" }
6
+ # headers = ActionDispatch::Http::Headers.new(env)
7
+ # headers["Content-Type"] # => "text/plain"
8
+ class Headers
9
+ CGI_VARIABLES = Set.new(%W[
10
+ AUTH_TYPE
11
+ CONTENT_LENGTH
12
+ CONTENT_TYPE
13
+ GATEWAY_INTERFACE
14
+ HTTPS
15
+ PATH_INFO
16
+ PATH_TRANSLATED
17
+ QUERY_STRING
18
+ REMOTE_ADDR
19
+ REMOTE_HOST
20
+ REMOTE_IDENT
21
+ REMOTE_USER
22
+ REQUEST_METHOD
23
+ SCRIPT_NAME
24
+ SERVER_NAME
25
+ SERVER_PORT
26
+ SERVER_PROTOCOL
27
+ SERVER_SOFTWARE
28
+ ]).freeze
5
29
 
6
- def initialize(*args)
30
+ HTTP_HEADER = /\A[A-Za-z0-9-]+\z/
7
31
 
8
- if args.size == 1 && args[0].is_a?(Hash)
9
- super()
10
- update(args[0])
11
- else
12
- super
13
- end
32
+ include Enumerable
33
+ attr_reader :env
34
+
35
+ def initialize(env = {}) # :nodoc:
36
+ @env = env
37
+ end
38
+
39
+ # Returns the value for the given key mapped to @env.
40
+ def [](key)
41
+ @env[env_name(key)]
42
+ end
43
+
44
+ # Sets the given value for the key mapped to @env.
45
+ def []=(key, value)
46
+ @env[env_name(key)] = value
47
+ end
48
+
49
+ def key?(key)
50
+ @env.key? env_name(key)
14
51
  end
52
+ alias :include? :key?
15
53
 
16
- def [](header_name)
17
- if include?(header_name)
18
- super
19
- else
20
- super(env_name(header_name))
54
+ # Returns the value for the given key mapped to @env.
55
+ #
56
+ # If the key is not found and an optional code block is not provided,
57
+ # raises a <tt>KeyError</tt> exception.
58
+ #
59
+ # If the code block is provided, then it will be run and
60
+ # its result returned.
61
+ def fetch(key, *args, &block)
62
+ @env.fetch env_name(key), *args, &block
63
+ end
64
+
65
+ def each(&block)
66
+ @env.each(&block)
67
+ end
68
+
69
+ # Returns a new Http::Headers instance containing the contents of
70
+ # <tt>headers_or_env</tt> and the original instance.
71
+ def merge(headers_or_env)
72
+ headers = Http::Headers.new(env.dup)
73
+ headers.merge!(headers_or_env)
74
+ headers
75
+ end
76
+
77
+ # Adds the contents of <tt>headers_or_env</tt> to original instance
78
+ # entries; duplicate keys are overwritten with the values from
79
+ # <tt>headers_or_env</tt>.
80
+ def merge!(headers_or_env)
81
+ headers_or_env.each do |key, value|
82
+ self[env_name(key)] = value
21
83
  end
22
84
  end
23
85
 
24
86
  private
25
- # Converts a HTTP header name to an environment variable name.
26
- def env_name(header_name)
27
- @@env_cache[header_name]
87
+ # Converts a HTTP header name to an environment variable name if it is
88
+ # not contained within the headers hash.
89
+ def env_name(key)
90
+ key = key.to_s
91
+ if key =~ HTTP_HEADER
92
+ key = key.upcase.tr('-', '_')
93
+ key = "HTTP_" + key unless CGI_VARIABLES.include?(key)
28
94
  end
95
+ key
96
+ end
29
97
  end
30
98
  end
31
99
  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
@@ -8,6 +10,8 @@ module ActionDispatch
8
10
  self.ignore_accept_header = false
9
11
  end
10
12
 
13
+ attr_reader :variant
14
+
11
15
  # The MIME type of the HTTP request, such as Mime::XML.
12
16
  #
13
17
  # For backward compatibility, the post \format is extracted from the
@@ -46,12 +50,18 @@ module ActionDispatch
46
50
  # GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first
47
51
  #
48
52
  def format(view_path = [])
49
- formats.first
53
+ formats.first || Mime::NullType.instance
50
54
  end
51
55
 
52
56
  def formats
53
- @env["action_dispatch.request.formats"] ||=
54
- if parameters[:format]
57
+ @env["action_dispatch.request.formats"] ||= begin
58
+ params_readable = begin
59
+ parameters[:format]
60
+ rescue ActionController::BadRequest
61
+ false
62
+ end
63
+
64
+ v = if params_readable
55
65
  Array(Mime[parameters[:format]])
56
66
  elsif use_accept_header && valid_accept_header
57
67
  accepts
@@ -60,13 +70,32 @@ module ActionDispatch
60
70
  else
61
71
  [Mime::HTML]
62
72
  end
73
+
74
+ v.select do |format|
75
+ format.symbol || format.ref == "*/*"
76
+ end
77
+ end
78
+ end
79
+
80
+ # Sets the \variant for template.
81
+ def variant=(variant)
82
+ if variant.is_a?(Symbol)
83
+ @variant = [variant]
84
+ elsif variant.nil? || variant.is_a?(Array) && variant.any? && variant.all?{ |v| v.is_a?(Symbol) }
85
+ @variant = variant
86
+ else
87
+ raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols, not a #{variant.class}. " \
88
+ "For security reasons, never directly set the variant to a user-provided value, " \
89
+ "like params[:variant].to_sym. Check user-provided value against a whitelist first, " \
90
+ "then set the variant: request.variant = :tablet if params[:variant] == 'tablet'"
91
+ end
63
92
  end
64
93
 
65
94
  # Sets the \format by string extension, which can be used to force custom formats
66
95
  # that are not controlled by the extension.
67
96
  #
68
97
  # class ApplicationController < ActionController::Base
69
- # before_filter :adjust_format_for_iphone
98
+ # before_action :adjust_format_for_iphone
70
99
  #
71
100
  # private
72
101
  # def adjust_format_for_iphone
@@ -78,6 +107,27 @@ module ActionDispatch
78
107
  @env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])]
79
108
  end
80
109
 
110
+ # Sets the \formats by string extensions. This differs from #format= by allowing you
111
+ # to set multiple, ordered formats, which is useful when you want to have a fallback.
112
+ #
113
+ # In this example, the :iphone format will be used if it's available, otherwise it'll fallback
114
+ # to the :html format.
115
+ #
116
+ # class ApplicationController < ActionController::Base
117
+ # before_action :adjust_format_for_iphone_with_html_fallback
118
+ #
119
+ # private
120
+ # def adjust_format_for_iphone_with_html_fallback
121
+ # request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
122
+ # end
123
+ # end
124
+ def formats=(extensions)
125
+ parameters[:format] = extensions.first.to_s
126
+ @env["action_dispatch.request.formats"] = extensions.collect do |extension|
127
+ Mime::Type.lookup_by_extension(extension)
128
+ end
129
+ end
130
+
81
131
  # Receives an array of mimes and return the first user sent mime that
82
132
  # matches the order array.
83
133
  #
@@ -90,7 +140,7 @@ module ActionDispatch
90
140
  end
91
141
  end
92
142
 
93
- order.include?(Mime::ALL) ? formats.first : nil
143
+ order.include?(Mime::ALL) ? format : nil
94
144
  end
95
145
 
96
146
  protected