actionpack 3.2.22.5 → 5.2.4

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 (271) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +279 -603
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -297
  5. data/lib/abstract_controller/asset_paths.rb +4 -2
  6. data/lib/abstract_controller/base.rb +82 -52
  7. data/lib/abstract_controller/caching/fragments.rb +166 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +117 -103
  10. data/lib/abstract_controller/collector.rb +18 -7
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +65 -38
  13. data/lib/abstract_controller/logger.rb +3 -2
  14. data/lib/abstract_controller/railties/routes_helpers.rb +5 -3
  15. data/lib/abstract_controller/rendering.rb +77 -129
  16. data/lib/abstract_controller/translation.rb +21 -3
  17. data/lib/abstract_controller/url_for.rb +9 -7
  18. data/lib/abstract_controller.rb +12 -13
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/base.rb +81 -40
  22. data/lib/action_controller/caching.rb +22 -62
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +30 -18
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +190 -47
  27. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  28. data/lib/action_controller/metal/cookies.rb +3 -3
  29. data/lib/action_controller/metal/data_streaming.rb +40 -65
  30. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  31. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  32. data/lib/action_controller/metal/exceptions.rb +19 -12
  33. data/lib/action_controller/metal/flash.rb +42 -9
  34. data/lib/action_controller/metal/force_ssl.rb +79 -19
  35. data/lib/action_controller/metal/head.rb +35 -10
  36. data/lib/action_controller/metal/helpers.rb +31 -21
  37. data/lib/action_controller/metal/http_authentication.rb +182 -134
  38. data/lib/action_controller/metal/implicit_render.rb +62 -8
  39. data/lib/action_controller/metal/instrumentation.rb +28 -26
  40. data/lib/action_controller/metal/live.rb +312 -0
  41. data/lib/action_controller/metal/mime_responds.rb +159 -163
  42. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  43. data/lib/action_controller/metal/params_wrapper.rb +146 -93
  44. data/lib/action_controller/metal/redirecting.rb +80 -56
  45. data/lib/action_controller/metal/renderers.rb +119 -47
  46. data/lib/action_controller/metal/rendering.rb +89 -32
  47. data/lib/action_controller/metal/request_forgery_protection.rb +373 -41
  48. data/lib/action_controller/metal/rescue.rb +9 -16
  49. data/lib/action_controller/metal/streaming.rb +39 -45
  50. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  51. data/lib/action_controller/metal/testing.rb +8 -29
  52. data/lib/action_controller/metal/url_for.rb +43 -32
  53. data/lib/action_controller/metal.rb +112 -106
  54. data/lib/action_controller/railtie.rb +56 -18
  55. data/lib/action_controller/railties/helpers.rb +24 -0
  56. data/lib/action_controller/renderer.rb +117 -0
  57. data/lib/action_controller/template_assertions.rb +11 -0
  58. data/lib/action_controller/test_case.rb +402 -347
  59. data/lib/action_controller.rb +31 -30
  60. data/lib/action_dispatch/http/cache.rb +133 -34
  61. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +40 -24
  63. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  64. data/lib/action_dispatch/http/headers.rb +117 -16
  65. data/lib/action_dispatch/http/mime_negotiation.rb +98 -33
  66. data/lib/action_dispatch/http/mime_type.rb +198 -146
  67. data/lib/action_dispatch/http/mime_types.rb +22 -7
  68. data/lib/action_dispatch/http/parameter_filter.rb +61 -49
  69. data/lib/action_dispatch/http/parameters.rb +94 -51
  70. data/lib/action_dispatch/http/rack_cache.rb +4 -3
  71. data/lib/action_dispatch/http/request.rb +262 -117
  72. data/lib/action_dispatch/http/response.rb +400 -86
  73. data/lib/action_dispatch/http/upload.rb +66 -29
  74. data/lib/action_dispatch/http/url.rb +232 -60
  75. data/lib/action_dispatch/journey/formatter.rb +189 -0
  76. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  77. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  78. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  79. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  80. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  81. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  82. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  83. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  84. data/lib/action_dispatch/journey/parser.rb +199 -0
  85. data/lib/action_dispatch/journey/parser.y +50 -0
  86. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  87. data/lib/action_dispatch/journey/path/pattern.rb +199 -0
  88. data/lib/action_dispatch/journey/route.rb +203 -0
  89. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  90. data/lib/action_dispatch/journey/router.rb +156 -0
  91. data/lib/action_dispatch/journey/routes.rb +82 -0
  92. data/lib/action_dispatch/journey/scanner.rb +64 -0
  93. data/lib/action_dispatch/journey/visitors.rb +268 -0
  94. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  95. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  96. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  97. data/lib/action_dispatch/journey.rb +7 -0
  98. data/lib/action_dispatch/middleware/callbacks.rb +17 -13
  99. data/lib/action_dispatch/middleware/cookies.rb +494 -162
  100. data/lib/action_dispatch/middleware/debug_exceptions.rb +176 -53
  101. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  102. data/lib/action_dispatch/middleware/exception_wrapper.rb +103 -38
  103. data/lib/action_dispatch/middleware/executor.rb +21 -0
  104. data/lib/action_dispatch/middleware/flash.rb +128 -91
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +43 -16
  106. data/lib/action_dispatch/middleware/reloader.rb +6 -83
  107. data/lib/action_dispatch/middleware/remote_ip.rb +151 -49
  108. data/lib/action_dispatch/middleware/request_id.rb +19 -15
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +38 -34
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -9
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +94 -44
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -4
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +36 -61
  114. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  115. data/lib/action_dispatch/middleware/stack.rb +33 -41
  116. data/lib/action_dispatch/middleware/static.rb +92 -48
  117. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +134 -5
  128. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  136. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  138. data/lib/action_dispatch/railtie.rb +29 -8
  139. data/lib/action_dispatch/request/session.rb +234 -0
  140. data/lib/action_dispatch/request/utils.rb +78 -0
  141. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  142. data/lib/action_dispatch/routing/inspector.rb +225 -0
  143. data/lib/action_dispatch/routing/mapper.rb +1329 -582
  144. data/lib/action_dispatch/routing/polymorphic_routes.rb +237 -94
  145. data/lib/action_dispatch/routing/redirection.rb +120 -50
  146. data/lib/action_dispatch/routing/route_set.rb +545 -322
  147. data/lib/action_dispatch/routing/routes_proxy.rb +37 -7
  148. data/lib/action_dispatch/routing/url_for.rb +103 -34
  149. data/lib/action_dispatch/routing.rb +66 -99
  150. data/lib/action_dispatch/system_test_case.rb +147 -0
  151. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  152. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  153. data/lib/action_dispatch/system_testing/server.rb +31 -0
  154. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  158. data/lib/action_dispatch/testing/assertions/response.rb +53 -42
  159. data/lib/action_dispatch/testing/assertions/routing.rb +79 -74
  160. data/lib/action_dispatch/testing/assertions.rb +15 -9
  161. data/lib/action_dispatch/testing/integration.rb +361 -207
  162. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  163. data/lib/action_dispatch/testing/test_process.rb +28 -19
  164. data/lib/action_dispatch/testing/test_request.rb +30 -33
  165. data/lib/action_dispatch/testing/test_response.rb +35 -11
  166. data/lib/action_dispatch.rb +42 -32
  167. data/lib/action_pack/gem_version.rb +17 -0
  168. data/lib/action_pack/version.rb +7 -7
  169. data/lib/action_pack.rb +4 -2
  170. metadata +116 -175
  171. data/lib/abstract_controller/layouts.rb +0 -423
  172. data/lib/abstract_controller/view_paths.rb +0 -96
  173. data/lib/action_controller/caching/actions.rb +0 -185
  174. data/lib/action_controller/caching/fragments.rb +0 -127
  175. data/lib/action_controller/caching/pages.rb +0 -187
  176. data/lib/action_controller/caching/sweeping.rb +0 -97
  177. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  178. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  179. data/lib/action_controller/deprecated.rb +0 -3
  180. data/lib/action_controller/metal/compatibility.rb +0 -65
  181. data/lib/action_controller/metal/hide_actions.rb +0 -41
  182. data/lib/action_controller/metal/rack_delegation.rb +0 -26
  183. data/lib/action_controller/metal/responder.rb +0 -286
  184. data/lib/action_controller/metal/session_management.rb +0 -14
  185. data/lib/action_controller/middleware.rb +0 -39
  186. data/lib/action_controller/railties/paths.rb +0 -25
  187. data/lib/action_controller/record_identifier.rb +0 -85
  188. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  189. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  190. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  191. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  192. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  193. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  194. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  195. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  196. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  197. data/lib/action_dispatch/middleware/head.rb +0 -18
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -75
  199. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  200. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  201. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  202. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  203. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  204. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  205. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  206. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  207. data/lib/action_dispatch/testing/assertions/dom.rb +0 -37
  208. data/lib/action_dispatch/testing/assertions/selector.rb +0 -435
  209. data/lib/action_dispatch/testing/assertions/tag.rb +0 -138
  210. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  211. data/lib/action_view/asset_paths.rb +0 -142
  212. data/lib/action_view/base.rb +0 -220
  213. data/lib/action_view/buffers.rb +0 -43
  214. data/lib/action_view/context.rb +0 -36
  215. data/lib/action_view/flows.rb +0 -79
  216. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  217. data/lib/action_view/helpers/asset_paths.rb +0 -7
  218. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  219. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  220. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  221. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  222. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  223. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  224. data/lib/action_view/helpers/cache_helper.rb +0 -64
  225. data/lib/action_view/helpers/capture_helper.rb +0 -203
  226. data/lib/action_view/helpers/controller_helper.rb +0 -25
  227. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  228. data/lib/action_view/helpers/date_helper.rb +0 -1062
  229. data/lib/action_view/helpers/debug_helper.rb +0 -40
  230. data/lib/action_view/helpers/form_helper.rb +0 -1486
  231. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  232. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  233. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  234. data/lib/action_view/helpers/number_helper.rb +0 -622
  235. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  236. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  237. data/lib/action_view/helpers/rendering_helper.rb +0 -92
  238. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  239. data/lib/action_view/helpers/tag_helper.rb +0 -167
  240. data/lib/action_view/helpers/text_helper.rb +0 -426
  241. data/lib/action_view/helpers/translation_helper.rb +0 -91
  242. data/lib/action_view/helpers/url_helper.rb +0 -693
  243. data/lib/action_view/helpers.rb +0 -60
  244. data/lib/action_view/locale/en.yml +0 -160
  245. data/lib/action_view/log_subscriber.rb +0 -28
  246. data/lib/action_view/lookup_context.rb +0 -258
  247. data/lib/action_view/path_set.rb +0 -101
  248. data/lib/action_view/railtie.rb +0 -55
  249. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  250. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  251. data/lib/action_view/renderer/renderer.rb +0 -61
  252. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  253. data/lib/action_view/renderer/template_renderer.rb +0 -95
  254. data/lib/action_view/template/error.rb +0 -128
  255. data/lib/action_view/template/handlers/builder.rb +0 -26
  256. data/lib/action_view/template/handlers/erb.rb +0 -125
  257. data/lib/action_view/template/handlers.rb +0 -50
  258. data/lib/action_view/template/resolver.rb +0 -298
  259. data/lib/action_view/template/text.rb +0 -30
  260. data/lib/action_view/template.rb +0 -337
  261. data/lib/action_view/test_case.rb +0 -246
  262. data/lib/action_view/testing/resolvers.rb +0 -49
  263. data/lib/action_view.rb +0 -84
  264. data/lib/sprockets/assets.rake +0 -99
  265. data/lib/sprockets/bootstrap.rb +0 -37
  266. data/lib/sprockets/compressors.rb +0 -83
  267. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  268. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  269. data/lib/sprockets/helpers.rb +0 -6
  270. data/lib/sprockets/railtie.rb +0 -62
  271. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,22 +1,34 @@
