actionpack 3.2.22.5 → 4.0.0.beta1

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 (265) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +641 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller.rb +1 -8
  6. data/lib/abstract_controller/asset_paths.rb +2 -2
  7. data/lib/abstract_controller/base.rb +39 -37
  8. data/lib/abstract_controller/callbacks.rb +101 -82
  9. data/lib/abstract_controller/collector.rb +7 -3
  10. data/lib/abstract_controller/helpers.rb +23 -11
  11. data/lib/abstract_controller/layouts.rb +68 -73
  12. data/lib/abstract_controller/logger.rb +1 -2
  13. data/lib/abstract_controller/rendering.rb +22 -13
  14. data/lib/abstract_controller/translation.rb +16 -1
  15. data/lib/abstract_controller/url_for.rb +6 -6
  16. data/lib/abstract_controller/view_paths.rb +1 -1
  17. data/lib/action_controller.rb +15 -6
  18. data/lib/action_controller/base.rb +46 -22
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/caching/fragments.rb +23 -53
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  23. data/lib/action_controller/log_subscriber.rb +11 -8
  24. data/lib/action_controller/metal.rb +16 -30
  25. data/lib/action_controller/metal/conditional_get.rb +76 -32
  26. data/lib/action_controller/metal/data_streaming.rb +20 -26
  27. data/lib/action_controller/metal/exceptions.rb +19 -6
  28. data/lib/action_controller/metal/flash.rb +24 -9
  29. data/lib/action_controller/metal/force_ssl.rb +32 -9
  30. data/lib/action_controller/metal/head.rb +25 -4
  31. data/lib/action_controller/metal/helpers.rb +6 -9
  32. data/lib/action_controller/metal/hide_actions.rb +1 -2
  33. data/lib/action_controller/metal/http_authentication.rb +105 -87
  34. data/lib/action_controller/metal/implicit_render.rb +1 -1
  35. data/lib/action_controller/metal/instrumentation.rb +2 -1
  36. data/lib/action_controller/metal/live.rb +141 -0
  37. data/lib/action_controller/metal/mime_responds.rb +161 -47
  38. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  39. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  40. data/lib/action_controller/metal/redirecting.rb +15 -20
  41. data/lib/action_controller/metal/renderers.rb +11 -9
  42. data/lib/action_controller/metal/rendering.rb +8 -0
  43. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  44. data/lib/action_controller/metal/responder.rb +20 -19
  45. data/lib/action_controller/metal/streaming.rb +12 -18
  46. data/lib/action_controller/metal/strong_parameters.rb +516 -0
  47. data/lib/action_controller/metal/testing.rb +13 -18
  48. data/lib/action_controller/metal/url_for.rb +27 -25
  49. data/lib/action_controller/model_naming.rb +12 -0
  50. data/lib/action_controller/railtie.rb +33 -17
  51. data/lib/action_controller/railties/helpers.rb +22 -0
  52. data/lib/action_controller/record_identifier.rb +18 -72
  53. data/lib/action_controller/test_case.rb +215 -123
  54. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  55. data/lib/action_dispatch.rb +27 -19
  56. data/lib/action_dispatch/http/cache.rb +63 -11
  57. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  58. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  59. data/lib/action_dispatch/http/headers.rb +27 -19
  60. data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
  61. data/lib/action_dispatch/http/mime_type.rb +145 -113
  62. data/lib/action_dispatch/http/mime_types.rb +1 -1
  63. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  64. data/lib/action_dispatch/http/parameters.rb +12 -5
  65. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  66. data/lib/action_dispatch/http/request.rb +49 -18
  67. data/lib/action_dispatch/http/response.rb +129 -35
  68. data/lib/action_dispatch/http/upload.rb +60 -17
  69. data/lib/action_dispatch/http/url.rb +53 -31
  70. data/lib/action_dispatch/journey.rb +5 -0
  71. data/lib/action_dispatch/journey/backwards.rb +5 -0
  72. data/lib/action_dispatch/journey/formatter.rb +146 -0
  73. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  74. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  75. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  76. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  77. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  78. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  79. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  80. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  81. data/lib/action_dispatch/journey/parser.rb +206 -0
  82. data/lib/action_dispatch/journey/parser.y +47 -0
  83. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  84. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  85. data/lib/action_dispatch/journey/route.rb +116 -0
  86. data/lib/action_dispatch/journey/router.rb +164 -0
  87. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  88. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  89. data/lib/action_dispatch/journey/routes.rb +75 -0
  90. data/lib/action_dispatch/journey/scanner.rb +61 -0
  91. data/lib/action_dispatch/journey/visitors.rb +189 -0
  92. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  93. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  94. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  95. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  96. data/lib/action_dispatch/middleware/cookies.rb +168 -57
  97. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  98. data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
  99. data/lib/action_dispatch/middleware/flash.rb +58 -58
  100. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  101. data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
  102. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  103. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  104. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  105. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  106. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  107. data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
  108. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  109. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  110. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  111. data/lib/action_dispatch/middleware/stack.rb +6 -1
  112. data/lib/action_dispatch/middleware/static.rb +5 -24
  113. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  114. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  115. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
  116. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  117. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
  118. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  119. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  122. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  124. data/lib/action_dispatch/railtie.rb +16 -6
  125. data/lib/action_dispatch/request/session.rb +181 -0
  126. data/lib/action_dispatch/routing.rb +41 -40
  127. data/lib/action_dispatch/routing/inspector.rb +240 -0
  128. data/lib/action_dispatch/routing/mapper.rb +501 -273
  129. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  130. data/lib/action_dispatch/routing/redirection.rb +46 -29
  131. data/lib/action_dispatch/routing/route_set.rb +203 -164
  132. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  133. data/lib/action_dispatch/routing/url_for.rb +48 -33
  134. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  135. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  136. data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
  137. data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
  138. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  139. data/lib/action_dispatch/testing/integration.rb +41 -22
  140. data/lib/action_dispatch/testing/test_process.rb +9 -6
  141. data/lib/action_dispatch/testing/test_request.rb +7 -3
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_pack/version.rb +4 -4
  144. data/lib/action_view.rb +17 -8
  145. data/lib/action_view/base.rb +15 -34
  146. data/lib/action_view/buffers.rb +1 -1
  147. data/lib/action_view/context.rb +4 -4
  148. data/lib/action_view/dependency_tracker.rb +91 -0
  149. data/lib/action_view/digestor.rb +85 -0
  150. data/lib/action_view/flows.rb +1 -4
  151. data/lib/action_view/helpers.rb +2 -4
  152. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  153. data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
  154. data/lib/action_view/helpers/asset_url_helper.rb +354 -0
  155. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  156. data/lib/action_view/helpers/cache_helper.rb +150 -18
  157. data/lib/action_view/helpers/capture_helper.rb +42 -29
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  159. data/lib/action_view/helpers/date_helper.rb +268 -247
  160. data/lib/action_view/helpers/debug_helper.rb +10 -11
  161. data/lib/action_view/helpers/form_helper.rb +904 -547
  162. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  163. data/lib/action_view/helpers/form_tag_helper.rb +188 -88
  164. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  165. data/lib/action_view/helpers/number_helper.rb +148 -354
  166. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  167. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  168. data/lib/action_view/helpers/rendering_helper.rb +2 -4
  169. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  170. data/lib/action_view/helpers/tag_helper.rb +43 -37
  171. data/lib/action_view/helpers/tags.rb +39 -0
  172. data/lib/action_view/helpers/tags/base.rb +148 -0
  173. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  174. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  175. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  176. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  177. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  178. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  179. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  180. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  181. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  182. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  183. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  184. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  185. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  186. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  187. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  188. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  189. data/lib/action_view/helpers/tags/label.rb +65 -0
  190. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  191. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  192. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  193. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  194. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  195. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  196. data/lib/action_view/helpers/tags/select.rb +41 -0
  197. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  198. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  199. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  200. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  201. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  202. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  203. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  204. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  205. data/lib/action_view/helpers/text_helper.rb +126 -113
  206. data/lib/action_view/helpers/translation_helper.rb +32 -16
  207. data/lib/action_view/helpers/url_helper.rb +200 -271
  208. data/lib/action_view/locale/en.yml +1 -105
  209. data/lib/action_view/log_subscriber.rb +6 -4
  210. data/lib/action_view/lookup_context.rb +15 -39
  211. data/lib/action_view/model_naming.rb +12 -0
  212. data/lib/action_view/path_set.rb +9 -39
  213. data/lib/action_view/railtie.rb +6 -22
  214. data/lib/action_view/record_identifier.rb +84 -0
  215. data/lib/action_view/renderer/abstract_renderer.rb +10 -19
  216. data/lib/action_view/renderer/partial_renderer.rb +144 -81
  217. data/lib/action_view/renderer/renderer.rb +2 -19
  218. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  219. data/lib/action_view/renderer/template_renderer.rb +14 -13
  220. data/lib/action_view/routing_url_for.rb +107 -0
  221. data/lib/action_view/template.rb +22 -21
  222. data/lib/action_view/template/error.rb +22 -12
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/handlers/builder.rb +1 -1
  225. data/lib/action_view/template/handlers/erb.rb +11 -16
  226. data/lib/action_view/template/handlers/raw.rb +11 -0
  227. data/lib/action_view/template/resolver.rb +111 -83
  228. data/lib/action_view/template/text.rb +12 -8
  229. data/lib/action_view/template/types.rb +57 -0
  230. data/lib/action_view/test_case.rb +66 -43
  231. data/lib/action_view/testing/resolvers.rb +3 -2
  232. data/lib/action_view/vendor/html-scanner.rb +20 -0
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  235. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
  236. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
  237. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  238. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  239. metadata +135 -125
  240. data/lib/action_controller/caching/actions.rb +0 -185
  241. data/lib/action_controller/caching/pages.rb +0 -187
  242. data/lib/action_controller/caching/sweeping.rb +0 -97
  243. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  244. data/lib/action_controller/metal/compatibility.rb +0 -65
  245. data/lib/action_controller/metal/session_management.rb +0 -14
  246. data/lib/action_controller/railties/paths.rb +0 -25
  247. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  248. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  249. data/lib/action_dispatch/middleware/head.rb +0 -18
  250. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  251. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  252. data/lib/action_view/asset_paths.rb +0 -142
  253. data/lib/action_view/helpers/asset_paths.rb +0 -7
  254. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  255. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  256. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  257. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  258. data/lib/sprockets/assets.rake +0 -99
  259. data/lib/sprockets/bootstrap.rb +0 -37
  260. data/lib/sprockets/compressors.rb +0 -83
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  263. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  264. data/lib/sprockets/railtie.rb +0 -62
  265. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,11 +1,11 @@
