actionpack 2.2.3 → 2.3.2

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 (264) hide show
  1. data/CHANGELOG +433 -375
  2. data/MIT-LICENSE +1 -1
  3. data/README +21 -75
  4. data/Rakefile +1 -1
  5. data/lib/action_controller.rb +80 -43
  6. data/lib/action_controller/assertions/model_assertions.rb +1 -0
  7. data/lib/action_controller/assertions/response_assertions.rb +43 -16
  8. data/lib/action_controller/assertions/routing_assertions.rb +1 -1
  9. data/lib/action_controller/assertions/selector_assertions.rb +17 -12
  10. data/lib/action_controller/assertions/tag_assertions.rb +1 -4
  11. data/lib/action_controller/base.rb +153 -82
  12. data/lib/action_controller/benchmarking.rb +9 -9
  13. data/lib/action_controller/caching.rb +9 -11
  14. data/lib/action_controller/caching/actions.rb +11 -18
  15. data/lib/action_controller/caching/fragments.rb +28 -20
  16. data/lib/action_controller/caching/pages.rb +13 -15
  17. data/lib/action_controller/caching/sweeping.rb +2 -2
  18. data/lib/action_controller/cgi_ext.rb +0 -1
  19. data/lib/action_controller/cgi_ext/cookie.rb +2 -0
  20. data/lib/action_controller/cgi_process.rb +54 -162
  21. data/lib/action_controller/cookies.rb +13 -25
  22. data/lib/action_controller/dispatcher.rb +43 -122
  23. data/lib/action_controller/failsafe.rb +52 -0
  24. data/lib/action_controller/flash.rb +38 -47
  25. data/lib/action_controller/helpers.rb +13 -9
  26. data/lib/action_controller/http_authentication.rb +203 -23
  27. data/lib/action_controller/integration.rb +126 -70
  28. data/lib/action_controller/layout.rb +36 -39
  29. data/lib/action_controller/middleware_stack.rb +119 -0
  30. data/lib/action_controller/middlewares.rb +13 -0
  31. data/lib/action_controller/mime_responds.rb +19 -4
  32. data/lib/action_controller/mime_type.rb +8 -0
  33. data/lib/action_controller/params_parser.rb +71 -0
  34. data/lib/action_controller/performance_test.rb +0 -1
  35. data/lib/action_controller/polymorphic_routes.rb +36 -30
  36. data/lib/action_controller/reloader.rb +14 -0
  37. data/lib/action_controller/request.rb +107 -499
  38. data/lib/action_controller/request_forgery_protection.rb +7 -39
  39. data/lib/action_controller/rescue.rb +55 -35
  40. data/lib/action_controller/resources.rb +34 -31
  41. data/lib/action_controller/response.rb +99 -57
  42. data/lib/action_controller/rewindable_input.rb +28 -0
  43. data/lib/action_controller/routing.rb +7 -7
  44. data/lib/action_controller/routing/builder.rb +4 -1
  45. data/lib/action_controller/routing/optimisations.rb +1 -1
  46. data/lib/action_controller/routing/recognition_optimisation.rb +1 -2
  47. data/lib/action_controller/routing/route.rb +15 -5
  48. data/lib/action_controller/routing/route_set.rb +82 -35
  49. data/lib/action_controller/routing/segments.rb +35 -0
  50. data/lib/action_controller/session/abstract_store.rb +181 -0
  51. data/lib/action_controller/session/cookie_store.rb +197 -175
  52. data/lib/action_controller/session/mem_cache_store.rb +36 -83
  53. data/lib/action_controller/session_management.rb +26 -134
  54. data/lib/action_controller/streaming.rb +24 -7
  55. data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
  56. data/lib/action_controller/templates/rescues/template_error.erb +2 -2
  57. data/lib/action_controller/test_case.rb +87 -30
  58. data/lib/action_controller/test_process.rb +145 -104
  59. data/lib/action_controller/uploaded_file.rb +44 -0
  60. data/lib/action_controller/url_rewriter.rb +3 -6
  61. data/lib/action_controller/vendor/html-scanner.rb +16 -0
  62. data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
  63. data/lib/action_controller/vendor/rack-1.0/rack.rb +89 -0
  64. data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +22 -0
  65. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +37 -0
  66. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +37 -0
  67. data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +58 -0
  68. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +124 -0
  69. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +51 -0
  70. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +55 -0
  71. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +40 -0
  72. data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +480 -0
  73. data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +63 -0
  74. data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +36 -0
  75. data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +49 -0
  76. data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +61 -0
  77. data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +45 -0
  78. data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +29 -0
  79. data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +23 -0
  80. data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +85 -0
  81. data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +153 -0
  82. data/lib/action_controller/vendor/rack-1.0/rack/file.rb +88 -0
  83. data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +48 -0
  84. data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +61 -0
  85. data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +8 -0
  86. data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +89 -0
  87. data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +55 -0
  88. data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +84 -0
  89. data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +59 -0
  90. data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +8 -0
  91. data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +18 -0
  92. data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +67 -0
  93. data/lib/action_controller/vendor/rack-1.0/rack/head.rb +19 -0
  94. data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +462 -0
  95. data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +65 -0
  96. data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +16 -0
  97. data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +27 -0
  98. data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +204 -0
  99. data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +160 -0
  100. data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +57 -0
  101. data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +64 -0
  102. data/lib/action_controller/vendor/rack-1.0/rack/request.rb +241 -0
  103. data/lib/action_controller/vendor/rack-1.0/rack/response.rb +179 -0
  104. data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +142 -0
  105. data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +91 -0
  106. data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +109 -0
  107. data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +100 -0
  108. data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +349 -0
  109. data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +106 -0
  110. data/lib/action_controller/vendor/rack-1.0/rack/static.rb +38 -0
  111. data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +55 -0
  112. data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +392 -0
  113. data/lib/action_controller/verification.rb +1 -1
  114. data/lib/action_pack.rb +1 -1
  115. data/lib/action_pack/version.rb +2 -2
  116. data/lib/action_view.rb +22 -17
  117. data/lib/action_view/base.rb +53 -79
  118. data/lib/action_view/erb/util.rb +38 -0
  119. data/lib/action_view/helpers.rb +24 -5
  120. data/lib/action_view/helpers/active_record_helper.rb +2 -2
  121. data/lib/action_view/helpers/asset_tag_helper.rb +81 -50
  122. data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
  123. data/lib/action_view/helpers/benchmark_helper.rb +26 -5
  124. data/lib/action_view/helpers/date_helper.rb +82 -7
  125. data/lib/action_view/helpers/form_helper.rb +295 -64
  126. data/lib/action_view/helpers/form_options_helper.rb +160 -18
  127. data/lib/action_view/helpers/form_tag_helper.rb +2 -2
  128. data/lib/action_view/helpers/number_helper.rb +31 -18
  129. data/lib/action_view/helpers/prototype_helper.rb +2 -12
  130. data/lib/action_view/helpers/sanitize_helper.rb +0 -10
  131. data/lib/action_view/helpers/scriptaculous_helper.rb +1 -0
  132. data/lib/action_view/helpers/tag_helper.rb +3 -4
  133. data/lib/action_view/helpers/text_helper.rb +99 -122
  134. data/lib/action_view/helpers/translation_helper.rb +19 -1
  135. data/lib/action_view/helpers/url_helper.rb +25 -2
  136. data/lib/action_view/inline_template.rb +1 -1
  137. data/lib/action_view/locale/en.yml +19 -1
  138. data/lib/action_view/partials.rb +46 -9
  139. data/lib/action_view/paths.rb +28 -84
  140. data/lib/action_view/reloadable_template.rb +117 -0
  141. data/lib/action_view/renderable.rb +28 -35
  142. data/lib/action_view/renderable_partial.rb +3 -4
  143. data/lib/action_view/template.rb +172 -31
  144. data/lib/action_view/template_error.rb +8 -9
  145. data/lib/action_view/template_handler.rb +1 -1
  146. data/lib/action_view/template_handlers.rb +9 -6
  147. data/lib/action_view/template_handlers/erb.rb +2 -39
  148. data/lib/action_view/template_handlers/rjs.rb +1 -0
  149. data/lib/action_view/test_case.rb +27 -1
  150. data/test/abstract_unit.rb +23 -17
  151. data/test/active_record_unit.rb +5 -4
  152. data/test/activerecord/active_record_store_test.rb +139 -106
  153. data/test/activerecord/render_partial_with_record_identification_test.rb +5 -21
  154. data/test/controller/action_pack_assertions_test.rb +25 -23
  155. data/test/controller/addresses_render_test.rb +3 -6
  156. data/test/controller/assert_select_test.rb +83 -70
  157. data/test/controller/base_test.rb +11 -13
  158. data/test/controller/benchmark_test.rb +3 -3
  159. data/test/controller/caching_test.rb +34 -24
  160. data/test/controller/capture_test.rb +3 -6
  161. data/test/controller/content_type_test.rb +3 -6
  162. data/test/controller/cookie_test.rb +31 -66
  163. data/test/controller/deprecation/deprecated_base_methods_test.rb +9 -11
  164. data/test/controller/dispatcher_test.rb +23 -28
  165. data/test/controller/fake_models.rb +8 -0
  166. data/test/controller/filters_test.rb +6 -2
  167. data/test/controller/flash_test.rb +2 -6
  168. data/test/controller/helper_test.rb +15 -1
  169. data/test/controller/html-scanner/document_test.rb +1 -1
  170. data/test/controller/html-scanner/sanitizer_test.rb +1 -1
  171. data/test/controller/http_basic_authentication_test.rb +88 -0
  172. data/test/controller/http_digest_authentication_test.rb +178 -0
  173. data/test/controller/integration_test.rb +56 -52
  174. data/test/controller/layout_test.rb +46 -44
  175. data/test/controller/middleware_stack_test.rb +90 -0
  176. data/test/controller/mime_responds_test.rb +7 -11
  177. data/test/controller/mime_type_test.rb +9 -0
  178. data/test/controller/polymorphic_routes_test.rb +235 -151
  179. data/test/controller/rack_test.rb +52 -81
  180. data/test/controller/redirect_test.rb +6 -14
  181. data/test/controller/render_test.rb +273 -60
  182. data/test/controller/request/json_params_parsing_test.rb +45 -0
  183. data/test/controller/request/multipart_params_parsing_test.rb +223 -0
  184. data/test/controller/request/query_string_parsing_test.rb +120 -0
  185. data/test/controller/request/url_encoded_params_parsing_test.rb +184 -0
  186. data/test/controller/request/xml_params_parsing_test.rb +88 -0
  187. data/test/controller/request_forgery_protection_test.rb +17 -98
  188. data/test/controller/request_test.rb +45 -530
  189. data/test/controller/rescue_test.rb +45 -22
  190. data/test/controller/resources_test.rb +112 -37
  191. data/test/controller/routing_test.rb +1442 -1384
  192. data/test/controller/selector_test.rb +3 -3
  193. data/test/controller/send_file_test.rb +30 -3
  194. data/test/controller/session/cookie_store_test.rb +169 -240
  195. data/test/controller/session/mem_cache_store_test.rb +94 -148
  196. data/test/controller/session/test_session_test.rb +58 -0
  197. data/test/controller/test_test.rb +32 -13
  198. data/test/controller/url_rewriter_test.rb +54 -4
  199. data/test/controller/verification_test.rb +1 -1
  200. data/test/controller/view_paths_test.rb +15 -15
  201. data/test/controller/webservice_test.rb +178 -147
  202. data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
  203. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  204. data/test/fixtures/layouts/default_html.html.erb +1 -0
  205. data/test/fixtures/layouts/xhr.html.erb +2 -0
  206. data/test/fixtures/multipart/empty +10 -0
  207. data/test/fixtures/multipart/hello.txt +1 -0
  208. data/test/fixtures/multipart/none +9 -0
  209. data/test/fixtures/public/500.da.html +1 -0
  210. data/test/fixtures/quiz/questions/_question.html.erb +1 -0
  211. data/test/fixtures/replies.yml +1 -1
  212. data/test/fixtures/test/_one.html.erb +1 -0
  213. data/test/fixtures/test/_two.html.erb +1 -0
  214. data/test/fixtures/test/dont_pick_me +1 -0
  215. data/test/fixtures/test/hello.builder +1 -1
  216. data/test/fixtures/test/hello_world.da.html.erb +1 -0
  217. data/test/fixtures/test/hello_world.erb~ +1 -0
  218. data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
  219. data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
  220. data/test/fixtures/test/malformed/malformed.erb~ +1 -0
  221. data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
  222. data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
  223. data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
  224. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
  225. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
  226. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
  227. data/test/fixtures/test/utf8.html.erb +2 -0
  228. data/test/template/active_record_helper_i18n_test.rb +31 -33
  229. data/test/template/active_record_helper_test.rb +34 -0
  230. data/test/template/asset_tag_helper_test.rb +52 -14
  231. data/test/template/atom_feed_helper_test.rb +3 -5
  232. data/test/template/benchmark_helper_test.rb +50 -24
  233. data/test/template/compiled_templates_test.rb +177 -33
  234. data/test/template/date_helper_i18n_test.rb +88 -81
  235. data/test/template/date_helper_test.rb +427 -43
  236. data/test/template/form_helper_test.rb +243 -44
  237. data/test/template/form_options_helper_test.rb +631 -565
  238. data/test/template/form_tag_helper_test.rb +9 -2
  239. data/test/template/javascript_helper_test.rb +0 -5
  240. data/test/template/number_helper_i18n_test.rb +60 -48
  241. data/test/template/number_helper_test.rb +1 -0
  242. data/test/template/render_test.rb +117 -35
  243. data/test/template/test_test.rb +4 -6
  244. data/test/template/text_helper_test.rb +129 -50
  245. data/test/template/translation_helper_test.rb +23 -19
  246. data/test/template/url_helper_test.rb +35 -2
  247. data/test/view/test_case_test.rb +8 -0
  248. metadata +197 -23
  249. data/lib/action_controller/assertions.rb +0 -69
  250. data/lib/action_controller/caching/sql_cache.rb +0 -18
  251. data/lib/action_controller/cgi_ext/session.rb +0 -53
  252. data/lib/action_controller/components.rb +0 -169
  253. data/lib/action_controller/rack_process.rb +0 -297
  254. data/lib/action_controller/request_profiler.rb +0 -169
  255. data/lib/action_controller/session/active_record_store.rb +0 -340
  256. data/lib/action_controller/session/drb_server.rb +0 -32
  257. data/lib/action_controller/session/drb_store.rb +0 -35
  258. data/test/controller/cgi_test.rb +0 -269
  259. data/test/controller/components_test.rb +0 -156
  260. data/test/controller/http_authentication_test.rb +0 -54
  261. data/test/controller/integration_upload_test.rb +0 -43
  262. data/test/controller/session_fixation_test.rb +0 -89
  263. data/test/controller/session_management_test.rb +0 -178
  264. data/test/fixtures/test/hello_world.js +0 -1