1
- require 'set'
2
- require 'active_support/core_ext/class/attribute_accessors'
3
- require 'active_support/core_ext/object/blank'
1
+ # frozen_string_literal: true
2
+
3
+ # -*- frozen-string-literal: true -*-
4
+
5
+ require "singleton"
6
+ require "active_support/core_ext/string/starts_ends_with"
4
7
 
5
8
  module Mime
6
- class Mimes < Array
7
- def symbols
8
- @symbols ||= map {|m| m.to_sym }
9
+ class Mimes
10
+ include Enumerable
11
+
12
+ def initialize
13
+ @mimes = []
14
+ @symbols = nil
9
15
  end
10
16
 
11
- %w(<< concat shift unshift push pop []= clear compact! collect!
12
- delete delete_at delete_if flatten! map! insert reject! reverse!
13
- replace slice! sort! uniq!).each do |method|
14
- module_eval <<-CODE, __FILE__, __LINE__ + 1
15
- def #{method}(*)
16
- @symbols = nil
17
- super
18
- end
19
- CODE
17
+ def each
18
+ @mimes.each { |x| yield x }
19
+ end
20
+
21
+ def <<(type)
22
+ @mimes << type
23
+ @symbols = nil
24
+ end
25
+
26
+ def delete_if
27
+ @mimes.delete_if { |x| yield x }.tap { @symbols = nil }
28
+ end
29
+
30
+ def symbols
31
+ @symbols ||= map(&:to_sym)
20
32
  end
