actionpack 4.0.1 → 4.2.11.1

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 (241) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +402 -1173
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -7
  5. data/lib/abstract_controller/base.rb +39 -7
  6. data/lib/abstract_controller/callbacks.rb +32 -53
  7. data/lib/abstract_controller/collector.rb +11 -1
  8. data/lib/abstract_controller/helpers.rb +26 -16
  9. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  10. data/lib/abstract_controller/rendering.rb +57 -127
  11. data/lib/abstract_controller/url_for.rb +1 -1
  12. data/lib/abstract_controller.rb +1 -2
  13. data/lib/action_controller/base.rb +19 -10
  14. data/lib/action_controller/caching/fragments.rb +7 -1
  15. data/lib/action_controller/caching.rb +2 -12
  16. data/lib/action_controller/log_subscriber.rb +29 -20
  17. data/lib/action_controller/metal/conditional_get.rb +37 -12
  18. data/lib/action_controller/metal/data_streaming.rb +1 -1
  19. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  20. data/lib/action_controller/metal/exceptions.rb +1 -1
  21. data/lib/action_controller/metal/flash.rb +17 -0
  22. data/lib/action_controller/metal/force_ssl.rb +2 -2
  23. data/lib/action_controller/metal/head.rb +8 -6
  24. data/lib/action_controller/metal/helpers.rb +6 -2
  25. data/lib/action_controller/metal/http_authentication.rb +45 -23
  26. data/lib/action_controller/metal/instrumentation.rb +9 -6
  27. data/lib/action_controller/metal/live.rb +173 -20
  28. data/lib/action_controller/metal/mime_responds.rb +127 -232
  29. data/lib/action_controller/metal/params_wrapper.rb +16 -9
  30. data/lib/action_controller/metal/rack_delegation.rb +1 -1
  31. data/lib/action_controller/metal/redirecting.rb +34 -26
  32. data/lib/action_controller/metal/renderers.rb +39 -12
  33. data/lib/action_controller/metal/rendering.rb +41 -14
  34. data/lib/action_controller/metal/request_forgery_protection.rb +147 -19
  35. data/lib/action_controller/metal/streaming.rb +19 -21
  36. data/lib/action_controller/metal/strong_parameters.rb +166 -22
  37. data/lib/action_controller/metal/testing.rb +0 -1
  38. data/lib/action_controller/metal/url_for.rb +11 -12
  39. data/lib/action_controller/metal.rb +14 -8
  40. data/lib/action_controller/model_naming.rb +1 -1
  41. data/lib/action_controller/railtie.rb +5 -1
  42. data/lib/action_controller/test_case.rb +160 -94
  43. data/lib/action_controller.rb +2 -18
  44. data/lib/action_dispatch/http/cache.rb +5 -4
  45. data/lib/action_dispatch/http/filter_parameters.rb +2 -2
  46. data/lib/action_dispatch/http/filter_redirect.rb +5 -4
  47. data/lib/action_dispatch/http/headers.rb +46 -10
  48. data/lib/action_dispatch/http/mime_negotiation.rb +31 -4
  49. data/lib/action_dispatch/http/mime_type.rb +25 -26
  50. data/lib/action_dispatch/http/mime_types.rb +1 -0
  51. data/lib/action_dispatch/http/parameter_filter.rb +1 -1
  52. data/lib/action_dispatch/http/parameters.rb +25 -41
  53. data/lib/action_dispatch/http/request.rb +49 -32
  54. data/lib/action_dispatch/http/response.rb +127 -25
  55. data/lib/action_dispatch/http/upload.rb +9 -21
  56. data/lib/action_dispatch/http/url.rb +97 -70
  57. data/lib/action_dispatch/journey/formatter.rb +35 -19
  58. data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
  59. data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
  60. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -33
  61. data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
  62. data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
  63. data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
  64. data/lib/action_dispatch/journey/nodes/node.rb +4 -0
  65. data/lib/action_dispatch/journey/parser.rb +51 -59
  66. data/lib/action_dispatch/journey/parser.y +12 -10
  67. data/lib/action_dispatch/journey/path/pattern.rb +16 -19
  68. data/lib/action_dispatch/journey/route.rb +8 -19
  69. data/lib/action_dispatch/journey/router/strexp.rb +9 -6
  70. data/lib/action_dispatch/journey/router/utils.rb +54 -18
  71. data/lib/action_dispatch/journey/router.rb +53 -75
  72. data/lib/action_dispatch/journey/routes.rb +4 -0
  73. data/lib/action_dispatch/journey/scanner.rb +5 -5
  74. data/lib/action_dispatch/journey/visitors.rb +81 -60
  75. data/lib/action_dispatch/journey/visualizer/fsm.css +0 -4
  76. data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
  77. data/lib/action_dispatch/middleware/callbacks.rb +7 -7
  78. data/lib/action_dispatch/middleware/cookies.rb +119 -43
  79. data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -13
  80. data/lib/action_dispatch/middleware/exception_wrapper.rb +60 -20
  81. data/lib/action_dispatch/middleware/flash.rb +37 -24
  82. data/lib/action_dispatch/middleware/params_parser.rb +2 -2
  83. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -3
  84. data/lib/action_dispatch/middleware/reloader.rb +11 -2
  85. data/lib/action_dispatch/middleware/remote_ip.rb +40 -54
  86. data/lib/action_dispatch/middleware/request_id.rb +1 -1
  87. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  88. data/lib/action_dispatch/middleware/session/cookie_store.rb +8 -7
  89. data/lib/action_dispatch/middleware/show_exceptions.rb +6 -2
  90. data/lib/action_dispatch/middleware/ssl.rb +10 -7
  91. data/lib/action_dispatch/middleware/static.rb +79 -23
  92. data/lib/action_dispatch/middleware/templates/rescues/{_request_and_response.erb → _request_and_response.html.erb} +0 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +21 -19
  95. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  96. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  97. data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +1 -1
  98. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  99. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  101. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  102. data/lib/action_dispatch/middleware/templates/rescues/{routing_error.erb → routing_error.html.erb} +3 -1
  103. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  104. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  105. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  106. data/lib/action_dispatch/middleware/templates/rescues/{unknown_action.erb → unknown_action.html.erb} +1 -1
  107. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  108. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +120 -64
  109. data/lib/action_dispatch/railtie.rb +5 -2
  110. data/lib/action_dispatch/request/session.rb +12 -0
  111. data/lib/action_dispatch/request/utils.rb +35 -0
  112. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  113. data/lib/action_dispatch/routing/inspector.rb +11 -17
  114. data/lib/action_dispatch/routing/mapper.rb +519 -312
  115. data/lib/action_dispatch/routing/polymorphic_routes.rb +204 -79
  116. data/lib/action_dispatch/routing/redirection.rb +51 -26
  117. data/lib/action_dispatch/routing/route_set.rb +331 -206
  118. data/lib/action_dispatch/routing/routes_proxy.rb +5 -4
  119. data/lib/action_dispatch/routing/url_for.rb +19 -5
  120. data/lib/action_dispatch/routing.rb +9 -6
  121. data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
  122. data/lib/action_dispatch/testing/assertions/response.rb +9 -15
  123. data/lib/action_dispatch/testing/assertions/routing.rb +22 -22
  124. data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
  125. data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
  126. data/lib/action_dispatch/testing/assertions.rb +11 -7
  127. data/lib/action_dispatch/testing/integration.rb +31 -29
  128. data/lib/action_dispatch/testing/test_request.rb +1 -1
  129. data/lib/action_dispatch/testing/test_response.rb +1 -5
  130. data/lib/action_dispatch.rb +5 -8
  131. data/lib/action_pack/gem_version.rb +15 -0
  132. data/lib/action_pack/version.rb +4 -7
  133. data/lib/action_pack.rb +1 -1
  134. metadata +77 -159
  135. data/lib/abstract_controller/layouts.rb +0 -423
  136. data/lib/abstract_controller/view_paths.rb +0 -96
  137. data/lib/action_controller/deprecated/integration_test.rb +0 -5
  138. data/lib/action_controller/deprecated.rb +0 -7
  139. data/lib/action_controller/metal/responder.rb +0 -287
  140. data/lib/action_controller/record_identifier.rb +0 -31
  141. data/lib/action_controller/vendor/html-scanner.rb +0 -5
  142. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -24
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -7
  144. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -43
  145. data/lib/action_view/base.rb +0 -201
  146. data/lib/action_view/buffers.rb +0 -49
  147. data/lib/action_view/context.rb +0 -36
  148. data/lib/action_view/dependency_tracker.rb +0 -93
  149. data/lib/action_view/digestor.rb +0 -113
  150. data/lib/action_view/flows.rb +0 -76
  151. data/lib/action_view/helpers/active_model_helper.rb +0 -49
  152. data/lib/action_view/helpers/asset_tag_helper.rb +0 -320
  153. data/lib/action_view/helpers/asset_url_helper.rb +0 -355
  154. data/lib/action_view/helpers/atom_feed_helper.rb +0 -203
  155. data/lib/action_view/helpers/cache_helper.rb +0 -196
  156. data/lib/action_view/helpers/capture_helper.rb +0 -216
  157. data/lib/action_view/helpers/controller_helper.rb +0 -25
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -30
  159. data/lib/action_view/helpers/date_helper.rb +0 -1083
  160. data/lib/action_view/helpers/debug_helper.rb +0 -39
  161. data/lib/action_view/helpers/form_helper.rb +0 -1880
  162. data/lib/action_view/helpers/form_options_helper.rb +0 -838
  163. data/lib/action_view/helpers/form_tag_helper.rb +0 -785
  164. data/lib/action_view/helpers/javascript_helper.rb +0 -117
  165. data/lib/action_view/helpers/number_helper.rb +0 -441
  166. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  167. data/lib/action_view/helpers/record_tag_helper.rb +0 -106
  168. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  169. data/lib/action_view/helpers/sanitize_helper.rb +0 -256
  170. data/lib/action_view/helpers/tag_helper.rb +0 -173
  171. data/lib/action_view/helpers/tags/base.rb +0 -148
  172. data/lib/action_view/helpers/tags/check_box.rb +0 -64
  173. data/lib/action_view/helpers/tags/checkable.rb +0 -16
  174. data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -44
  175. data/lib/action_view/helpers/tags/collection_helpers.rb +0 -84
  176. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -36
  177. data/lib/action_view/helpers/tags/collection_select.rb +0 -28
  178. data/lib/action_view/helpers/tags/color_field.rb +0 -25
  179. data/lib/action_view/helpers/tags/date_field.rb +0 -13
  180. data/lib/action_view/helpers/tags/date_select.rb +0 -72
  181. data/lib/action_view/helpers/tags/datetime_field.rb +0 -22
  182. data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -19
  183. data/lib/action_view/helpers/tags/datetime_select.rb +0 -8
  184. data/lib/action_view/helpers/tags/email_field.rb +0 -8
  185. data/lib/action_view/helpers/tags/file_field.rb +0 -8
  186. data/lib/action_view/helpers/tags/grouped_collection_select.rb +0 -29
  187. data/lib/action_view/helpers/tags/hidden_field.rb +0 -8
  188. data/lib/action_view/helpers/tags/label.rb +0 -66
  189. data/lib/action_view/helpers/tags/month_field.rb +0 -13
  190. data/lib/action_view/helpers/tags/number_field.rb +0 -18
  191. data/lib/action_view/helpers/tags/password_field.rb +0 -12
  192. data/lib/action_view/helpers/tags/radio_button.rb +0 -31
  193. data/lib/action_view/helpers/tags/range_field.rb +0 -8
  194. data/lib/action_view/helpers/tags/search_field.rb +0 -24
  195. data/lib/action_view/helpers/tags/select.rb +0 -40
  196. data/lib/action_view/helpers/tags/tel_field.rb +0 -8
  197. data/lib/action_view/helpers/tags/text_area.rb +0 -18
  198. data/lib/action_view/helpers/tags/text_field.rb +0 -29
  199. data/lib/action_view/helpers/tags/time_field.rb +0 -13
  200. data/lib/action_view/helpers/tags/time_select.rb +0 -8
  201. data/lib/action_view/helpers/tags/time_zone_select.rb +0 -20
  202. data/lib/action_view/helpers/tags/url_field.rb +0 -8
  203. data/lib/action_view/helpers/tags/week_field.rb +0 -13
  204. data/lib/action_view/helpers/tags.rb +0 -39
  205. data/lib/action_view/helpers/text_helper.rb +0 -443
  206. data/lib/action_view/helpers/translation_helper.rb +0 -107
  207. data/lib/action_view/helpers/url_helper.rb +0 -635
  208. data/lib/action_view/helpers.rb +0 -58
  209. data/lib/action_view/locale/en.yml +0 -56
  210. data/lib/action_view/log_subscriber.rb +0 -30
  211. data/lib/action_view/lookup_context.rb +0 -241
  212. data/lib/action_view/model_naming.rb +0 -12
  213. data/lib/action_view/path_set.rb +0 -77
  214. data/lib/action_view/railtie.rb +0 -43
  215. data/lib/action_view/record_identifier.rb +0 -84
  216. data/lib/action_view/renderer/abstract_renderer.rb +0 -47
  217. data/lib/action_view/renderer/partial_renderer.rb +0 -492
  218. data/lib/action_view/renderer/renderer.rb +0 -50
  219. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -103
  220. data/lib/action_view/renderer/template_renderer.rb +0 -96
  221. data/lib/action_view/routing_url_for.rb +0 -107
  222. data/lib/action_view/tasks/dependencies.rake +0 -17
  223. data/lib/action_view/template/error.rb +0 -138
  224. data/lib/action_view/template/handlers/builder.rb +0 -26
  225. data/lib/action_view/template/handlers/erb.rb +0 -146
  226. data/lib/action_view/template/handlers/raw.rb +0 -11
  227. data/lib/action_view/template/handlers.rb +0 -53
  228. data/lib/action_view/template/resolver.rb +0 -326
  229. data/lib/action_view/template/text.rb +0 -34
  230. data/lib/action_view/template/types.rb +0 -57
  231. data/lib/action_view/template.rb +0 -339
  232. data/lib/action_view/test_case.rb +0 -270
  233. data/lib/action_view/testing/resolvers.rb +0 -50
  234. data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
  235. data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
  236. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
  237. data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
  238. data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
  239. data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
  240. data/lib/action_view/vendor/html-scanner.rb +0 -20
  241. data/lib/action_view.rb +0 -93