@@ -134,7 +134,7 @@ module ActionController
134
134
  path = "/#{path}" unless path.first == '/'
135
135
 
136
136
  # Assume given controller
137
- request = ActionController::TestRequest.new({}, {}, nil)
137
+ request = ActionController::TestRequest.new
138
138
  request.env["REQUEST_METHOD"] = request_method.to_s.upcase if request_method
139
139
  request.path = path
140
140
 
@@ -3,9 +3,6 @@
3
3
  # Under MIT and/or CC By license.
4
4
  #++
5
5
 
6
- require 'rexml/document'
7
- require 'html/document'
8
-
9
6
  module ActionController
10
7
  module Assertions
11
8
  unless const_defined?(:NO_STRIP)
@@ -112,20 +109,27 @@ module ActionController
112
109
  # starting from (and including) that element and all its children in
113
110
  # depth-first order.
114
111
  #
115
- # If no element if specified, calling +assert_select+ will select from the
116
- # response HTML. Calling #assert_select inside an +assert_select+ block will
117
- # run the assertion for each element selected by the enclosing assertion.
112
+ # If no element if specified, calling +assert_select+ selects from the
113
+ # response HTML unless +assert_select+ is called from within an +assert_select+ block.
114
+ #
115
+ # When called with a block +assert_select+ passes an array of selected elements
116
+ # to the block. Calling +assert_select+ from the block, with no element specified,
117
+ # runs the assertion on the complete set of elements selected by the enclosing assertion.
118
+ # Alternatively the array may be iterated through so that +assert_select+ can be called
119
+ # separately for each element.
120
+ #
118
121
  #