1
1
  require 'set'
2
2
  require 'active_support/core_ext/class/attribute_accessors'
3
- require 'active_support/core_ext/object/blank'
3
+ require 'active_support/core_ext/string/starts_ends_with'
4
4
 
5
5
  module Mime
6
6
  class Mimes < Array
7
7
  def symbols
8
- @symbols ||= map {|m| m.to_sym }
8
+ @symbols ||= map { |m| m.to_sym }
9
9
  end
10
10
 
11
11
  %w(<< concat shift unshift push pop []= clear compact! collect!
@@ -22,11 +22,18 @@ module Mime
22
22
 
23
23
  SET = Mimes.new
24
24
  EXTENSION_LOOKUP = {}
25
- LOOKUP = {}
25
+ LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }
26
26
 
27
- def self.[](type)
28
- return type if type.is_a?(Type)
29
- Type.lookup_by_extension(type.to_s)
27
+ class << self
28
+ def [](type)
29
+ return type if type.is_a?(Type)
30
+ Type.lookup_by_extension(type) || NullType.new
31
+ end
32
+
33
+ def fetch(type)
34
+ return type if type.is_a?(Type)
35
+ EXTENSION_LOOKUP.fetch(type.to_s) { |k| yield k }
36
+ end
30
37
  end
31
38
 
