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
@@ -4,10 +4,19 @@ require 'active_support/core_ext/hash/indifferent_access'
4
4
  module ActionDispatch
5
5
  module Http
6
6
  module Parameters
7
+ def initialize(env)
8
+ super
9
+ @symbolized_path_params = nil
10
+ end
11
+
7
12
  # Returns both GET and POST \parameters in a single hash.
8
13
  def parameters
9
14
  @env["action_dispatch.request.parameters"] ||= begin
10
- params = request_parameters.merge(query_parameters)
15
+ params = begin
16
+ request_parameters.merge(query_parameters)
17
+ rescue EOFError
18
+ query_parameters.dup
19
+ end
11
20
  params.merge!(path_parameters)
12
21
  encode_params(params).with_indifferent_access
13
22
  end
@@ -45,10 +54,8 @@ module ActionDispatch
45
54
  # you'll get a weird error down the road, but our form handling
46
55
  # should really prevent that from happening
47
56
  def encode_params(params)
48
- return params unless "ruby".encoding_aware?
49
-
50
57
  if params.is_a?(String)
51
- return params.force_encoding("UTF-8").encode!
58
+ return params.force_encoding(Encoding::UTF_8).encode!
52
59
  elsif !params.is_a?(Hash)
53
60
  return params
54
61
  end
@@ -65,7 +72,7 @@ module ActionDispatch
65
72
  end
66
73
  end
67
74
 
68
- # Convert nested Hash to HashWithIndifferentAccess
75
+ # Convert nested Hash to ActiveSupport::HashWithIndifferentAccess
69
76
  def normalize_parameters(value)
70
77
  case value
71
78
  when Hash
@@ -8,8 +8,7 @@ module ActionDispatch
8
8
  new
9
9
  end
10
10
 
11
- # TODO: Finally deal with the RAILS_CACHE global
12
- def initialize(store = RAILS_CACHE)
11
+ def initialize(store = Rails.cache)
13
12
  @store = store
14
13
  end
15
14
 
@@ -33,7 +32,7 @@ module ActionDispatch
33
32
  new
34
33
  end
35
34
 
36
- def initialize(store = RAILS_CACHE)
35
+ def initialize(store = Rails.cache)
37
36
  @store = store
38
37
  end
39
38
 
@@ -1,12 +1,16 @@
1
- require 'tempfile'
2
1
  require 'stringio'
3
- require 'strscan'
4
2
 
5
- require 'active_support/core_ext/hash/indifferent_access'
6
- require 'active_support/core_ext/string/access'
7
3
  require 'active_support/inflector'
8
4
  require 'action_dispatch/http/headers'
9
5
  require 'action_controller/metal/exceptions'
6
+ require 'rack/request'
7
+ require 'action_dispatch/http/cache'
8
+ require 'action_dispatch/http/mime_negotiation'
9
+ require 'action_dispatch/http/parameters'
10
+ require 'action_dispatch/http/filter_parameters'
11
+ require 'action_dispatch/http/upload'
12
+ require 'action_dispatch/http/url'
13
+ require 'active_support/core_ext/array/conversions'
10
14
 
11
15
  module ActionDispatch
12
16
  class Request < Rack::Request
@@ -17,7 +21,10 @@ module ActionDispatch
17
21
  include ActionDispatch::Http::Upload
18
22
  include ActionDispatch::Http::URL
19
23
 