119
122
  # ==== Example
120
- # assert_select "ol>li" do |elements|
123
+ # If the response contains two ordered lists, each with four list elements then:
124
+ # assert_select "ol" do |elements|
121
125
  # elements.each do |element|
122
- # assert_select element, "li"
126
+ # assert_select element, "li", 4
123
127
  # end
124
128
  # end
125
129
  #
126
- # Or for short:
127
- # assert_select "ol>li" do
128
- # assert_select "li"
130
+ # will pass, as will:
131
+ # assert_select "ol" do
132
+ # assert_select "li", 8
129
133
  # end
130
134
  #
131
135
  # The selector may be a CSS selector expression (String), an expression
@@ -405,6 +409,7 @@ module ActionController
405
409
  if rjs_type
406
410
  if rjs_type == :insert
407
411
  position = args.shift
412
+ id = args.shift
408
413
  insertion = "insert_#{position}".to_sym
409
414
  raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion]
410
415
  statement = "(#{RJS_STATEMENTS[insertion]})"
@@ -590,7 +595,7 @@ module ActionController
590
595
  def response_from_page_or_rjs()
591
596
  content_type = @response.content_type
592
597
 
593
- if content_type && content_type =~ /text\/javascript/
598
+ if content_type && Mime::JS =~ content_type
594
599
  body = @response.body.dup