@@ -10,6 +10,8 @@ module ActionDispatch
10
10
  self.ignore_accept_header = false
11
11
  end
12
12
 
13
+ attr_reader :variant
14
+
13
15
  # The MIME type of the HTTP request, such as Mime::XML.
14
16
  #
15
17
  # For backward compatibility, the post \format is extracted from the
@@ -48,12 +50,18 @@ module ActionDispatch
48
50
  # GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first
49
51
  #
50
52
  def format(view_path = [])
51
- formats.first
53
+ formats.first || Mime::NullType.instance
52
54
  end
53
55
 
54
56
  def formats
55
- @env["action_dispatch.request.formats"] ||=
56
- 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
57
65
  Array(Mime[parameters[:format]])
58
66
  elsif use_accept_header && valid_accept_header
59
67
  accepts
@@ -62,6 +70,25 @@ module ActionDispatch
62
70
  else
63
71
  [Mime::HTML]
64
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
65
92
  end
66
93
 
67
94
  # Sets the \format by string extension, which can be used to force custom formats
@@ -113,7 +140,7 @@ module ActionDispatch
113
140
  end
114
141
  end
115
142
 
116
- order.include?(Mime::ALL) ? formats.first : nil
143
+ order.include?(Mime::ALL) ? format : nil
117
144
  end