21
33
  end
22
34
 
@@ -24,12 +36,19 @@ module Mime
24
36
  EXTENSION_LOOKUP = {}
25
37
  LOOKUP = {}
26
38
 
27
- def self.[](type)
28
- return type if type.is_a?(Type)
29
- Type.lookup_by_extension(type.to_s)
39
+ class << self
40
+ def [](type)
41
+ return type if type.is_a?(Type)
42
+ Type.lookup_by_extension(type)
43
+ end
44
+
45
+ def fetch(type)
46
+ return type if type.is_a?(Type)
47
+ EXTENSION_LOOKUP.fetch(type.to_s) { |k| yield k }
48
+ end
30
49
  end
31
50
 
32
- # Encapsulates the notion of a mime type. Can be used at render time, for example, with:
51
+ # Encapsulates the notion of a MIME type. Can be used at render time, for example, with:
33
52
  #
34
53
  # class PostsController < ActionController::Base
35
54
  # def show
@@ -37,52 +56,90 @@ module Mime
37
56
  #
38
57
  # respond_to do |format|
39
58
  # format.html
40
- # format.ics { render :text => post.to_ics, :mime_type => Mime::Type["text/calendar"] }
41
- # format.xml { render :xml => @people.to_xml }
59
+ # format.ics { render body: @post.to_ics, mime_type: Mime::Type.lookup("text/calendar") }
60
+ # format.xml { render xml: @post }
42
61
  # end