595
600
  root = HTML::Node.new(nil)
596
601
 
@@ -1,6 +1,3 @@
1
- require 'rexml/document'
2
- require 'html/document'
3
-
4
1
  module ActionController
5
2
  module Assertions
6
3
  # Pair of assertions to testing elements in the HTML output of the response.
@@ -127,4 +124,4 @@ module ActionController
127
124
  end
128
125
  end
129
126
  end
130
- end
127
+ end
@@ -1,12 +1,3 @@
1
- require 'action_controller/mime_type'
2
- require 'action_controller/request'
3
- require 'action_controller/response'
4
- require 'action_controller/routing'
5
- require 'action_controller/resources'
6
- require 'action_controller/url_rewriter'
7
- require 'action_controller/status_codes'
8
- require 'action_view'
9
- require 'drb'
10
1
  require 'set'
11
2
 
12
3
  module ActionController #:nodoc:
@@ -31,7 +22,7 @@ module ActionController #:nodoc:
31
22
  attr_reader :allowed_methods
32
23
 
33
24
  def initialize(*allowed_methods)
34
- super("Only #{allowed_methods.to_sentence} requests are allowed.")
25
+ super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.")
35
26
  @allowed_methods = allowed_methods
36
27
  end
37
28
 
@@ -173,8 +164,8 @@ module ActionController #:nodoc:
173
164
  #
174
165
  # Other options for session storage are:
175
166
  #