118
145
 
119
146
  protected
@@ -1,5 +1,6 @@
1
1
  require 'set'
2
- require 'active_support/core_ext/class/attribute_accessors'
2
+ require 'singleton'
3
+ require 'active_support/core_ext/module/attribute_accessors'
3
4
  require 'active_support/core_ext/string/starts_ends_with'
4
5
 
5
6
  module Mime
@@ -22,12 +23,12 @@ module Mime
22
23
 
23
24
  SET = Mimes.new
24
25
  EXTENSION_LOOKUP = {}
25
- LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
26
+ LOOKUP = {}
26
27
 
27
28
  class << self
28
29
  def [](type)
29
30
  return type if type.is_a?(Type)
30
- Type.lookup_by_extension(type) || NullType.new
31
+ Type.lookup_by_extension(type)
31
32
  end
32
33
 
33
34
  def fetch(type)
@@ -44,8 +45,8 @@ module Mime
44
45
  #
45
46
  # respond_to do |format|
46
47
  # format.html
47
- # format.ics { render text: post.to_ics, mime_type: Mime::Type["text/calendar"] }
48
- # format.xml { render xml: @people }
48
+ # format.ics { render text: @post.to_ics, mime_type: Mime::Type["text/calendar"] }
49
+ # format.xml { render xml: @post }
49
50
  # end