32
39
  # Encapsulates the notion of a mime type. Can be used at render time, for example, with:
@@ -37,8 +44,8 @@ module Mime
37
44
  #
38
45
  # respond_to do |format|
39
46
  # format.html
40
- # format.ics { render :text => post.to_ics, :mime_type => Mime::Type["text/calendar"] }
41
- # format.xml { render :xml => @people.to_xml }
47
+ # format.ics { render text: post.to_ics, mime_type: Mime::Type["text/calendar"] }
48
+ # format.xml { render xml: @people }
42
49
  # end
43
50
  # end
44
51
  # end
@@ -50,42 +57,99 @@ module Mime
50
57
  # i.e. following a link, getting an image or posting a form. CSRF protection
51
58
  # only needs to protect against these types.
52
59
  @@browser_generated_types = Set.new [:html, :url_encoded_form, :multipart_form, :text]
53
- cattr_reader :browser_generated_types
54
60
  attr_reader :symbol
55
61
 
62
+ @register_callbacks = []
63
+
56
64
  # A simple helper class used in parsing the accept header
57
65
  class AcceptItem #:nodoc:
58
- attr_accessor :order, :name, :q
66
+ attr_accessor :index, :name, :q
67
+ alias :to_s :name
59
68
 
60
- def initialize(order, name, q=nil)
61
- @order = order
62
- @name = name.strip
63
- q ||= 0.0 if @name == Mime::ALL # default wildcard match to end of list
69
+ def initialize(index, name, q = nil)
70
+ @index = index
71
+ @name = name
72
+ q ||= 0.0 if @name == Mime::ALL.to_s # default wildcard match to end of list
64
73
  @q = ((q || 1.0).to_f * 100).to_i