176
- # * ActiveRecordStore - Sessions are stored in your database, which works better than PStore with multiple app servers and,
177
- # unlike CookieStore, hides your session contents from the user. To use ActiveRecordStore, set
167
+ # * ActiveRecord::SessionStore - Sessions are stored in your database, which works better than PStore with multiple app servers and,
168
+ # unlike CookieStore, hides your session contents from the user. To use ActiveRecord::SessionStore, set
178
169
  #
179
170
  # config.action_controller.session_store = :active_record_store
180
171
  #
@@ -263,7 +254,7 @@ module ActionController #:nodoc:
263
254
  cattr_reader :protected_instance_variables
264
255
  # Controller specific instance variables which will not be accessible inside views.
265
256
  @@protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
266
- @action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params
257
+ @action_name @before_filter_chain_aborted @action_cache_path @_session @_headers @_params
267
258
  @_flash @_response)
268
259
 
269
260
  # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
@@ -310,10 +301,7 @@ module ActionController #:nodoc:
310
301
  # A YAML parser is also available and can be turned on with:
311
302
  #
312
303
  # ActionController::Base.param_parsers[Mime::YAML] = :yaml
313
- @@param_parsers = { Mime::MULTIPART_FORM => :multipart_form,
314
- Mime::URL_ENCODED_FORM => :url_encoded_form,
315
- Mime::XML => :xml_simple,
316
- Mime::JSON => :json }
304
+ @@param_parsers = {}
317
305
  cattr_accessor :param_parsers
318
306
 
319
307
  # Controls the default charset for all renders.
@@ -336,6 +324,10 @@ module ActionController #:nodoc:
336
324
  # sets it to <tt>:authenticity_token</tt> by default.
337
325
  cattr_accessor :request_forgery_protection_token
338
326
 
327
+ # Controls the IP Spoofing check when determining the remote IP.
328
+ @@ip_spoofing_check = true
329
+ cattr_accessor :ip_spoofing_check
330
+
339
331
  # Indicates whether or not optimise the generated named
340
332
  # route helper methods
341
333
  cattr_accessor :optimise_named_routes
@@ -387,6 +379,13 @@ module ActionController #:nodoc:
387
379
  attr_accessor :action_name
388
380
 
389
381
  class << self
382
+ def call(env)
383
+ # HACK: For global rescue to have access to the original request and response
384
+ request = env["action_controller.rescue.request"] ||= Request.new(env)
385
+ response = env["action_controller.rescue.response"] ||= Response.new
386
+ process(request, response)
387
+ end
388
+
390
389
  # Factory for the standard create, process loop where the controller is discarded after processing.
391
390
  def process(request, response) #:nodoc:
392
391
  new.process(request, response)
@@ -507,7 +506,7 @@ module ActionController #:nodoc:
507
506
  protected :filter_parameters
508
507
  end
509
508
 
510
- delegate :exempt_from_layout, :to => 'ActionView::Base'
509
+ delegate :exempt_from_layout, :to => 'ActionView::Template'
511
510
  end
512
511
 
513
512
  public
@@ -529,7 +528,7 @@ module ActionController #:nodoc:
529
528
  end
530
529
 
531
530
  def send_response
532
- response.prepare! unless component_request?
531
+ response.prepare!
533
532
  response
534
533
  end
535
534
 
@@ -645,7 +644,7 @@ module ActionController #:nodoc:
645
644
  end
646
645
 
647
646
  def session_enabled?
648
- request.session_options && request.session_options[:disabled] != false
647
+ ActiveSupport::Deprecation.warn("Sessions are now lazy loaded. So if you don't access them, consider them disabled.", caller)
649
648
  end
650
649
 
651
650
  self.view_paths = []
@@ -785,9 +784,37 @@ module ActionController #:nodoc:
785
784
  # # placed in "app/views/layouts/special.r(html|xml)"
786
785
  # render :text => "Hi there!", :layout => "special"
787
786
  #
788
- # The <tt>:text</tt> option can also accept a Proc object, which can be used to manually control the page generation. This should
789
- # generally be avoided, as it violates the separation between code and content, and because almost everything that can be
790
- # done with this method can also be done more cleanly using one of the other rendering methods, most notably templates.
787
+ # === Streaming data and/or controlling the page generation
788
+ #
789
+ # The <tt>:text</tt> option can also accept a Proc object, which can be used to:
790
+ #
791
+ # 1. stream on-the-fly generated data to the browser. Note that you should
792
+ # use the methods provided by ActionController::Steaming instead if you
793
+ # want to stream a buffer or a file.
794
+ # 2. manually control the page generation. This should generally be avoided,
795
+ # as it violates the separation between code and content, and because almost
796
+ # everything that can be done with this method can also be done more cleanly
797
+ # using one of the other rendering methods, most notably templates.
798
+ #
799
+ # Two arguments are passed to the proc, a <tt>response</tt> object and an
800
+ # <tt>output</tt> object. The response object is equivalent to the return
801
+ # value of the ActionController::Base#response method, and can be used to
802
+ # control various things in the HTTP response, such as setting the
803
+ # Content-Type header. The output object is an writable <tt>IO</tt>-like
804
+ # object, so one can call <tt>write</tt> and <tt>flush</tt> on it.
805
+ #
806
+ # The following example demonstrates how one can stream a large amount of
807
+ # on-the-fly generated data to the browser:
808
+ #
809
+ # # Streams about 180 MB of generated data to the browser.
810
+ # render :text => proc { |response, output|
811
+ # 10_000_000.times do |i|
812
+ # output.write("This is line #{i}\n")
813
+ # output.flush
814
+ # end
815
+ # }
816
+ #
817
+ # Another example:
791
818
  #