50
51
  # end
51
52
  # end
@@ -53,10 +54,6 @@ module Mime
53
54
  @@html_types = Set.new [:html, :all]
54
55
  cattr_reader :html_types
55
56
 
56
- # These are the content types which browsers can generate without using ajax, flash, etc
57
- # i.e. following a link, getting an image or posting a form. CSRF protection
58
- # only needs to protect against these types.
59
- @@browser_generated_types = Set.new [:html, :url_encoded_form, :multipart_form, :text]
60
57
  attr_reader :symbol
61
58
 
62
59
  @register_callbacks = []
@@ -149,7 +146,7 @@ module Mime
149
146
  end
150
147
 
151
148
  def lookup(string)
152
- LOOKUP[string]
149
+ LOOKUP[string] || Type.new(string)
153
150
  end
154
151
 
155
152
  def lookup_by_extension(extension)
@@ -177,7 +174,7 @@ module Mime
177
174
  end
178
175
 
179
176
  def parse(accept_header)
180
- if accept_header !~ /,/
177
+ if !accept_header.include?(',')
181
178
  accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
182
179
  parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact
183
180
  else
@@ -228,9 +225,12 @@ module Mime
228
225
  end
229
226
  end
230
227
 
228
+ attr_reader :hash
229
+
231
230
  def initialize(string, symbol = nil, synonyms = [])