43
62
  # end
44
63
  # end
45
64
  class Type
46
- @@html_types = Set.new [:html, :all]
47
- cattr_reader :html_types
48
-
49
- # These are the content types which browsers can generate without using ajax, flash, etc
50
- # i.e. following a link, getting an image or posting a form. CSRF protection
51
- # only needs to protect against these types.
52
- @@browser_generated_types = Set.new [:html, :url_encoded_form, :multipart_form, :text]
53
- cattr_reader :browser_generated_types
54
65
  attr_reader :symbol
55
66
 
56
- # A simple helper class used in parsing the accept header
67
+ @register_callbacks = []
68
+
69
+ # A simple helper class used in parsing the accept header.
57
70
  class AcceptItem #:nodoc:
58
- attr_accessor :order, :name, :q
71
+ attr_accessor :index, :name, :q
72
+ alias :to_s :name
59
73
 
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
74
+ def initialize(index, name, q = nil)
75
+ @index = index
76
+ @name = name
77
+ q ||= 0.0 if @name == "*/*".freeze # Default wildcard match to end of list.
64
78
  @q = ((q || 1.0).to_f * 100).to_i
65
79
  end
66
80
 
67
- def to_s
68
- @name
69
- end
70
-
71
81
  def <=>(item)
72
- result = item.q <=> q
73
- result = order <=> item.order if result == 0
82
+ result = item.q <=> @q
83
+ result = @index <=> item.index if result == 0
74
84
  result
75
85
  end
86
+ end
76
87
 