65
74
  end
66
75
 
67
- def to_s
68
- @name
69
- end
70
-
71
76
  def <=>(item)
72
- result = item.q <=> q
73
- result = order <=> item.order if result == 0
77
+ result = item.q <=> @q
78
+ result = @index <=> item.index if result == 0
74
79
  result
75
80
  end
76
81
 
77
82
  def ==(item)
78
- name == (item.respond_to?(:name) ? item.name : item)
83
+ @name == item.to_s
79
84
  end
80
85
  end
81
86
 
82
- class << self
87
+ class AcceptList < Array #:nodoc:
88
+ def assort!
89
+ sort!
90
+
91
+ # Take care of the broken text/xml entry by renaming or deleting it
92
+ if text_xml_idx && app_xml_idx
93
+ app_xml.q = [text_xml.q, app_xml.q].max # set the q value to the max of the two
94
+ exchange_xml_items if app_xml_idx > text_xml_idx # make sure app_xml is ahead of text_xml in the list
95
+ delete_at(text_xml_idx) # delete text_xml from the list
96
+ elsif text_xml_idx
97
+ text_xml.name = Mime::XML.to_s
98
+ end
99
+
100
+ # Look for more specific XML-based types and sort them ahead of app/xml
101
+ if app_xml_idx
102
+ idx = app_xml_idx
103
+
104
+ while idx < length
105
+ type = self[idx]
106
+ break if type.q < app_xml.q
107
+
108
+ if type.name.ends_with? '+xml'
109
+ self[app_xml_idx], self[idx] = self[idx], app_xml
110
+ @app_xml_idx = idx
111
+ end
112
+ idx += 1
113
+ end
114
+ end
115
+
116
+ map! { |i| Mime::Type.lookup(i.name) }.uniq!
117
+ to_a
118
+ end
119
+
120
+ private
121
+ def text_xml_idx
122
+ @text_xml_idx ||= index('text/xml')
123
+ end
83
124
 
125
+ def app_xml_idx
126
+ @app_xml_idx ||= index(Mime::XML.to_s)
127
+ end
128
+
129
+ def text_xml
130
+ self[text_xml_idx]
131
+ end
132
+
133
+ def app_xml
134
+ self[app_xml_idx]
135
+ end
136
+
137
+ def exchange_xml_items
138
+ self[app_xml_idx], self[text_xml_idx] = text_xml, app_xml
139
+ @app_xml_idx, @text_xml_idx = text_xml_idx, app_xml_idx
140
+ end
141
+ end
142
+
143
+ class << self
84
144
  TRAILING_STAR_REGEXP = /(text|application)\/\*/