232
231
  @symbol, @synonyms = symbol, synonyms
233
232
  @string = string
233
+ @hash = [@string, @synonyms, @symbol].hash
234
234
  end
235
235
 
236
236
  def to_s
@@ -264,6 +264,13 @@ module Mime
264
264
  end
265
265
  end
266
266
 
267
+ def eql?(other)
268
+ super || (self.class == other.class &&
269
+ @string == other.string &&
270
+ @synonyms == other.synonyms &&
271
+ @symbol == other.symbol)
272
+ end
273
+
267
274
  def =~(mime_type)
268
275
  return false if mime_type.blank?
269
276
  regexp = Regexp.new(Regexp.quote(mime_type.to_s))
@@ -272,23 +279,15 @@ module Mime
272
279
  end
273
280
  end
274
281
 
275
- # Returns true if Action Pack should check requests using this Mime Type for possible request forgery. See
276
- # ActionController::RequestForgeryProtection.
277
- def verify_request?
278
- ActiveSupport::Deprecation.warn "Mime::Type#verify_request? is deprecated and will be removed in Rails 4.1"
279
- @@browser_generated_types.include?(to_sym)
280
- end
281
-
282
- def self.browser_generated_types
283
- ActiveSupport::Deprecation.warn "Mime::Type.browser_generated_types is deprecated and will be removed in Rails 4.1"
284
- @@browser_generated_types
285
- end
286
-
287
282
  def html?
288
283
  @@html_types.include?(to_sym) || @string =~ /html/
289
284
  end
290
285
 
291
286
 
287
+ protected
288
+
289
+ attr_reader :string, :synonyms
290
+
292
291
  private
293
292
 
294
293
  def to_ary; end
@@ -308,13 +307,13 @@ module Mime
308
307
  end