77
- def ==(item)
78
- name == (item.respond_to?(:name) ? item.name : item)
88
+ class AcceptList #:nodoc:
89
+ def self.sort!(list)
90
+ list.sort!
91
+
92
+ text_xml_idx = find_item_by_name list, "text/xml"
93
+ app_xml_idx = find_item_by_name list, Mime[:xml].to_s
94
+
95
+ # Take care of the broken text/xml entry by renaming or deleting it.
96
+ if text_xml_idx && app_xml_idx
97
+ app_xml = list[app_xml_idx]
98
+ text_xml = list[text_xml_idx]
99
+
100
+ app_xml.q = [text_xml.q, app_xml.q].max # Set the q value to the max of the two.
101
+ if app_xml_idx > text_xml_idx # Make sure app_xml is ahead of text_xml in the list.
102
+ list[app_xml_idx], list[text_xml_idx] = text_xml, app_xml
103
+ app_xml_idx, text_xml_idx = text_xml_idx, app_xml_idx
104
+ end
105
+ list.delete_at(text_xml_idx) # Delete text_xml from the list.
106
+ elsif text_xml_idx
107
+ list[text_xml_idx].name = Mime[:xml].to_s
108
+ end
109
+
110
+ # Look for more specific XML-based types and sort them ahead of app/xml.
111
+ if app_xml_idx
112
+ app_xml = list[app_xml_idx]
113
+ idx = app_xml_idx
114
+
115
+ while idx < list.length
116
+ type = list[idx]
117
+ break if type.q < app_xml.q
118
+
119
+ if type.name.ends_with? "+xml"
120
+ list[app_xml_idx], list[idx] = list[idx], app_xml
121
+ app_xml_idx = idx
122
+ end
123
+ idx += 1
124
+ end
125
+ end
126
+
127
+ list.map! { |i| Mime::Type.lookup(i.name) }.uniq!
128
+ list
129
+ end
130
+
131
+ def self.find_item_by_name(array, name)
132
+ array.index { |item| item.name == name }
79
133
  end
80
134
  end
81
135
 
82
136
  class << self
137
+ TRAILING_STAR_REGEXP = /^(text|application)\/\*/
138
+ PARAMETER_SEPARATOR_REGEXP = /;\s*\w+="?\w+"?/
83
139
 
84
- TRAILING_STAR_REGEXP = /(text|application)\/\*/
85
- Q_SEPARATOR_REGEXP = /;\s*q=/
140
+ def register_callback(&block)
141
+ @register_callbacks << block
142
+ end
86
143
 
87
144
  def lookup(string)
88
145
  LOOKUP[string] || Type.new(string)
@@ -92,115 +149,75 @@ module Mime
92
149
  EXTENSION_LOOKUP[extension.to_s]
93
150
  end
94
151
 
95
- # Registers an alias that's not used on mime type lookup, but can be referenced directly. Especially useful for
152
+ # Registers an alias that's not used on MIME type lookup, but can be referenced directly. Especially useful for
96
153
  # rendering different HTML versions depending on the user agent, like an iPhone.
97
154
  def register_alias(string, symbol, extension_synonyms = [])
98
155
  register(string, symbol, [], extension_synonyms, true)
99
156
  end
100
157
 
101
158
  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))
159
+ new_mime = Type.new(string, symbol, mime_type_synonyms)
103
160
 
104
- SET << Mime.const_get(symbol.to_s.upcase)
161
+ SET << new_mime
105
162
 
106
- ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = SET.last } unless skip_lookup
107
- ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = SET.last }
163
+ ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = new_mime } unless skip_lookup
164
+ ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = new_mime }
165
+
166
+ @register_callbacks.each do |callback|
167
+ callback.call(new_mime)
168
+ end
169
+ new_mime
108
170
  end
109
171
 
110
172
  def parse(accept_header)
111
- 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
173
+ if !accept_header.include?(",")
174
+ accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
175
+ parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact
118
176
  else
119
- # keep track of creation order to keep the subsequent sort stable
120
177
  list, index = [], 0
121
- accept_header.split(/,/).each do |header|
122
- params, q = header.split(Q_SEPARATOR_REGEXP)
123
- if params.present?
124
- params.strip!
125
-
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
178
+ accept_header.split(",").each do |header|
179
+ params, q = header.split(PARAMETER_SEPARATOR_REGEXP)
152
180
 
153
- # delete text_xml from the list
154
- list.delete_at(text_xml)
181
+ next unless params
182
+ params.strip!
183
+ next if params.empty?
155
184
 
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
161
-
162
- if app_xml
163
- idx = app_xml
164
- app_xml_type = list[app_xml]
185
+ params = parse_trailing_star(params) || [params]
165
186
 
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
172
- end
173
- idx += 1
187
+ params.each do |m|
188
+ list << AcceptItem.new(index, m.to_s, q)
189
+ index += 1
174
190
  end
175
191
  end