20
- LOCALHOST = [/^127\.0\.0\.\d{1,3}$/, "::1", /^0:0:0:0:0:0:0:1(%.*)?$/].freeze
24
+ autoload :Session, 'action_dispatch/request/session'
25
+
26
+ LOCALHOST = Regexp.union [/^127\.0\.0\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
27
+
21
28
  ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE
22
29
  PATH_TRANSLATED REMOTE_HOST
23
30
  REMOTE_IDENT REMOTE_USER REMOTE_ADDR
@@ -35,6 +42,17 @@ module ActionDispatch
35
42
  METHOD
36
43
  end
37
44
 
45
+ def initialize(env)
46
+ super
47
+ @method = nil
48
+ @request_method = nil
49
+ @remote_ip = nil
50
+ @original_fullpath = nil
51
+ @fullpath = nil
52
+ @ip = nil
53
+ @uuid = nil
54
+ end
55
+
38
56
  def key?(key)
39
57
  @env.key?(key)
40
58
  end
@@ -56,12 +74,13 @@ module ActionDispatch
56
74
  RFC5789 = %w(PATCH)
57
75
 
58
76
  HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789
77
+
59
78
  HTTP_METHOD_LOOKUP = {}
60
79
 
61
80
  # Populate the HTTP method lookup cache
62
- HTTP_METHODS.each do |method|
81
+ HTTP_METHODS.each { |method|
63
82
  HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym
64
- end
83
+ }
65
84
 
66
85
  # Returns the HTTP \method that the application should see.
67
86
  # In the case where the \method was overridden by a middleware
@@ -102,6 +121,12 @@ module ActionDispatch
102
121
  HTTP_METHOD_LOOKUP[request_method] == :post
103
122
  end
104
123
 
124
+ # Is this a PATCH request?
125
+ # Equivalent to <tt>request.request_method == :patch</tt>.
126
+ def patch?
127
+ HTTP_METHOD_LOOKUP[request_method] == :patch
128
+ end
129
+
105
130
  # Is this a PUT request?
106
131
  # Equivalent to <tt>request.request_method_symbol == :put</tt>.
107
132
  def put?
@@ -115,9 +140,9 @@ module ActionDispatch
115
140
  end
116
141
 
117
142
  # Is this a HEAD request?
118
- # Equivalent to <tt>request.method_symbol == :head</tt>.
143
+ # Equivalent to <tt>request.request_method_symbol == :head</tt>.
119
144
  def head?
120
- HTTP_METHOD_LOOKUP[method] == :head
145
+ HTTP_METHOD_LOOKUP[request_method] == :head
121
146
  end
122
147
 
123
148
  # Provides access to the request's HTTP headers, for example:
@@ -195,7 +220,7 @@ module ActionDispatch
195
220
  # variable is already set, wrap it in a StringIO.
196
221
  def body
197
222
  if raw_post = @env['RAW_POST_DATA']
198
- raw_post.force_encoding(Encoding::BINARY) if raw_post.respond_to?(:force_encoding)
223
+ raw_post.force_encoding(Encoding::BINARY)
199
224
  StringIO.new(raw_post)
200
225
  else
201
226
  @env['rack.input']
@@ -213,32 +238,38 @@ module ActionDispatch
213
238
  # TODO This should be broken apart into AD::Request::Session and probably
214
239
  # be included by the session middleware.
215
240
  def reset_session
216
- session.destroy if session && session.respond_to?(:destroy)
217
- self.session = {}
241
+ if session && session.respond_to?(:destroy)
242
+ session.destroy
243
+ else
244
+ self.session = {}
245
+ end
218
246
  @env['action_dispatch.request.flash_hash'] = nil
219
247
  end
220
248
 
221
249
  def session=(session) #:nodoc:
222
- @env['rack.session'] = session
250
+ Session.set @env, session
223
251
  end
224
252
 
225
253
  def session_options=(options)
226
- @env['rack.session.options'] = options
254
+ Session::Options.set @env, options
227
255
  end
228
256
 
229
257
  # Override Rack's GET method to support indifferent access
230
258
  def GET
231
- @env["action_dispatch.request.query_parameters"] ||= deep_munge(normalize_parameters(super) || {})
259
+ @env["action_dispatch.request.query_parameters"] ||= (normalize_parameters(super) || {})
260
+ rescue TypeError => e
261
+ raise ActionController::BadRequest.new(:query, e)
232
262
  end
233
263
  alias :query_parameters :GET
234
264
 
235
265
  # Override Rack's POST method to support indifferent access
236
266
  def POST
237
- @env["action_dispatch.request.request_parameters"] ||= deep_munge(normalize_parameters(super) || {})
267
+ @env["action_dispatch.request.request_parameters"] ||= (normalize_parameters(super) || {})
268
+ rescue TypeError => e
269
+ raise ActionController::BadRequest.new(:request, e)
238
270
  end
239
271
  alias :request_parameters :POST
240
272
 
241
-
242
273
  # Returns the authorization header regardless of whether it was specified directly or through one of the
243
274
  # proxy alternatives.
244
275
  def authorization
@@ -250,7 +281,7 @@ module ActionDispatch
250
281
 
251
282
  # True if the request came from localhost, 127.0.0.1.
252
283
  def local?
253
- LOCALHOST.any? { |local_ip| local_ip === remote_addr && local_ip === remote_ip }
284
+ LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
254
285
  end
255
286
 
256
287
  # Remove nils from the params hash
@@ -1,7 +1,5 @@
1
- require 'digest/md5'
2
- require 'active_support/core_ext/module/delegation'
3
- require 'active_support/core_ext/object/blank'
4
1
  require 'active_support/core_ext/class/attribute_accessors'
2
+ require 'monitor'
5
3
 
6
4
  module ActionDispatch # :nodoc:
7
5
  # Represents an HTTP response generated by a controller action. Use it to
@@ -29,7 +27,7 @@ module ActionDispatch # :nodoc:
29
27
  # class DemoControllerTest < ActionDispatch::IntegrationTest
30
28
  # def test_print_root_path_to_console
31
29
  # get('/')
32
- # puts @response.body
30
+ # puts response.body
33
31
  # end
34
32
  # end
35
33
  class Response
@@ -41,7 +39,7 @@ module ActionDispatch # :nodoc:
41
39
  alias_method :headers, :header
42
40
 
43
41
  delegate :[], :[]=, :to => :@header
44
- delegate :each, :to => :@body
42
+ delegate :each, :to => :@stream
45
43
 
46
44
  # Sets the HTTP response's content MIME type. For example, in the controller
47
45
  # you could write this:
@@ -51,22 +49,64 @@ module ActionDispatch # :nodoc:
51
49
  # If a character set has been defined for this response (see charset=) then
52
50
  # the character set information will also be included in the content type
53
51
  # information.
54
- attr_accessor :charset, :content_type
52
+ attr_accessor :charset
53
+ attr_reader :content_type
55
54
 
56
55
  CONTENT_TYPE = "Content-Type".freeze
57
56
  SET_COOKIE = "Set-Cookie".freeze
58
57
  LOCATION = "Location".freeze
59
-
58
+
60
59
  cattr_accessor(:default_charset) { "utf-8" }
60
+ cattr_accessor(:default_headers)
61
61
 
62
62
  include Rack::Response::Helpers
63
+ include ActionDispatch::Http::FilterRedirect
63
64
  include ActionDispatch::Http::Cache::Response
65
+ include MonitorMixin
66
+
67
+ class Buffer # :nodoc:
68
+ def initialize(response, buf)
69
+ @response = response
70
+ @buf = buf
71
+ @closed = false
72
+ end
73
+
74
+ def write(string)
75
+ raise IOError, "closed stream" if closed?
76
+
77
+ @response.commit!
78
+ @buf.push string
79
+ end
80
+
81
+ def each(&block)
82
+ @buf.each(&block)
83
+ end
84
+
85
+ def close
86
+ @response.commit!
87
+ @closed = true
88
+ end
89
+
90
+ def closed?
91
+ @closed
92
+ end
93
+ end
94
+
95
+ attr_reader :stream
64
96
 
65
97
  def initialize(status = 200, header = {}, body = [])
98
+ super()
99
+
100
+ header = merge_default_headers(header, self.class.default_headers)
101
+
66
102
  self.body, self.header, self.status = body, header, status
67
103
 
68
104
  @sending_file = false
69
- @blank = false
105
+ @blank = false
106
+ @cv = new_cond
107
+ @committed = false
108
+ @content_type = nil
109
+ @charset = nil
70
110
 
71
111
  if content_type = self[CONTENT_TYPE]
72
112
  type, charset = content_type.split(/;\s*charset=/)
@@ -79,37 +119,69 @@ module ActionDispatch # :nodoc:
79
119
  yield self if block_given?
80
120
  end
81
121
 
122
+ def await_commit
123
+ synchronize do
124
+ @cv.wait_until { @committed }
125
+ end
126
+ end
127
+
128
+ def commit!
129
+ synchronize do
130
+ @committed = true
131
+ @cv.broadcast
132
+ end
133
+ end
134
+
135
+ def committed?
136
+ @committed
137
+ end
138
+
139
+ # Sets the HTTP status code.
82
140
  def status=(status)
83
141
  @status = Rack::Utils.status_code(status)
84
142
  end
85
143
 
86
- # The response code of the request
144
+ def content_type=(content_type)
145
+ @content_type = content_type.to_s
146
+ end
147
+
148
+ # The response code of the request.
87
149
  def response_code
88
150
  @status
89
151
  end
90
152
 
91
- # Returns a String to ensure compatibility with Net::HTTPResponse
153
+ # Returns a string to ensure compatibility with <tt>Net::HTTPResponse</tt>.
92
154
  def code
93
155
  @status.to_s
94
156
  end
95
157
 
158
+ # Returns the corresponding message for the current HTTP status code:
159
+ #
160
+ # response.status = 200
161
+ # response.message # => "OK"
162
+ #
163
+ # response.status = 404
164
+ # response.message # => "Not Found"
165
+ #
96
166
  def message
97
167
  Rack::Utils::HTTP_STATUS_CODES[@status]
98
168
  end
99
169
  alias_method :status_message, :message
100
170
 
101
171
  def respond_to?(method)
102
- if method.to_sym == :to_path
103
- @body.respond_to?(:to_path)
172
+ if method.to_s == 'to_path'
173
+ stream.respond_to?(:to_path)
104
174
  else
105
175
  super
106
176
  end
107
177
  end
108
178
 
109
179
  def to_path
110
- @body.to_path
180
+ stream.to_path
111
181
  end
112
182
 
183
+ # Returns the content of the response as a string. This contains the contents
184
+ # of any calls to <tt>render</tt>.
113
185
  def body
114
186
  strings = []
115
187
  each { |part| strings << part.to_s }
@@ -118,21 +190,21 @@ module ActionDispatch # :nodoc:
118
190
 
119
191
  EMPTY = " "
120
192
 
193
+ # Allows you to manually set or override the response body.
121
194
  def body=(body)
122
195
  @blank = true if body == EMPTY
123
196
 
124
- # Explicitly check for strings. This is *wrong* theoretically
125
- # but if we don't check this, the performance on string bodies
126
- # is bad on Ruby 1.8 (because strings responds to each then).
127
- @body = if body.respond_to?(:to_str) || !body.respond_to?(:each)
128
- [body]
197
+ if body.respond_to?(:to_path)
198
+ @stream = body
129
199
  else
130
- body
200
+ @stream = build_buffer self, munge_body_object(body)
131
201
  end
132
202
  end
133
203
 
134
204
  def body_parts
135
- @body
205
+ parts = []
206
+ @stream.each { |x| parts << x }
207
+ parts
136
208
  end
137
209
 
138
210
  def set_cookie(key, value)
@@ -153,21 +225,11 @@ module ActionDispatch # :nodoc:
153
225
  end
154
226
 
155
227
  def close
156
- @body.close if @body.respond_to?(:close)
228
+ stream.close if stream.respond_to?(:close)
157
229
  end
158
230
 
159
231
  def to_a
160
- assign_default_content_type_and_charset!
161
- handle_conditional_get!
162
-
163
- @header[SET_COOKIE] = @header[SET_COOKIE].join("\n") if @header[SET_COOKIE].respond_to?(:join)
164
-
165
- if [204, 304].include?(@status)
166
- @header.delete CONTENT_TYPE
167
- [@status, @header, []]
168
- else
169
- [@status, @header, self]
170
- end
232
+ rack_response @status, @header.to_hash
171
233
  end
172
234
  alias prepare! to_a
173
235
  alias to_ary to_a # For implicit splat on 1.9.2
@@ -191,16 +253,48 @@ module ActionDispatch # :nodoc:
191
253
 
192
254
  private
193
255
 
194
- def assign_default_content_type_and_charset!
256
+ def merge_default_headers(original, default)
257
+ return original unless default.respond_to?(:merge)
258
+
259
+ default.merge(original)
260
+ end
261
+
262
+ def build_buffer(response, body)
263
+ Buffer.new response, body
264
+ end
265
+
266
+ def munge_body_object(body)
267
+ body.respond_to?(:each) ? body : [body]
268
+ end
269
+
270
+ def assign_default_content_type_and_charset!(headers)
195
271
  return if headers[CONTENT_TYPE].present?
196
272
 
197
273
  @content_type ||= Mime::HTML
198
- @charset ||= self.class.default_charset
274
+ @charset ||= self.class.default_charset unless @charset == false
199
275
 
200
276
  type = @content_type.to_s.dup
201
- type << "; charset=#{@charset}" unless @sending_file
277
+ type << "; charset=#{@charset}" if append_charset?
202
278
 
203
279
  headers[CONTENT_TYPE] = type
204
280
  end
281
+
282
+ def append_charset?
283
+ !@sending_file && @charset != false
284
+ end
285
+
286
+ def rack_response(status, header)
287
+ assign_default_content_type_and_charset!(header)
288
+ handle_conditional_get!
289
+
290
+ header[SET_COOKIE] = header[SET_COOKIE].join("\n") if header[SET_COOKIE].respond_to?(:join)
291
+
292
+ if [204, 304].include?(@status)
293
+ header.delete CONTENT_TYPE
294
+ [status, header, []]
295
+ else
296
+ [status, header, self]
297
+ end
298
+ end
205
299
  end
206
300
  end