309
308
 
310
309
  class NullType
310
+ include Singleton
311
+
311
312
  def nil?
312
313
  true
313
314
  end
314
315
 
315
- def ref
316
- nil
317
- end
316
+ def ref; end
318
317
 
319
318
  def respond_to_missing?(method, include_private = false)
320
319
  method.to_s.ends_with? '?'
@@ -7,6 +7,7 @@ Mime::Type.register "text/javascript", :js, %w( application/javascript applicati
7
7
  Mime::Type.register "text/css", :css
8
8
  Mime::Type.register "text/calendar", :ics
9
9
  Mime::Type.register "text/csv", :csv
10
+ Mime::Type.register "text/vcard", :vcf
10
11
 
11
12
  Mime::Type.register "image/png", :png, [], %w(png)
12
13
  Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe pjpeg)
@@ -56,7 +56,7 @@ module ActionDispatch
56
56
  elsif value.is_a?(Array)
57
57
  value = value.map { |v| v.is_a?(Hash) ? call(v) : v }
58
58
  elsif blocks.any?
59
- key = key.dup
59
+ key = key.dup if key.duplicable?
60
60
  value = value.dup if value.duplicable?
61
61
  blocks.each { |b| b.call(key, value) }
62
62
  end
@@ -1,13 +1,11 @@
1
1
  require 'active_support/core_ext/hash/keys'
2
2
  require 'active_support/core_ext/hash/indifferent_access'
3
+ require 'active_support/deprecation'
3
4
 
4
5
  module ActionDispatch
5
6
  module Http
6
7
  module Parameters
7
- def initialize(env)
8
- super
9
- @symbolized_path_params = nil
10
- end
8
+ PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
11
9
 
12
10
  # Returns both GET and POST \parameters in a single hash.
13
11
  def parameters
@@ -18,65 +16,51 @@ module ActionDispatch
18
16
  query_parameters.dup
19
17
  end
20
18
  params.merge!(path_parameters)
21
- params.with_indifferent_access
22
19
  end
23
20
  end
24
21
  alias :params :parameters
25
22
 
26
23
  def path_parameters=(parameters) #:nodoc:
27
- @symbolized_path_params = nil
28
- @env.delete("action_dispatch.request.parameters")
29
- @env["action_dispatch.request.path_parameters"] = parameters
24
+ @env.delete('action_dispatch.request.parameters')
25
+ @env[PARAMETERS_KEY] = parameters
30
26
  end
31
27
 
32
- # The same as <tt>path_parameters</tt> with explicitly symbolized keys.
33
28
  def symbolized_path_parameters
34
- @symbolized_path_params ||= path_parameters.symbolize_keys
29
+ ActiveSupport::Deprecation.warn(
30
+ '`symbolized_path_parameters` is deprecated. Please use `path_parameters`.'
31
+ )
32
+ path_parameters
35
33
  end
36
34
 
37
35
  # Returns a hash with the \parameters used to form the \path of the request.
38
36
  # Returned hash keys are strings:
39
37
  #
40
38
  # {'action' => 'my_action', 'controller' => 'my_controller'}
41
- #
42
- # See <tt>symbolized_path_parameters</tt> for symbolized keys.
43
39
  def path_parameters
44
- @env["action_dispatch.request.path_parameters"] ||= {}
45
- end
46
-
47
- def reset_parameters #:nodoc:
48
- @env.delete("action_dispatch.request.parameters")
40
+ @env[PARAMETERS_KEY] ||= {}
49
41
  end
50
42
 
51
43
  private
52
44
 
53
- # Convert nested Hash to HashWithIndifferentAccess
54
- # and UTF-8 encode both keys and values in nested Hash.
45
+ # Convert nested Hash to HashWithIndifferentAccess.
55
46
  #
56
- # TODO: Validate that the characters are UTF-8. If they aren't,
57
- # you'll get a weird error down the road, but our form handling
58
- # should really prevent that from happening
59
47
  def normalize_encode_params(params)