85
- Q_SEPARATOR_REGEXP = /;\s*q=/
145
+ PARAMETER_SEPARATOR_REGEXP = /;\s*\w+="?\w+"?/
146
+
147
+ def register_callback(&block)
148
+ @register_callbacks << block
149
+ end
86
150
 
87
151
  def lookup(string)
88
- LOOKUP[string] || Type.new(string)
152
+ LOOKUP[string]
89
153
  end
90
154
 
91
155
  def lookup_by_extension(extension)
@@ -99,91 +163,51 @@ module Mime
99
163
  end
100
164
 
101
165
  def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)
102
- Mime.const_set(symbol.to_s.upcase, Type.new(string, symbol, mime_type_synonyms))
166
+ Mime.const_set(symbol.upcase, Type.new(string, symbol, mime_type_synonyms))
103
167
 
104
- SET << Mime.const_get(symbol.to_s.upcase)
168
+ new_mime = Mime.const_get(symbol.upcase)
169
+ SET << new_mime
105
170
 
106
171
  ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = SET.last } unless skip_lookup
107
172
  ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = SET.last }
173
+
174
+ @register_callbacks.each do |callback|
175
+ callback.call(new_mime)
176
+ end
108
177
  end
109
178
 
110
179
  def parse(accept_header)
111
180
  if accept_header !~ /,/
112
- accept_header = accept_header.split(Q_SEPARATOR_REGEXP).first
113
- if accept_header =~ TRAILING_STAR_REGEXP
114
- parse_data_with_trailing_star($1)
115
- else
116
- [Mime::Type.lookup(accept_header)]
117
- end
181
+ accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
182
+ parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)]
118
183
  else
119
- # keep track of creation order to keep the subsequent sort stable
120
- list, index = [], 0
121
- accept_header.split(/,/).each do |header|
122
- params, q = header.split(Q_SEPARATOR_REGEXP)
184
+ list, index = AcceptList.new, 0
185
+ accept_header.split(',').each do |header|
186
+ params, q = header.split(PARAMETER_SEPARATOR_REGEXP)
123
187
  if params.present?
124
188
  params.strip!
125
189
 
126
- if params =~ TRAILING_STAR_REGEXP
127
- parse_data_with_trailing_star($1).each do |m|
128
- list << AcceptItem.new(index, m.to_s, q)
129
- index += 1
130
- end
131
- else
132
- list << AcceptItem.new(index, params, q)
133
- index += 1
134
- end
135
- end
136
- end
137
- list.sort!
138
-
139
- # Take care of the broken text/xml entry by renaming or deleting it
140
- text_xml = list.index("text/xml")
141
- app_xml = list.index(Mime::XML.to_s)
142
-
143
- if text_xml && app_xml
144
- # set the q value to the max of the two
145
- list[app_xml].q = [list[text_xml].q, list[app_xml].q].max
146
-
147
- # make sure app_xml is ahead of text_xml in the list
148
- if app_xml > text_xml
149
- list[app_xml], list[text_xml] = list[text_xml], list[app_xml]
150
- app_xml, text_xml = text_xml, app_xml
151
- end
152
-
153
- # delete text_xml from the list
154
- list.delete_at(text_xml)
155
-
156
- elsif text_xml
157
- list[text_xml].name = Mime::XML.to_s
158
- end
159
-
160
- # Look for more specific XML-based types and sort them ahead of app/xml
190
+ params = parse_trailing_star(params) || [params]
161
191
 
162
- if app_xml
163
- idx = app_xml
164
- app_xml_type = list[app_xml]
165
-
166
- while(idx < list.length)
167
- type = list[idx]
168
- break if type.q < app_xml_type.q
169
- if type.name =~ /\+xml$/
170
- list[app_xml], list[idx] = list[idx], list[app_xml]
171
- app_xml = idx
192
+ params.each do |m|
193
+ list << AcceptItem.new(index, m.to_s, q)
194
+ index += 1
172
195
  end
173
- idx += 1
174
196
  end
175
197
  end
176
-
177
- list.map! { |i| Mime::Type.lookup(i.name) }.uniq!
178
- list
198
+ list.assort!
179
199
  end
180
200
  end
181
201
 