176
-
177
- list.map! { |i| Mime::Type.lookup(i.name) }.uniq!
178
- list
192
+ AcceptList.sort! list
179
193
  end
180
194
  end
181
195
 
182
- # input: 'text'
183
- # returned value: [Mime::JSON, Mime::XML, Mime::ICS, Mime::HTML, Mime::CSS, Mime::CSV, Mime::JS, Mime::YAML, Mime::TEXT]
196
+ def parse_trailing_star(accept_header)
197
+ parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
198
+ end
199
+
200
+ # For an input of <tt>'text'</tt>, returns <tt>[Mime[:json], Mime[:xml], Mime[:ics],
201
+ # Mime[:html], Mime[:css], Mime[:csv], Mime[:js], Mime[:yaml], Mime[:text]</tt>.
184
202
  #
185
- # input: 'application'
186
- # returned value: [Mime::HTML, Mime::JS, Mime::XML, Mime::YAML, Mime::ATOM, Mime::JSON, Mime::RSS, Mime::URL_ENCODED_FORM]
187
- def parse_data_with_trailing_star(input)
188
- Mime::SET.select { |m| m =~ input }
203
+ # For an input of <tt>'application'</tt>, returns <tt>[Mime[:html], Mime[:js],
204
+ # Mime[:xml], Mime[:yaml], Mime[:atom], Mime[:json], Mime[:rss], Mime[:url_encoded_form]</tt>.
205
+ def parse_data_with_trailing_star(type)
206
+ Mime::SET.select { |m| m =~ type }
189
207
  end
190
208
 
191
209
  # This method is opposite of register method.
192
210
  #
193
- # Usage:
211
+ # To unregister a MIME type:
194
212
  #
195
- # Mime::Type.unregister(:mobile)
213
+ # Mime::Type.unregister(:mobile)
196
214
  def unregister(symbol)
197
- symbol = symbol.to_s.upcase
198
- mime = Mime.const_get(symbol)
199
- Mime.instance_eval { remove_const(symbol) }
200
-
201
- SET.delete_if { |v| v.eql?(mime) }
202
- LOOKUP.delete_if { |k,v| v.eql?(mime) }
203
- EXTENSION_LOOKUP.delete_if { |k,v| v.eql?(mime) }
215
+ symbol = symbol.downcase
216
+ if mime = Mime[symbol]
217
+ SET.delete_if { |v| v.eql?(mime) }
218
+ LOOKUP.delete_if { |_, v| v.eql?(mime) }
219
+ EXTENSION_LOOKUP.delete_if { |_, v| v.eql?(mime) }
220
+ end
204
221
  end
205
222
  end
206
223
 
@@ -225,7 +242,7 @@ module Mime
225
242
  end
226
243
 
227
244
  def ref
228
- to_sym || to_s
245
+ symbol || to_s
229
246
  end
230
247
 
231
248
  def ===(list)
@@ -237,7 +254,7 @@ module Mime
237
254
  end
238
255
 
239
256
  def ==(mime_type)
240
- return false if mime_type.blank?
257
+ return false unless mime_type
241
258
  (@synonyms + [ self ]).any? do |synonym|
242
259
  synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
243
260
  end
@@ -251,40 +268,75 @@ module Mime
251
268
  end
252
269
 
253
270
  def =~(mime_type)
254
- return false if mime_type.blank?
271
+ return false unless mime_type
255
272
  regexp = Regexp.new(Regexp.quote(mime_type.to_s))
256
- (@synonyms + [ self ]).any? do |synonym|
257
- synonym.to_s =~ regexp
258
- end
259
- end
260
-
261
- # Returns true if Action Pack should check requests using this Mime Type for possible request forgery. See
262
- # ActionController::RequestForgeryProtection.
263
- def verify_request?
264
- @@browser_generated_types.include?(to_sym)
273
+ @synonyms.any? { |synonym| synonym.to_s =~ regexp } || @string =~ regexp
265
274
  end
266
275
 
267
276
  def html?
268
- @@html_types.include?(to_sym) || @string =~ /html/
277
+ symbol == :html || @string =~ /html/
269
278
  end
270
279
 
271
- def respond_to?(method, include_private = false) #:nodoc:
272
- super || method.to_s =~ /(\w+)\?$/
273
- end
280
+ def all?; false; end
274
281
 
282
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
283
+ # Workaround for Ruby 2.2 "private attribute?" warning.
275
284
  protected