60
- if params.is_a?(String)
61
- return params.force_encoding(Encoding::UTF_8).encode!
62
- elsif !params.is_a?(Hash)
63
- return params
64
- end
65
-
66
- new_hash = {}
67
- params.each do |k, v|
68
- new_key = k.is_a?(String) ? k.dup.force_encoding(Encoding::UTF_8).encode! : k
69
- new_hash[new_key] =
70
- case v
71
- when Hash
72
- normalize_encode_params(v)
73
- when Array
74
- v.map! {|el| normalize_encode_params(el) }
75
- else
76
- normalize_encode_params(v)
77
- end
48
+ case params
49
+ when Hash
50
+ if params.has_key?(:tempfile)
51
+ UploadedFile.new(params)
52
+ else
53
+ params.each_with_object({}) do |(key, val), new_hash|
54
+ new_hash[key] = if val.is_a?(Array)
55
+ val.map! { |el| normalize_encode_params(el) }
56
+ else
57
+ normalize_encode_params(val)
58
+ end
59
+ end.with_indifferent_access
60
+ end
61
+ else
62
+ params
78
63
  end
79
- new_hash.with_indifferent_access
80
64
  end
81
65
  end
82
66
  end
@@ -18,12 +18,12 @@ module ActionDispatch
18
18
  include ActionDispatch::Http::MimeNegotiation
19
19
  include ActionDispatch::Http::Parameters
20
20
  include ActionDispatch::Http::FilterParameters
21
- include ActionDispatch::Http::Upload
22
21
  include ActionDispatch::Http::URL
23
22
 
24
23
  autoload :Session, 'action_dispatch/request/session'
24
+ autoload :Utils, 'action_dispatch/request/utils'
25
25
 
26
- LOCALHOST = Regexp.union [/^127\.0\.0\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
26
+ LOCALHOST = Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
27
27
 
28
28
  ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE
29
29
  PATH_TRANSLATED REMOTE_HOST
@@ -53,6 +53,17 @@ module ActionDispatch
53
53
  @uuid = nil
54
54
  end
55
55
 
56
+ def check_path_parameters!
57
+ # If any of the path parameters has an invalid encoding then
58
+ # raise since it's likely to trigger errors further on.
59
+ path_parameters.each do |key, value|
60
+ next unless value.respond_to?(:valid_encoding?)
61
+ unless value.valid_encoding?
62
+ raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}"
63
+ end
64
+ end
65
+ end
66
+
56
67
  def key?(key)
57
68
  @env.key?(key)
58
69
  end
@@ -64,6 +75,7 @@ module ActionDispatch
64
75
  # Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt)
65
76
  # Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt)
66
77
  # Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt)
78
+ # Calendar Extensions to WebDAV (http://www.ietf.org/rfc/rfc4791.txt)
67
79
  # PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt)
68
80
  RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
69
81
  RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
@@ -71,9 +83,10 @@ module ActionDispatch
71
83
  RFC3648 = %w(ORDERPATCH)
72
84
  RFC3744 = %w(ACL)
73
85
  RFC5323 = %w(SEARCH)
86
+ RFC4791 = %w(MKCALENDAR)
74
87
  RFC5789 = %w(PATCH)
75
88
 
76
- HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789
89
+ HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789
77
90
 
78
91
  HTTP_METHOD_LOOKUP = {}
79
92
 
@@ -92,6 +105,12 @@ module ActionDispatch
92
105
  @request_method ||= check_method(env["REQUEST_METHOD"])
93
106
  end
94
107
 
108
+ def request_method=(request_method) #:nodoc:
109
+ if check_method(request_method)
110
+ @request_method = env["REQUEST_METHOD"] = request_method
111
+ end
112
+ end
113
+
95
114
  # Returns a symbol form of the #request_method
96
115
  def request_method_symbol
97
116
  HTTP_METHOD_LOOKUP[request_method]
@@ -152,6 +171,13 @@ module ActionDispatch
152
171
  Http::Headers.new(@env)
153
172
  end
154
173
 
174
+ # Returns a +String+ with the last requested path including their params.
175
+ #
176
+ # # get '/foo'
177
+ # request.original_fullpath # => '/foo'
178
+ #
179
+ # # get '/foo?bar'
180
+ # request.original_fullpath # => '/foo?bar'
155
181
  def original_fullpath