182
- # input: 'text'
183
- # returned value: [Mime::JSON, Mime::XML, Mime::ICS, Mime::HTML, Mime::CSS, Mime::CSV, Mime::JS, Mime::YAML, Mime::TEXT]
202
+ def parse_trailing_star(accept_header)
203
+ parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
204
+ end
205
+
206
+ # For an input of <tt>'text'</tt>, returns <tt>[Mime::JSON, Mime::XML, Mime::ICS,
207
+ # Mime::HTML, Mime::CSS, Mime::CSV, Mime::JS, Mime::YAML, Mime::TEXT]</tt>.
184
208
  #
185
- # input: 'application'
186
- # returned value: [Mime::HTML, Mime::JS, Mime::XML, Mime::YAML, Mime::ATOM, Mime::JSON, Mime::RSS, Mime::URL_ENCODED_FORM]
209
+ # For an input of <tt>'application'</tt>, returns <tt>[Mime::HTML, Mime::JS,
210
+ # Mime::XML, Mime::YAML, Mime::ATOM, Mime::JSON, Mime::RSS, Mime::URL_ENCODED_FORM]</tt>.
187
211
  def parse_data_with_trailing_star(input)
188
212
  Mime::SET.select { |m| m =~ input }
189
213
  end
@@ -192,9 +216,9 @@ module Mime
192
216
  #
193
217
  # Usage:
194
218
  #
195
- # Mime::Type.unregister(:mobile)
219
+ # Mime::Type.unregister(:mobile)
196
220
  def unregister(symbol)
197
- symbol = symbol.to_s.upcase
221
+ symbol = symbol.upcase
198
222
  mime = Mime.const_get(symbol)
199
223
  Mime.instance_eval { remove_const(symbol) }
200
224
 
@@ -204,12 +228,9 @@ module Mime
204
228
  end
205
229
  end
206
230
 
207
- attr_reader :hash
208
-
209
231
  def initialize(string, symbol = nil, synonyms = [])
210
232
  @symbol, @synonyms = symbol, synonyms
211
233
  @string = string
212
- @hash = [@string, @synonyms, @symbol].hash
213
234
  end
214
235
 
215
236
  def to_s
@@ -243,13 +264,6 @@ module Mime
243
264
  end
244
265
  end
245
266
 
246
- def eql?(other)
247
- super || (self.class == other.class &&
248
- @string == other.string &&
249
- @synonyms == other.synonyms &&
250
- @symbol == other.symbol)
251
- end
252
-
253
267
  def =~(mime_type)
254
268
  return false if mime_type.blank?
255
269
  regexp = Regexp.new(Regexp.quote(mime_type.to_s))
@@ -261,29 +275,47 @@ module Mime
261
275
  # Returns true if Action Pack should check requests using this Mime Type for possible request forgery. See
262
276
  # ActionController::RequestForgeryProtection.
263
277
  def verify_request?
278
+ ActiveSupport::Deprecation.warn "Mime::Type#verify_request? is deprecated and will be removed in Rails 4.1"
264
279
  @@browser_generated_types.include?(to_sym)
265
280
  end
266
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
+
267
287
  def html?
268
288
  @@html_types.include?(to_sym) || @string =~ /html/
269
289
  end
270
290
 
271
- def respond_to?(method, include_private = false) #:nodoc:
272
- super || method.to_s =~ /(\w+)\?$/
273
- end
274
291
 
275
- protected
292
+ private
276
293
 
277
- attr_reader :string, :synonyms
294
+ def to_ary; end
295
+ def to_a; end
278
296
 
279
- private
280
- def method_missing(method, *args)
281
- if method.to_s =~ /(\w+)\?$/
282
- $1.downcase.to_sym == to_sym
283
- else
284
- super
285
- end
297
+ def method_missing(method, *args)
298
+ if method.to_s.ends_with? '?'
299
+ method[0..-2].downcase.to_sym == to_sym
300
+ else
301
+ super
286
302
  end
303
+ end
304
+
305
+ def respond_to_missing?(method, include_private = false) #:nodoc:
306
+ method.to_s.ends_with? '?'
307
+ end
308
+ end
309
+
310
+ class NullType
311
+ def nil?
312
+ true
313
+ end
314
+
315
+ private
316
+ def method_missing(method, *args)
317
+ false if method.to_s.ends_with? '?'
318
+ end
287
319
  end