276
285
 
277
- attr_reader :string, :synonyms
286
+ attr_reader :string, :synonyms
278
287
 
279
288
  private
289
+
290
+ def to_ary; end
291
+ def to_a; end
292
+
280
293
  def method_missing(method, *args)
281
- if method.to_s =~ /(\w+)\?$/
282
- $1.downcase.to_sym == to_sym
294
+ if method.to_s.ends_with? "?"
295
+ method[0..-2].downcase.to_sym == to_sym
283
296
  else
284
297
  super
285
298
  end
286
299
  end
300
+
301
+ def respond_to_missing?(method, include_private = false)
302
+ (method.to_s.ends_with? "?") || super
303
+ end
304
+ end
305
+
306
+ class AllType < Type
307
+ include Singleton
308
+
309
+ def initialize
310
+ super "*/*", :all
311
+ end
312
+
313
+ def all?; true; end
314
+ def html?; true; end
315
+ end
316
+
317
+ # ALL isn't a real MIME type, so we don't register it for lookup with the
318
+ # other concrete types. It's a wildcard match that we use for `respond_to`
319
+ # negotiation internals.
320
+ ALL = AllType.instance
321
+
322
+ class NullType
323
+ include Singleton
324
+
325
+ def nil?
326
+ true
327
+ end
328
+
329
+ def ref; end
330
+
331
+ private
332
+ def respond_to_missing?(method, _)
333
+ method.to_s.ends_with? "?"
334
+ end
335
+
336
+ def method_missing(method, *args)
337
+ false if method.to_s.ends_with? "?"
338
+ end
287
339
  end
288
340
  end
289
341
 
290
- require 'action_dispatch/http/mime_types'
342
+ require "action_dispatch/http/mime_types"
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Build list of Mime types for HTTP responses
2
- # http://www.iana.org/assignments/media-types/
4
+ # https://www.iana.org/assignments/media-types/
3
5
 
4
6
  Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )
5
7
  Mime::Type.register "text/plain", :text, [], %w(txt)
@@ -7,29 +9,42 @@ Mime::Type.register "text/javascript", :js, %w( application/javascript applicati
7
9
  Mime::Type.register "text/css", :css
8
10
  Mime::Type.register "text/calendar", :ics
9
11
  Mime::Type.register "text/csv", :csv
12
+ Mime::Type.register "text/vcard", :vcf
13
+ Mime::Type.register "text/vtt", :vtt, %w(vtt)
10
14
 
11
15
  Mime::Type.register "image/png", :png, [], %w(png)
12
- Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe)
16
+ Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe pjpeg)
13
17
  Mime::Type.register "image/gif", :gif, [], %w(gif)
14
18
  Mime::Type.register "image/bmp", :bmp, [], %w(bmp)
15
19
  Mime::Type.register "image/tiff", :tiff, [], %w(tif tiff)
20
+ Mime::Type.register "image/svg+xml", :svg
16
21
 
17
22
  Mime::Type.register "video/mpeg", :mpeg, [], %w(mpg mpeg mpe)
18
23
 
24
+ Mime::Type.register "audio/mpeg", :mp3, [], %w(mp1 mp2 mp3)
25
+ Mime::Type.register "audio/ogg", :ogg, [], %w(oga ogg spx opus)
26
+ Mime::Type.register "audio/aac", :m4a, %w( audio/mp4 ), %w(m4a mpg4 aac)
27
+
28
+ Mime::Type.register "video/webm", :webm, [], %w(webm)
29
+ Mime::Type.register "video/mp4", :mp4, [], %w(mp4 m4v)
30
+
31
+ Mime::Type.register "font/otf", :otf, [], %w(otf)
32
+ Mime::Type.register "font/ttf", :ttf, [], %w(ttf)
33
+ Mime::Type.register "font/woff", :woff, [], %w(woff)
34
+ Mime::Type.register "font/woff2", :woff2, [], %w(woff2)
35
+
19
36
  Mime::Type.register "application/xml", :xml, %w( text/xml application/x-xml )
20
37
  Mime::Type.register "application/rss+xml", :rss
21
38
  Mime::Type.register "application/atom+xml", :atom
22
- Mime::Type.register "application/x-yaml", :yaml, %w( text/yaml )
39
+ Mime::Type.register "application/x-yaml", :yaml, %w( text/yaml ), %w(yml yaml)
23
40
 