792
819
  # # Renders "Hello from code!"
793
820
  # render :text => proc { |response, output| output.write("Hello from code!") }
@@ -864,20 +891,31 @@ module ActionController #:nodoc:
864
891
  def render(options = nil, extra_options = {}, &block) #:doc:
865
892
  raise DoubleRenderError, "Can only render or redirect once per action" if performed?
866
893
 
894
+ validate_render_arguments(options, extra_options, block_given?)
895
+
867
896
  if options.nil?
868
- return render(:file => default_template_name, :layout => true)
869
- elsif !extra_options.is_a?(Hash)
870
- raise RenderError, "You called render with invalid options : #{options.inspect}, #{extra_options.inspect}"
871
- else
872
- if options == :update
873
- options = extra_options.merge({ :update => true })
874
- elsif !options.is_a?(Hash)
875
- raise RenderError, "You called render with invalid options : #{options.inspect}"
897
+ options = { :template => default_template, :layout => true }
898
+ elsif options == :update
899
+ options = extra_options.merge({ :update => true })
900
+ elsif options.is_a?(String) || options.is_a?(Symbol)
901
+ case options.to_s.index('/')
902
+ when 0
903
+ extra_options[:file] = options
904
+ when nil
905
+ extra_options[:action] = options
906
+ else
907
+ extra_options[:template] = options
876
908
  end
909
+
910
+ options = extra_options
911
+ elsif !options.is_a?(Hash)
912
+ extra_options[:partial] = options
913
+ options = extra_options
877
914
  end
878
915
 
879
- response.layout = layout = pick_layout(options)
880
- logger.info("Rendering template within #{layout}") if logger && layout
916
+ layout = pick_layout(options)
917
+ response.layout = layout.path_without_format_and_extension if layout
918
+ logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger && layout
881
919
 
882
920
  if content_type = options[:content_type]
883
921
  response.content_type = content_type.to_s
@@ -902,7 +940,7 @@ module ActionController #:nodoc:
902
940
  render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
903
941
 
904
942
  elsif action_name = options[:action]
905
- render_for_file(default_template_name(action_name.to_s), options[:status], layout)
943
+ render_for_file(default_template(action_name.to_s), options[:status], layout)
906
944
 
907
945
  elsif xml = options[:xml]
908
946
  response.content_type ||= Mime::XML
@@ -937,7 +975,7 @@ module ActionController #:nodoc:
937
975
  render_for_text(nil, options[:status])
938
976
 
939
977
  else
940
- render_for_file(default_template_name, options[:status], layout)
978
+ render_for_file(default_template, options[:status], layout)
941
979
  end
942
980
  end
943
981
  end
@@ -994,7 +1032,7 @@ module ActionController #:nodoc:
994
1032
  @performed_redirect = false
995
1033
  response.redirected_to = nil
996
1034
  response.redirected_to_method_params = nil
997
- response.headers['Status'] = DEFAULT_RENDER_STATUS_CODE
1035
+ response.status = DEFAULT_RENDER_STATUS_CODE
998
1036
  response.headers.delete('Location')
999
1037
  end
1000
1038
 
@@ -1065,7 +1103,6 @@ module ActionController #:nodoc:
1065
1103
  end
1066
1104
 
1067
1105
  response.redirected_to = options
1068
- logger.info("Redirected to #{options}") if logger && logger.info?
1069
1106
 
1070
1107
  case options
1071
1108
  # The scheme name consist of a letter followed by any combination of
@@ -1088,6 +1125,7 @@ module ActionController #:nodoc:
1088
1125
 
1089
1126
  def redirect_to_full_url(url, status)
1090
1127
  raise DoubleRenderError if performed?
1128
+ logger.info("Redirected to #{url}") if logger && logger.info?
1091
1129
  response.redirect(url, interpret_status(status))
1092
1130
  @performed_redirect = true
1093
1131
  end
@@ -1097,6 +1135,11 @@ module ActionController #:nodoc:
1097
1135
  # request is considered stale and should be generated from scratch. Otherwise,
1098
1136
  # it's fresh and we don't need to generate anything and a reply of "304 Not Modified" is sent.
1099
1137
  #
1138
+ # Parameters:
1139
+ # * <tt>:etag</tt>
1140
+ # * <tt>:last_modified</tt>
1141
+ # * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
1142
+ #
1100
1143
  # Example:
1101
1144
  #
1102
1145
  # def show
@@ -1115,22 +1158,36 @@ module ActionController #:nodoc:
1115
1158
  end