156
182
  @original_fullpath ||= (env["ORIGINAL_FULLPATH"] || fullpath)
157
183
  end
@@ -189,8 +215,8 @@ module ActionDispatch
189
215
  end
190
216
 
191
217
  # Returns true if the "X-Requested-With" header contains "XMLHttpRequest"
192
- # (case-insensitive). All major JavaScript libraries send this header with
193
- # every Ajax request.
218
+ # (case-insensitive), which may need to be manually added depending on the
219
+ # choice of JavaScript libraries and frameworks.
194
220
  def xml_http_request?
195
221
  @env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i
196
222
  end
@@ -205,7 +231,7 @@ module ActionDispatch
205
231
  @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
206
232
  end
207
233
 
208
- # Returns the unique request id, which is based off either the X-Request-Id header that can
234
+ # Returns the unique request id, which is based on either the X-Request-Id header that can
209
235
  # be generated by a firewall, load balancer, or web server or by the RequestId middleware
210
236
  # (which sets the action_dispatch.request_id environment variable).
211
237
  #
@@ -225,7 +251,7 @@ module ActionDispatch
225
251
  def raw_post
226
252
  unless @env.include? 'RAW_POST_DATA'
227
253
  raw_post_body = body
228
- @env['RAW_POST_DATA'] = raw_post_body.read(@env['CONTENT_LENGTH'].to_i)
254
+ @env['RAW_POST_DATA'] = raw_post_body.read(content_length)
229
255
  raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
230
256
  end
231
257
  @env['RAW_POST_DATA']
@@ -271,16 +297,16 @@ module ActionDispatch
271
297
 
272
298
  # Override Rack's GET method to support indifferent access
273
299
  def GET
274
- @env["action_dispatch.request.query_parameters"] ||= (normalize_encode_params(super) || {})
275
- rescue TypeError => e
300
+ @env["action_dispatch.request.query_parameters"] ||= Utils.deep_munge(normalize_encode_params(super || {}))
301
+ rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
276
302
  raise ActionController::BadRequest.new(:query, e)
277
303
  end
278
304
  alias :query_parameters :GET
279
305
 
280
306
  # Override Rack's POST method to support indifferent access
281
307
  def POST
282
- @env["action_dispatch.request.request_parameters"] ||= (normalize_encode_params(super) || {})
283
- rescue TypeError => e
308
+ @env["action_dispatch.request.request_parameters"] ||= Utils.deep_munge(normalize_encode_params(super || {}))
309
+ rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
284
310
  raise ActionController::BadRequest.new(:request, e)
285
311
  end
286
312
  alias :request_parameters :POST
@@ -299,33 +325,24 @@ module ActionDispatch
299
325
  LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
300
326
  end
301
327
 
302
- # Remove nils from the params hash
328
+ # Extracted into ActionDispatch::Request::Utils.deep_munge, but kept here for backwards compatibility.
303
329
  def deep_munge(hash)
304
- hash.each do |k, v|
305
- case v
306
- when Array
307
- v.grep(Hash) { |x| deep_munge(x) }
308
- v.compact!
309
- hash[k] = nil if v.empty?
310
- when Hash
311
- deep_munge(v)
312
- end
313
- end
330
+ ActiveSupport::Deprecation.warn(
331
+ 'This method has been extracted into `ActionDispatch::Request::Utils.deep_munge`. Please start using that instead.'
332
+ )
314
333
 
315
- hash
334
+ Utils.deep_munge(hash)
316
335
  end
317
336
 
318
337
  protected
319
-
320
- def parse_query(qs)
321
- deep_munge(super)
322
- end
338
+ def parse_query(qs)
339
+ Utils.deep_munge(super)
340
+ end
323
341
 
324
342
  private
325
-
326
- def check_method(name)
327
- HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
328
- name
329
- end
343
+ def check_method(name)
344
+ HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS[0...-1].join(', ')}, and #{HTTP_METHODS[-1]}")
345
+ name
346
+ end
330
347
  end
331
348
  end