24
41
  Mime::Type.register "multipart/form-data", :multipart_form
25
42
  Mime::Type.register "application/x-www-form-urlencoded", :url_encoded_form
26
43
 
27
- # http://www.ietf.org/rfc/rfc4627.txt
44
+ # https://www.ietf.org/rfc/rfc4627.txt
28
45
  # http://www.json.org/JSONRequest.html
29
46
  Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
30
47
 
31
48
  Mime::Type.register "application/pdf", :pdf, [], %w(pdf)
32
49
  Mime::Type.register "application/zip", :zip, [], %w(zip)
33
-
34
- # Create Mime::ALL but do not add it to the SET.
35
- Mime::ALL = Mime::Type.new("*/*", :all, [])
50
+ Mime::Type.register "application/gzip", :gzip, %w(application/x-gzip), %w(gz)
@@ -1,74 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/duplicable"
4
+
1
5
  module ActionDispatch
2
6
  module Http
3
7
  class ParameterFilter
8
+ FILTERED = "[FILTERED]".freeze # :nodoc:
4
9
 
5
- def initialize(filters)
10
+ def initialize(filters = [])
6
11
  @filters = filters
7
12
  end
8
13
 
9
14
  def filter(params)
10
- if enabled?
11
- compiled_filter.call(params)
12
- else
13
- params.dup
14
- end
15
+ compiled_filter.call(params)
15
16
  end
16
17
 
17
18
  private
18
19
 
19
- def enabled?
20
- @filters.present?
20
+ def compiled_filter
21
+ @compiled_filter ||= CompiledFilter.compile(@filters)
21
22
  end
22
23
 
23
- FILTERED = '[FILTERED]'.freeze
24
+ class CompiledFilter # :nodoc:
25
+ def self.compile(filters)
26
+ return lambda { |params| params.dup } if filters.empty?
24
27
 
25
- def compiled_filter
26
- @compiled_filter ||= begin
27
- regexps, blocks = compile_filter
28
-
29
- lambda do |original_params|
30
- filtered_params = {}
31
-
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
44
-
45
- filtered_params[key] = value
46
- end
28
+ strings, regexps, blocks = [], [], []
47
29
 
48
- filtered_params
30
+ filters.each do |item|
31
+ case item
32
+ when Proc
33
+ blocks << item
34
+ when Regexp
35
+ regexps << item
36
+ else
37
+ strings << Regexp.escape(item.to_s)
38
+ end
49
39
  end
40
+
41
+ deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
42
+ deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
43
+
44
+ regexps << Regexp.new(strings.join("|".freeze), true) unless strings.empty?
45
+ deep_regexps << Regexp.new(deep_strings.join("|".freeze), true) unless deep_strings.empty?
46
+
47
+ new regexps, deep_regexps, blocks
50
48
  end
51
- end
52
49
 
53
- def compile_filter
54
- strings, regexps, blocks = [], [], []
55
-
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
65
- end
50
+ attr_reader :regexps, :deep_regexps, :blocks
51
+
52
+ def initialize(regexps, deep_regexps, blocks)
53
+ @regexps = regexps
54
+ @deep_regexps = deep_regexps.any? ? deep_regexps : nil
55
+ @blocks = blocks
66
56
  end
67
57
 
68
- regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
69
- [regexps, blocks]
70
- end
58
+ def call(original_params, parents = [])
59
+ filtered_params = original_params.class.new
60
+
61
+ original_params.each do |key, value|
62
+ parents.push(key) if deep_regexps
63
+ if regexps.any? { |r| key =~ r }
64
+ value = FILTERED
65
+ elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| joined =~ r }
66
+ value = FILTERED
67
+ elsif value.is_a?(Hash)
68
+ value = call(value, parents)
69
+ elsif value.is_a?(Array)
70
+ value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
71
+ elsif blocks.any?
72
+ key = key.dup if key.duplicable?
73
+ value = value.dup if value.duplicable?
74
+ blocks.each { |b| b.call(key, value) }
75
+ end
76
+ parents.pop if deep_regexps
77
+
78
+ filtered_params[key] = value
79
+ end
71
80
 
81
+ filtered_params
82
+ end
83
+ end
72
84
  end
73
85
  end
74
86
  end