1116
1159
 
1117
1160
  # Sets the etag, last_modified, or both on the response and renders a
1118
- # "304 Not Modified" response if the request is already fresh.
1161
+ # "304 Not Modified" response if the request is already fresh.
1162
+ #
1163
+ # Parameters:
1164
+ # * <tt>:etag</tt>
1165
+ # * <tt>:last_modified</tt>
1166
+ # * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
1119
1167
  #
1120
1168
  # Example:
1121
1169
  #
1122
1170
  # def show
1123
1171
  # @article = Article.find(params[:id])
1124
- # fresh_when(:etag => @article, :last_modified => @article.created_at.utc)
1172
+ # fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
1125
1173
  # end
1126
- #
1127
- # This will render the show template if the request isn't sending a matching etag or
1174
+ #
1175
+ # This will render the show template if the request isn't sending a matching etag or
1128
1176
  # If-Modified-Since header and just a "304 Not Modified" response if there's a match.
1177
+ #
1129
1178
  def fresh_when(options)
1130
- options.assert_valid_keys(:etag, :last_modified)
1179
+ options.assert_valid_keys(:etag, :last_modified, :public)
1131
1180
 
1132
1181
  response.etag = options[:etag] if options[:etag]
1133
1182
  response.last_modified = options[:last_modified] if options[:last_modified]
1183
+
1184
+ if options[:public]
1185
+ cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
1186
+ cache_control.delete("private")
1187
+ cache_control.delete("no-cache")
1188
+ cache_control << "public"
1189
+ response.headers["Cache-Control"] = cache_control.join(', ')
1190
+ end
1134
1191
 
1135
1192
  if request.fresh?(response)
1136
1193
  head :not_modified
@@ -1142,15 +1199,26 @@ module ActionController #:nodoc:
1142
1199
  #
1143
1200
  # Examples:
1144
1201
  # expires_in 20.minutes
1145
- # expires_in 3.hours, :private => false
1146
- # expires in 3.hours, 'max-stale' => 5.hours, :private => nil, :public => true
1202
+ # expires_in 3.hours, :public => true
1203
+ # expires in 3.hours, 'max-stale' => 5.hours, :public => true
1147
1204
  #
1148
1205
  # This method will overwrite an existing Cache-Control header.
1149
1206
  # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
1150
1207
  def expires_in(seconds, options = {}) #:doc:
1151
- cache_options = { 'max-age' => seconds, 'private' => true }.symbolize_keys.merge!(options.symbolize_keys)
1152
- cache_options.delete_if { |k,v| v.nil? or v == false }
1153
- cache_control = cache_options.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
1208
+ cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
1209
+
1210
+ cache_control << "max-age=#{seconds}"
1211
+ cache_control.delete("no-cache")
1212
+ if options[:public]
1213
+ cache_control.delete("private")
1214
+ cache_control << "public"
1215
+ else
1216
+ cache_control << "private"
1217
+ end
1218
+
1219
+ # This allows for additional headers to be passed through like 'max-stale' => 5.hours
1220
+ cache_control += options.symbolize_keys.reject{|k,v| k == :public || k == :private }.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
1221
+
1154
1222
  response.headers["Cache-Control"] = cache_control.join(', ')
1155
1223
  end
1156
1224
 
@@ -1164,23 +1232,19 @@ module ActionController #:nodoc:
1164
1232
  def reset_session #:doc:
1165
1233
  request.reset_session
1166
1234
  @_session = request.session
1167
- #http://rails.lighthouseapp.com/projects/8994/tickets/1558-memory-problem-on-reset_session-in-around_filter#ticket-1558-1
1168
- #MRI appears to have a GC related memory leak to do with the finalizer that is defined on CGI::Session
1169
- ObjectSpace.undefine_finalizer(@_session)
1170
- response.session = @_session
1171
1235
  end
1172
1236
 
1173
-
1174
1237
  private
1175
1238
  def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
1176
- logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
1239
+ path = template_path.respond_to?(:path_without_format_and_extension) ? template_path.path_without_format_and_extension : template_path
1240
+ logger.info("Rendering #{path}" + (status ? " (#{status})" : '')) if logger
1177
1241
  render_for_text @template.render(:file => template_path, :locals => locals, :layout => layout), status
1178
1242
  end
1179
1243
 
1180
1244
  def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
1181
1245
  @performed_render = true
1182
1246
 
1183
- response.headers['Status'] = interpret_status(status || DEFAULT_RENDER_STATUS_CODE)
1247
+ response.status = interpret_status(status || DEFAULT_RENDER_STATUS_CODE)
1184
1248
 
1185
1249
  if append_response
1186
1250
  response.body ||= ''
@@ -1194,6 +1258,16 @@ module ActionController #:nodoc:
1194
1258
  end
1195
1259
  end
1196
1260
 