288
320
  end
289
321
 
@@ -9,7 +9,7 @@ Mime::Type.register "text/calendar", :ics
9
9
  Mime::Type.register "text/csv", :csv
10
10
 
11
11
  Mime::Type.register "image/png", :png, [], %w(png)
12
- Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe)
12
+ Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe pjpeg)
13
13
  Mime::Type.register "image/gif", :gif, [], %w(gif)
14
14
  Mime::Type.register "image/bmp", :bmp, [], %w(bmp)
15
15
  Mime::Type.register "image/tiff", :tiff, [], %w(tif tiff)
@@ -1,74 +1,72 @@
1
1
  module ActionDispatch
2
2
  module Http
3
3
  class ParameterFilter
4
+ FILTERED = '[FILTERED]'.freeze # :nodoc:
4
5
 
5
- def initialize(filters)
6
+ def initialize(filters = [])
6
7
  @filters = filters
7
8
  end
8
9
 
9
10
  def filter(params)
10
- if enabled?
11
- compiled_filter.call(params)
12
- else
13
- params.dup
14
- end
11
+ compiled_filter.call(params)
15
12
  end
16
13
 
17
14
  private
18
15
 
19
- def enabled?
20
- @filters.present?
16
+ def compiled_filter
17
+ @compiled_filter ||= CompiledFilter.compile(@filters)
21
18
  end
22
19
 
23
- FILTERED = '[FILTERED]'.freeze
20
+ class CompiledFilter # :nodoc:
21
+ def self.compile(filters)
22
+ return lambda { |params| params.dup } if filters.empty?
24
23
 
25
- def compiled_filter
26
- @compiled_filter ||= begin
27
- regexps, blocks = compile_filter
24
+ strings, regexps, blocks = [], [], []
28
25
 
29
- lambda do |original_params|
30
- filtered_params = {}
26
+ filters.each do |item|
27
+ case item
28
+ when Proc
29
+ blocks << item
30
+ when Regexp
31
+ regexps << item
32
+ else
33
+ strings << item.to_s
34
+ end
35
+ end
31
36
 
32
- original_params.each do |key, value|
33
- if regexps.find { |r| key =~ r }
34
- value = FILTERED
35
- elsif value.is_a?(Hash)
36
- value = filter(value)
37
- elsif value.is_a?(Array)
38
- value = value.map { |v| v.is_a?(Hash) ? filter(v) : v }
39
- elsif blocks.present?
40
- key = key.dup
41
- value = value.dup if value.duplicable?
42
- blocks.each { |b| b.call(key, value) }
43
- end
37
+ regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
38
+ new regexps, blocks
39
+ end
44
40
 
45
- filtered_params[key] = value
46
- end
41
+ attr_reader :regexps, :blocks
47
42
 
48
- filtered_params
49
- end
43
+ def initialize(regexps, blocks)
44
+ @regexps = regexps
45
+ @blocks = blocks
50
46
  end
51
- end
52
47
 
53
- def compile_filter
54
- strings, regexps, blocks = [], [], []
48
+ def call(original_params)
49
+ filtered_params = {}
50
+
51
+ original_params.each do |key, value|
52
+ if regexps.any? { |r| key =~ r }
53
+ value = FILTERED
54
+ elsif value.is_a?(Hash)
55
+ value = call(value)
56
+ elsif value.is_a?(Array)
57
+ value = value.map { |v| v.is_a?(Hash) ? call(v) : v }
58
+ elsif blocks.any?
59
+ key = key.dup
60
+ value = value.dup if value.duplicable?
61
+ blocks.each { |b| b.call(key, value) }
62
+ end
55
63
 
56
- @filters.each do |item|
57
- case item
58
- when NilClass
59
- when Proc
60
- blocks << item
61
- when Regexp
62
- regexps << item
63
- else
64
- strings << item.to_s
64
+ filtered_params[key] = value
65
65
  end
66
- end
67
66
 
68
- regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
69
- [regexps, blocks]
67
+ filtered_params
68
+ end
70
69
  end
71
-
72
70
  end
73
71
  end
74
72
  end