1261
+ def validate_render_arguments(options, extra_options, has_block)
1262
+ if options && (has_block && options != :update) && !options.is_a?(String) && !options.is_a?(Hash) && !options.is_a?(Symbol)
1263
+ raise RenderError, "You called render with invalid options : #{options.inspect}"
1264
+ end
1265
+
1266
+ if !extra_options.is_a?(Hash)
1267
+ raise RenderError, "You called render with invalid options : #{options.inspect}, #{extra_options.inspect}"
1268
+ end
1269
+ end
1270
+
1197
1271
  def initialize_template_class(response)
1198
1272
  response.template = ActionView::Base.new(self.class.view_paths, {}, self)
1199
1273
  response.template.helpers.send :include, self.class.master_helper_module
@@ -1202,7 +1276,7 @@ module ActionController #:nodoc:
1202
1276
  end
1203
1277
 
1204
1278
  def assign_shortcuts(request, response)
1205
- @_request, @_params, @_cookies = request, request.parameters, request.cookies
1279
+ @_request, @_params = request, request.parameters
1206
1280
 
1207
1281
  @_response = response
1208
1282
  @_response.session = request.session
@@ -1220,11 +1294,10 @@ module ActionController #:nodoc:
1220
1294
  def log_processing
1221
1295
  if logger && logger.info?
1222
1296
  log_processing_for_request_id
1223
- log_processing_for_session_id
1224
1297
  log_processing_for_parameters
1225
1298
  end
1226
1299
  end
1227
-
1300
+
1228
1301
  def log_processing_for_request_id
1229
1302
  request_id = "\n\nProcessing #{self.class.name}\##{action_name} "
1230
1303
  request_id << "to #{params[:format]} " if params[:format]
@@ -1233,17 +1306,10 @@ module ActionController #:nodoc:
1233
1306
  logger.info(request_id)
1234
1307
  end
1235
1308
 
1236
- def log_processing_for_session_id
1237
- if @_session && @_session.respond_to?(:session_id) && @_session.respond_to?(:dbman) &&
1238
- !@_session.dbman.is_a?(CGI::Session::CookieStore)
1239
- logger.info " Session ID: #{@_session.session_id}"
1240
- end
1241
- end
1242
-
1243
1309
  def log_processing_for_parameters
1244
1310
  parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup
1245
1311
  parameters = parameters.except!(:controller, :action, :format, :_method)
1246
-
1312
+
1247
1313
  logger.info " Parameters: #{parameters.inspect}" unless parameters.empty?
1248
1314
  end
1249
1315
 
@@ -1258,10 +1324,17 @@ module ActionController #:nodoc:
1258
1324
  elsif respond_to? :method_missing
1259
1325
  method_missing action_name
1260
1326
  default_render unless performed?
1261
- elsif template_exists?
1262
- default_render
1263
1327
  else
1264
- raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}", caller
1328
+ begin
1329
+ default_render
1330
+ rescue ActionView::MissingTemplate => e
1331
+ # Was the implicit template missing, or was it another template?
1332
+ if e.path == default_template_name
1333
+ raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence(:locale => :en)}", caller
1334
+ else
1335
+ raise e
1336
+ end
1337
+ end
1265
1338
  end
1266
1339
  end
1267
1340
 
@@ -1273,11 +1346,6 @@ module ActionController #:nodoc:
1273
1346
  @action_name = (params['action'] || 'index')
1274
1347
  end
1275
1348
 
1276
- def assign_default_content_type_and_charset
1277
- response.assign_default_content_type_and_charset!
1278
- end
1279
- deprecate :assign_default_content_type_and_charset => :'response.assign_default_content_type_and_charset!'
1280
-
1281
1349
  def action_methods
1282
1350
  self.class.action_methods
1283
1351
  end
@@ -1308,14 +1376,8 @@ module ActionController #:nodoc:
1308
1376
  "#{request.protocol}#{request.host}#{request.request_uri}"
1309
1377
  end
1310
1378
 
1311
- def close_session
1312
- @_session.close if @_session && @_session.respond_to?(:close)
1313
- end
1314
-
1315
- def template_exists?(template_name = default_template_name)
1316
- @template.send(:_pick_template, template_name) ? true : false
1317
- rescue ActionView::MissingTemplate
1318
- false
1379
+ def default_template(action_name = self.action_name)
1380
+ self.view_paths.find_template(default_template_name(action_name), default_template_format)
1319
1381
  end
1320
1382
 
1321
1383
  def default_template_name(action_name = self.action_name)
@@ -1337,7 +1399,16 @@ module ActionController #:nodoc:
1337
1399
  end
1338
1400
 
1339
1401
  def process_cleanup
1340
- close_session
1341
1402
  end
1342
1403
  end
1404
+
1405
+ Base.class_eval do
1406
+ [ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
1407
+ Cookies, Caching, Verification, Streaming, SessionManagement,
1408
+ HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods,
1409
+ RecordIdentifier, RequestForgeryProtection, Translation
1410
+ ].each do |mod|
1411
+ include mod
1412
+ end
1413
+ end
1343
1414
  end