actionpack 1.13.6 → 2.0.0

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 (317) hide show
  1. data/CHANGELOG +1400 -20
  2. data/MIT-LICENSE +1 -1
  3. data/README +5 -5
  4. data/RUNNING_UNIT_TESTS +4 -5
  5. data/Rakefile +5 -6
  6. data/install.rb +2 -2
  7. data/lib/action_controller.rb +11 -15
  8. data/lib/action_controller/assertions.rb +12 -25
  9. data/lib/action_controller/assertions/dom_assertions.rb +18 -4
  10. data/lib/action_controller/assertions/model_assertions.rb +8 -1
  11. data/lib/action_controller/assertions/response_assertions.rb +35 -12
  12. data/lib/action_controller/assertions/routing_assertions.rb +56 -12
  13. data/lib/action_controller/assertions/selector_assertions.rb +105 -38
  14. data/lib/action_controller/assertions/tag_assertions.rb +28 -15
  15. data/lib/action_controller/base.rb +318 -250
  16. data/lib/action_controller/benchmarking.rb +33 -29
  17. data/lib/action_controller/caching.rb +130 -64
  18. data/lib/action_controller/cgi_ext.rb +16 -0
  19. data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
  20. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  21. data/lib/action_controller/cgi_ext/session.rb +73 -0
  22. data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
  23. data/lib/action_controller/cgi_process.rb +34 -57
  24. data/lib/action_controller/components.rb +19 -36
  25. data/lib/action_controller/cookies.rb +10 -9
  26. data/lib/action_controller/dispatcher.rb +195 -0
  27. data/lib/action_controller/filters.rb +35 -34
  28. data/lib/action_controller/flash.rb +30 -35
  29. data/lib/action_controller/helpers.rb +121 -47
  30. data/lib/action_controller/http_authentication.rb +126 -0
  31. data/lib/action_controller/integration.rb +105 -101
  32. data/lib/action_controller/layout.rb +59 -47
  33. data/lib/action_controller/mime_responds.rb +57 -68
  34. data/lib/action_controller/mime_type.rb +43 -80
  35. data/lib/action_controller/mime_types.rb +20 -0
  36. data/lib/action_controller/polymorphic_routes.rb +88 -0
  37. data/lib/action_controller/record_identifier.rb +91 -0
  38. data/lib/action_controller/request.rb +553 -88
  39. data/lib/action_controller/request_forgery_protection.rb +126 -0
  40. data/lib/action_controller/request_profiler.rb +138 -0
  41. data/lib/action_controller/rescue.rb +185 -69
  42. data/lib/action_controller/resources.rb +211 -172
  43. data/lib/action_controller/response.rb +49 -8
  44. data/lib/action_controller/routing.rb +359 -236
  45. data/lib/action_controller/routing_optimisation.rb +119 -0
  46. data/lib/action_controller/session/active_record_store.rb +3 -2
  47. data/lib/action_controller/session/cookie_store.rb +161 -0
  48. data/lib/action_controller/session/mem_cache_store.rb +9 -16
  49. data/lib/action_controller/session_management.rb +17 -8
  50. data/lib/action_controller/streaming.rb +6 -3
  51. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  52. data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
  53. data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
  54. data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
  55. data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
  56. data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
  57. data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
  58. data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
  59. data/lib/action_controller/test_case.rb +53 -0
  60. data/lib/action_controller/test_process.rb +59 -46
  61. data/lib/action_controller/url_rewriter.rb +48 -24
  62. data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
  63. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  64. data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
  65. data/lib/action_controller/verification.rb +27 -21
  66. data/lib/action_pack.rb +1 -1
  67. data/lib/action_pack/version.rb +4 -4
  68. data/lib/action_view.rb +2 -3
  69. data/lib/action_view/base.rb +218 -63
  70. data/lib/action_view/compiled_templates.rb +1 -2
  71. data/lib/action_view/helpers/active_record_helper.rb +35 -17
  72. data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
  73. data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
  74. data/lib/action_view/helpers/benchmark_helper.rb +12 -5
  75. data/lib/action_view/helpers/cache_helper.rb +29 -0
  76. data/lib/action_view/helpers/capture_helper.rb +97 -63
  77. data/lib/action_view/helpers/date_helper.rb +295 -35
  78. data/lib/action_view/helpers/debug_helper.rb +6 -2
  79. data/lib/action_view/helpers/form_helper.rb +354 -111
  80. data/lib/action_view/helpers/form_options_helper.rb +171 -109
  81. data/lib/action_view/helpers/form_tag_helper.rb +332 -76
  82. data/lib/action_view/helpers/javascript_helper.rb +35 -11
  83. data/lib/action_view/helpers/javascripts/controls.js +484 -354
  84. data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
  85. data/lib/action_view/helpers/javascripts/effects.js +396 -364
  86. data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
  87. data/lib/action_view/helpers/number_helper.rb +84 -60
  88. data/lib/action_view/helpers/prototype_helper.rb +419 -43
  89. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  90. data/lib/action_view/helpers/record_tag_helper.rb +59 -0
  91. data/lib/action_view/helpers/sanitize_helper.rb +223 -0
  92. data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
  93. data/lib/action_view/helpers/tag_helper.rb +69 -39
  94. data/lib/action_view/helpers/text_helper.rb +221 -148
  95. data/lib/action_view/helpers/url_helper.rb +283 -165
  96. data/lib/action_view/partials.rb +134 -62
  97. data/lib/action_view/template_error.rb +4 -12
  98. data/lib/actionpack.rb +1 -0
  99. data/test/abstract_unit.rb +21 -1
  100. data/test/action_view_test.rb +26 -0
  101. data/test/active_record_unit.rb +12 -20
  102. data/test/activerecord/active_record_store_test.rb +2 -2
  103. data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
  104. data/test/controller/action_pack_assertions_test.rb +21 -152
  105. data/test/controller/addresses_render_test.rb +2 -7
  106. data/test/controller/assert_select_test.rb +120 -14
  107. data/test/controller/base_test.rb +11 -13
  108. data/test/controller/caching_test.rb +125 -5
  109. data/test/controller/capture_test.rb +23 -16
  110. data/test/controller/cgi_test.rb +66 -391
  111. data/test/controller/components_test.rb +31 -42
  112. data/test/controller/content_type_test.rb +1 -1
  113. data/test/controller/cookie_test.rb +42 -14
  114. data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
  115. data/test/controller/dispatcher_test.rb +123 -0
  116. data/test/controller/fake_models.rb +5 -0
  117. data/test/controller/filters_test.rb +44 -7
  118. data/test/controller/flash_test.rb +46 -2
  119. data/test/controller/fragment_store_setting_test.rb +10 -8
  120. data/test/controller/helper_test.rb +19 -2
  121. data/test/controller/html-scanner/document_test.rb +124 -0
  122. data/test/controller/html-scanner/node_test.rb +69 -0
  123. data/test/controller/html-scanner/sanitizer_test.rb +250 -0
  124. data/test/controller/html-scanner/tag_node_test.rb +239 -0
  125. data/test/controller/html-scanner/text_node_test.rb +51 -0
  126. data/test/controller/html-scanner/tokenizer_test.rb +125 -0
  127. data/test/controller/http_authentication_test.rb +54 -0
  128. data/test/controller/integration_test.rb +12 -26
  129. data/test/controller/layout_test.rb +64 -12
  130. data/test/controller/mime_responds_test.rb +193 -38
  131. data/test/controller/mime_type_test.rb +30 -8
  132. data/test/controller/new_render_test.rb +104 -22
  133. data/test/controller/polymorphic_routes_test.rb +98 -0
  134. data/test/controller/record_identifier_test.rb +103 -0
  135. data/test/controller/redirect_test.rb +120 -18
  136. data/test/controller/render_test.rb +195 -45
  137. data/test/controller/request_forgery_protection_test.rb +217 -0
  138. data/test/controller/request_test.rb +545 -27
  139. data/test/controller/rescue_test.rb +501 -0
  140. data/test/controller/resources_test.rb +258 -132
  141. data/test/controller/routing_test.rb +502 -106
  142. data/test/controller/selector_test.rb +5 -5
  143. data/test/controller/send_file_test.rb +17 -7
  144. data/test/controller/session/cookie_store_test.rb +246 -0
  145. data/test/controller/session/mem_cache_store_test.rb +182 -0
  146. data/test/controller/session_fixation_test.rb +8 -11
  147. data/test/controller/session_management_test.rb +7 -7
  148. data/test/controller/test_test.rb +150 -38
  149. data/test/controller/url_rewriter_test.rb +87 -12
  150. data/test/controller/verification_test.rb +11 -0
  151. data/test/controller/view_paths_test.rb +137 -0
  152. data/test/controller/webservice_test.rb +11 -75
  153. data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
  154. data/test/fixtures/db_definitions/sqlite.sql +2 -1
  155. data/test/fixtures/developer.rb +2 -0
  156. data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
  157. data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
  158. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  159. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  160. data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
  161. data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
  162. data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
  163. data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
  164. data/test/fixtures/multipart/binary_file +0 -0
  165. data/test/fixtures/multipart/bracketed_param +5 -0
  166. data/test/fixtures/override/test/hello_world.erb +1 -0
  167. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  168. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  169. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  170. data/test/fixtures/post_test/post/index.html.erb +1 -0
  171. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  172. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  173. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  174. data/test/fixtures/public/404.html +1 -0
  175. data/test/fixtures/public/500.html +1 -0
  176. data/test/fixtures/public/javascripts/application.js +0 -1
  177. data/test/fixtures/public/javascripts/bank.js +1 -0
  178. data/test/fixtures/public/javascripts/robber.js +1 -0
  179. data/test/fixtures/public/stylesheets/bank.css +1 -0
  180. data/test/fixtures/public/stylesheets/robber.css +1 -0
  181. data/test/fixtures/replies.yml +2 -0
  182. data/test/fixtures/reply.rb +2 -1
  183. data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
  184. data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
  185. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  186. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  187. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  188. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  189. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  190. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  191. data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
  192. data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
  193. data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
  194. data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
  195. data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
  196. data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
  197. data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
  198. data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
  199. data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
  200. data/test/fixtures/test/_hash_greeting.erb +1 -0
  201. data/test/fixtures/test/_hash_object.erb +2 -0
  202. data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
  203. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  204. data/test/fixtures/test/_partial.erb +1 -0
  205. data/test/fixtures/test/_partial.html.erb +1 -0
  206. data/test/fixtures/test/_partial.js.erb +1 -0
  207. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  208. data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
  209. data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
  210. data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
  211. data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
  212. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  213. data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
  214. data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
  215. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  216. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  217. data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  218. data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
  219. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  220. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  221. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  222. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  223. data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
  224. data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
  225. data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
  226. data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
  227. data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
  228. data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
  229. data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
  230. data/test/fixtures/test/list.erb +1 -0
  231. data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
  232. data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
  233. data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  234. data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
  235. data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
  236. data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
  237. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  238. data/test/fixtures/topic.rb +1 -1
  239. data/test/template/active_record_helper_test.rb +67 -20
  240. data/test/template/asset_tag_helper_test.rb +222 -54
  241. data/test/template/atom_feed_helper_test.rb +101 -0
  242. data/test/template/benchmark_helper_test.rb +2 -2
  243. data/test/template/compiled_templates_test.rb +76 -32
  244. data/test/template/date_helper_test.rb +125 -9
  245. data/test/template/form_helper_test.rb +326 -33
  246. data/test/template/form_options_helper_test.rb +822 -15
  247. data/test/template/form_tag_helper_test.rb +96 -30
  248. data/test/template/javascript_helper_test.rb +61 -13
  249. data/test/template/number_helper_test.rb +12 -11
  250. data/test/template/prototype_helper_test.rb +185 -24
  251. data/test/template/sanitize_helper_test.rb +49 -0
  252. data/test/template/scriptaculous_helper_test.rb +9 -3
  253. data/test/template/tag_helper_test.rb +13 -2
  254. data/test/template/text_helper_test.rb +38 -52
  255. data/test/template/url_helper_test.rb +216 -46
  256. metadata +144 -116
  257. data/examples/.htaccess +0 -24
  258. data/examples/address_book/index.rhtml +0 -33
  259. data/examples/address_book/layout.rhtml +0 -8
  260. data/examples/address_book_controller.cgi +0 -9
  261. data/examples/address_book_controller.fcgi +0 -6
  262. data/examples/address_book_controller.rb +0 -52
  263. data/examples/address_book_controller.rbx +0 -4
  264. data/examples/benchmark.rb +0 -52
  265. data/examples/benchmark_with_ar.fcgi +0 -89
  266. data/examples/blog_controller.cgi +0 -53
  267. data/examples/debate/index.rhtml +0 -14
  268. data/examples/debate/new_topic.rhtml +0 -22
  269. data/examples/debate/topic.rhtml +0 -32
  270. data/examples/debate_controller.cgi +0 -57
  271. data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
  272. data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
  273. data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
  274. data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
  275. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
  276. data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
  277. data/lib/action_controller/deprecated_dependencies.rb +0 -65
  278. data/lib/action_controller/deprecated_redirects.rb +0 -17
  279. data/lib/action_controller/deprecated_request_methods.rb +0 -34
  280. data/lib/action_controller/macros/auto_complete.rb +0 -53
  281. data/lib/action_controller/macros/in_place_editing.rb +0 -33
  282. data/lib/action_controller/pagination.rb +0 -408
  283. data/lib/action_controller/scaffolding.rb +0 -189
  284. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
  285. data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
  286. data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
  287. data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
  288. data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
  289. data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
  290. data/lib/action_controller/vendor/xml_node.rb +0 -97
  291. data/lib/action_view/helpers/deprecated_helper.rb +0 -37
  292. data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
  293. data/lib/action_view/helpers/pagination_helper.rb +0 -86
  294. data/test/activerecord/active_record_assertions_test.rb +0 -92
  295. data/test/activerecord/pagination_test.rb +0 -165
  296. data/test/controller/deprecated_instance_variables_test.rb +0 -48
  297. data/test/controller/raw_post_test.rb +0 -68
  298. data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
  299. data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
  300. data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
  301. data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
  302. data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
  303. data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
  304. data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
  305. data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
  306. data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
  307. data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
  308. data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
  309. data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
  310. data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
  311. data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
  312. data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
  313. data/test/fixtures/test/_hash_object.rhtml +0 -1
  314. data/test/fixtures/test/list.rhtml +0 -1
  315. data/test/template/deprecated_helper_test.rb +0 -36
  316. data/test/template/deprecated_instance_variables_test.rb +0 -43
  317. data/test/template/java_script_macros_helper_test.rb +0 -109
@@ -0,0 +1,16 @@
1
+ require 'action_controller/cgi_ext/stdinput'
2
+ require 'action_controller/cgi_ext/query_extension'
3
+ require 'action_controller/cgi_ext/cookie'
4
+ require 'action_controller/cgi_ext/session'
5
+
6
+ class CGI #:nodoc:
7
+ include ActionController::CgiExt::Stdinput
8
+
9
+ class << self
10
+ alias :escapeHTML_fail_on_nil :escapeHTML
11
+
12
+ def escapeHTML(string)
13
+ escapeHTML_fail_on_nil(string) unless string.nil?
14
+ end
15
+ end
16
+ end
@@ -1,10 +1,11 @@
1
1
  CGI.module_eval { remove_const "Cookie" }
2
2
 
3
+ # TODO: document how this differs from stdlib CGI::Cookie
3
4
  class CGI #:nodoc:
4
- # This is a cookie class that fixes the performance problems with the default one that ships with 1.8.1 and below.
5
- # It replaces the inheritance on SimpleDelegator with DelegateClass(Array) following the suggestion from Matz on
6
- # http://groups.google.com/groups?th=e3a4e68ba042f842&seekm=c3sioe%241qvm%241%40news.cybercity.dk#link14
7
5
  class Cookie < DelegateClass(Array)
6
+ attr_accessor :name, :value, :path, :domain, :expires
7
+ attr_reader :secure, :http_only
8
+
8
9
  # Create a new CGI::Cookie object.
9
10
  #
10
11
  # The contents of the cookie can be specified as a +name+ and one
@@ -19,9 +20,11 @@ class CGI #:nodoc:
19
20
  # domain:: the domain for which this cookie applies.
20
21
  # expires:: the time at which this cookie expires, as a +Time+ object.
21
22
  # secure:: whether this cookie is a secure cookie or not (default to
22
- # false). Secure cookies are only transmitted to HTTPS
23
+ # false). Secure cookies are only transmitted to HTTPS
23
24
  # servers.
24
- #
25
+ # http_only:: whether this cookie can be accessed by client side scripts (e.g. document.cookie) or only over HTTP
26
+ # More details: http://msdn2.microsoft.com/en-us/library/system.web.httpcookie.httponly.aspx
27
+ # Defaults to false.
25
28
  # These keywords correspond to attributes of the cookie object.
26
29
  def initialize(name = '', *value)
27
30
  if name.kind_of?(String)
@@ -30,6 +33,7 @@ class CGI #:nodoc:
30
33
  @domain = nil
31
34
  @expires = nil
32
35
  @secure = false
36
+ @http_only = false
33
37
  @path = nil
34
38
  else
35
39
  @name = name['name']
@@ -37,12 +41,11 @@ class CGI #:nodoc:
37
41
  @domain = name['domain']
38
42
  @expires = name['expires']
39
43
  @secure = name['secure'] || false
44
+ @http_only = name['http_only'] || false
40
45
  @path = name['path']
41
46
  end
42
-
43
- unless @name
44
- raise ArgumentError, "`name' required"
45
- end
47
+
48
+ raise ArgumentError, "`name' required" unless @name
46
49
 
47
50
  # simple support for IE
48
51
  unless @path
@@ -57,44 +60,26 @@ class CGI #:nodoc:
57
60
  @_dc_obj = obj
58
61
  end
59
62
 
60
- attr_accessor("name", "value", "path", "domain", "expires")
61
- attr_reader("secure")
62
-
63
63
  # Set whether the Cookie is a secure cookie or not.
64
- #
65
- # +val+ must be a boolean.
66
64
  def secure=(val)
67
- @secure = val if val == true or val == false
68
- @secure
65
+ @secure = val == true
66
+ end
67
+
68
+ # Set whether the Cookie is an HTTP only cookie or not.
69
+ def http_only=(val)
70
+ @http_only = val == true
69
71
  end
70
72
 
71
73
  # Convert the Cookie to its string representation.
72
74
  def to_s
73
- buf = ""
75
+ buf = ''
74
76
  buf << @name << '='
75
-
76
- if @value.kind_of?(String)
77
- buf << CGI::escape(@value)
78
- else
79
- buf << @value.collect{|v| CGI::escape(v) }.join("&")
80
- end
81
-
82
- if @domain
83
- buf << '; domain=' << @domain
84
- end
85
-
86
- if @path
87
- buf << '; path=' << @path
88
- end
89
-
90
- if @expires
91
- buf << '; expires=' << CGI::rfc1123_date(@expires)
92
- end
93
-
94
- if @secure == true
95
- buf << '; secure'
96
- end
97
-
77
+ buf << (@value.kind_of?(String) ? CGI::escape(@value) : @value.collect{|v| CGI::escape(v) }.join("&"))
78
+ buf << '; domain=' << @domain if @domain
79
+ buf << '; path=' << @path if @path
80
+ buf << '; expires=' << CGI::rfc1123_date(@expires) if @expires
81
+ buf << '; secure' if @secure
82
+ buf << '; HttpOnly' if @http_only
98
83
  buf
99
84
  end
100
85
 
@@ -0,0 +1,22 @@
1
+ require 'cgi'
2
+
3
+ class CGI #:nodoc:
4
+ module QueryExtension
5
+ # Remove the old initialize_query method before redefining it.
6
+ remove_method :initialize_query
7
+
8
+ # Neuter CGI parameter parsing.
9
+ def initialize_query
10
+ # Fix some strange request environments.
11
+ env_table['REQUEST_METHOD'] ||= 'GET'
12
+
13
+ # POST assumes missing Content-Type is application/x-www-form-urlencoded.
14
+ if env_table['CONTENT_TYPE'].blank? && env_table['REQUEST_METHOD'] == 'POST'
15
+ env_table['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
16
+ end
17
+
18
+ @cookies = CGI::Cookie::parse(env_table['HTTP_COOKIE'] || env_table['COOKIE'])
19
+ @params = {}
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,73 @@
1
+ require 'digest/md5'
2
+ require 'cgi/session'
3
+ require 'cgi/session/pstore'
4
+
5
+ class CGI #:nodoc:
6
+ # * Expose the CGI instance to session stores.
7
+ # * Don't require 'digest/md5' whenever a new session id is generated.
8
+ class Session #:nodoc:
9
+ begin
10
+ require 'securerandom'
11
+
12
+ # Generate a 32-character unique id using SecureRandom.
13
+ # This is used to generate session ids but may be reused elsewhere.
14
+ def self.generate_unique_id(constant = nil)
15
+ SecureRandom.hex(16)
16
+ end
17
+ rescue LoadError
18
+ # Generate an 32-character unique id based on a hash of the current time,
19
+ # a random number, the process id, and a constant string. This is used
20
+ # to generate session ids but may be reused elsewhere.
21
+ def self.generate_unique_id(constant = 'foobar')
22
+ md5 = Digest::MD5.new
23
+ now = Time.now
24
+ md5 << now.to_s
25
+ md5 << String(now.usec)
26
+ md5 << String(rand(0))
27
+ md5 << String($$)
28
+ md5 << constant
29
+ md5.hexdigest
30
+ end
31
+ end
32
+
33
+ # Make the CGI instance available to session stores.
34
+ attr_reader :cgi
35
+ attr_reader :dbman
36
+ alias_method :initialize_without_cgi_reader, :initialize
37
+ def initialize(cgi, options = {})
38
+ @cgi = cgi
39
+ initialize_without_cgi_reader(cgi, options)
40
+ end
41
+
42
+ private
43
+ # Create a new session id.
44
+ def create_new_id
45
+ @new_session = true
46
+ self.class.generate_unique_id
47
+ end
48
+
49
+ # * Don't require 'digest/md5' whenever a new session is started.
50
+ class PStore #:nodoc:
51
+ def initialize(session, option={})
52
+ dir = option['tmpdir'] || Dir::tmpdir
53
+ prefix = option['prefix'] || ''
54
+ id = session.session_id
55
+ md5 = Digest::MD5.hexdigest(id)[0,16]
56
+ path = dir+"/"+prefix+md5
57
+ path.untaint
58
+ if File::exist?(path)
59
+ @hash = nil
60
+ else
61
+ unless session.new_session
62
+ raise CGI::Session::NoSession, "uninitialized session"
63
+ end
64
+ @hash = {}
65
+ end
66
+ @p = ::PStore.new(path)
67
+ @p.transaction do |p|
68
+ File.chmod(0600, p.path)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,23 @@
1
+ require 'cgi'
2
+
3
+ module ActionController
4
+ module CgiExt
5
+ # Publicize the CGI's internal input stream so we can lazy-read
6
+ # request.body. Make it writable so we don't have to play $stdin games.
7
+ module Stdinput
8
+ def self.included(base)
9
+ base.class_eval do
10
+ remove_method :stdinput
11
+ attr_accessor :stdinput
12
+ end
13
+
14
+ base.alias_method_chain :initialize, :stdinput
15
+ end
16
+
17
+ def initialize_with_stdinput(type = nil, stdinput = $stdin)
18
+ @stdinput = stdinput
19
+ initialize_without_stdinput(type || 'query')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,8 +1,5 @@
1
- require 'action_controller/cgi_ext/cgi_ext'
2
- require 'action_controller/cgi_ext/cookie_performance_fix'
3
- require 'action_controller/cgi_ext/raw_post_data_fix'
4
- require 'action_controller/cgi_ext/session_performance_fix'
5
- require 'action_controller/cgi_ext/pstore_performance_fix'
1
+ require 'action_controller/cgi_ext'
2
+ require 'action_controller/session/cookie_store'
6
3
 
7
4
  module ActionController #:nodoc:
8
5
  class Base
@@ -40,9 +37,9 @@ module ActionController #:nodoc:
40
37
  class SessionFixationAttempt < StandardError; end #:nodoc:
41
38
 
42
39
  DEFAULT_SESSION_OPTIONS = {
43
- :database_manager => CGI::Session::PStore,
44
- :prefix => "ruby_sess.",
45
- :session_path => "/",
40
+ :database_manager => CGI::Session::CookieStore, # store data in cookie
41
+ :prefix => "ruby_sess.", # prefix session file names
42
+ :session_path => "/", # available to all paths in app
46
43
  :session_key => "_session_id",
47
44
  :cookie_only => true
48
45
  } unless const_defined?(:DEFAULT_SESSION_OPTIONS)
@@ -50,45 +47,42 @@ module ActionController #:nodoc:
50
47
  def initialize(cgi, session_options = {})
51
48
  @cgi = cgi
52
49
  @session_options = session_options
53
- @env = @cgi.send(:env_table)
50
+ @env = @cgi.send!(:env_table)
54
51
  super()
55
52
  end
56
53
 
57
- def cookie_only?
58
- session_options_with_string_keys['cookie_only']
59
- end
60
-
61
54
  def query_string
62
- if (qs = @cgi.query_string) && !qs.empty?
55
+ qs = @cgi.query_string if @cgi.respond_to?(:query_string)
56
+ if !qs.blank?
63
57
  qs
64
- elsif uri = @env['REQUEST_URI']
65
- parts = uri.split('?')
66
- parts.shift
67
- parts.join('?')
68
58
  else
69
- @env['QUERY_STRING'] || ''
59
+ super
60
+ end
61
+ end
62
+
63
+ # The request body is an IO input stream. If the RAW_POST_DATA environment
64
+ # variable is already set, wrap it in a StringIO.
65
+ def body
66
+ if raw_post = env['RAW_POST_DATA']
67
+ StringIO.new(raw_post)
68
+ else
69
+ @cgi.stdinput
70
70
  end
71
71
  end
72
72
 
73
73
  def query_parameters
74
- @query_parameters ||=
75
- (qs = self.query_string).empty? ? {} : CGIMethods.parse_query_parameters(qs)
74
+ @query_parameters ||= self.class.parse_query_parameters(query_string)
76
75
  end
77
76
 
78
77
  def request_parameters
79
- @request_parameters ||=
80
- if ActionController::Base.param_parsers.has_key?(content_type)
81
- CGIMethods.parse_formatted_request_parameters(content_type, @env['RAW_POST_DATA'])
82
- else
83
- CGIMethods.parse_request_parameters(@cgi.params)
84
- end
78
+ @request_parameters ||= parse_formatted_request_parameters
85
79
  end
86
80
 
87
81
  def cookies
88
82
  @cgi.cookies.freeze
89
83
  end
90
84
 
91
- def host_with_port
85
+ def host_with_port_without_standard_port_handling
92
86
  if forwarded = env["HTTP_X_FORWARDED_HOST"]
93
87
  forwarded.split(/,\s?/).last
94
88
  elsif http_host = env['HTTP_HOST']
@@ -101,11 +95,11 @@ module ActionController #:nodoc:
101
95
  end
102
96
 
103
97
  def host
104
- host_with_port[/^[^:]+/]
98
+ host_with_port_without_standard_port_handling.sub(/:\d+$/, '')
105
99
  end
106
100
 
107
101
  def port
108
- if host_with_port =~ /:(\d+)$/
102
+ if host_with_port_without_standard_port_handling =~ /:(\d+)$/
109
103
  $1.to_i
110
104
  else
111
105
  standard_port
@@ -118,7 +112,7 @@ module ActionController #:nodoc:
118
112
  @session = Hash.new
119
113
  else
120
114
  stale_session_check! do
121
- if cookie_only? && request_parameters[session_options_with_string_keys['session_key']]
115
+ if cookie_only? && query_parameters[session_options_with_string_keys['session_key']]
122
116
  raise SessionFixationAttempt
123
117
  end
124
118
  case value = session_options_with_string_keys['new_session']
@@ -150,7 +144,7 @@ module ActionController #:nodoc:
150
144
  end
151
145
 
152
146
  def method_missing(method_id, *arguments)
153
- @cgi.send(method_id, *arguments) rescue super
147
+ @cgi.send!(method_id, *arguments) rescue super
154
148
  end
155
149
 
156
150
  private
@@ -164,12 +158,17 @@ module ActionController #:nodoc:
164
158
  end
165
159
  end
166
160
 
161
+ def cookie_only?
162
+ session_options_with_string_keys['cookie_only']
163
+ end
164
+
167
165
  def stale_session_check!
168
166
  yield
169
167
  rescue ArgumentError => argument_error
170
- if argument_error.message =~ %r{undefined class/module ([\w:]+)}
168
+ if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
171
169
  begin
172
- Module.const_missing($1)
170
+ # Note that the regexp does not allow $1 to end with a ':'
171
+ $1.constantize
173
172
  rescue LoadError, NameError => const_error
174
173
  raise ActionController::SessionRestoreError, <<-end_msg
175
174
  Session contains objects whose class definition isn\'t available.
@@ -196,16 +195,13 @@ end_msg
196
195
  end
197
196
 
198
197
  def out(output = $stdout)
199
- convert_content_type!
200
- set_content_length!
201
-
202
198
  output.binmode if output.respond_to?(:binmode)
203
199
  output.sync = false if output.respond_to?(:sync=)
204
200
 
205
201
  begin
206
202
  output.write(@cgi.header(@headers))
207
203
 
208
- if @cgi.send(:env_table)['REQUEST_METHOD'] == 'HEAD'
204
+ if @cgi.send!(:env_table)['REQUEST_METHOD'] == 'HEAD'
209
205
  return
210
206
  elsif @body.respond_to?(:call)
211
207
  # Flush the output now in case the @body Proc uses
@@ -221,24 +217,5 @@ end_msg
221
217
  # lost connection to parent process, ignore output
222
218
  end
223
219
  end
224
-
225
- private
226
- def convert_content_type!
227
- if content_type = @headers.delete("Content-Type")
228
- @headers["type"] = content_type
229
- end
230
- if content_type = @headers.delete("Content-type")
231
- @headers["type"] = content_type
232
- end
233
- if content_type = @headers.delete("content-type")
234
- @headers["type"] = content_type
235
- end
236
- end
237
-
238
- # Don't set the Content-Length for block-based bodies as that would mean reading it all into memory. Not nice
239
- # for, say, a 2GB streaming file.
240
- def set_content_length!
241
- @headers["Content-Length"] = @body.size unless @body.respond_to?(:call)
242
- end
243
220
  end
244
221
  end
@@ -17,44 +17,44 @@ module ActionController #:nodoc:
17
17
  # end
18
18
  #
19
19
  # The same can be done in a view to do a partial rendering:
20
- #
21
- # Let's see a greeting:
20
+ #
21
+ # Let's see a greeting:
22
22
  # <%= render_component :controller => "greeter", :action => "hello_world" %>
23
23
  #
24
24
  # It is also possible to specify the controller as a class constant, bypassing the inflector
25
25
  # code to compute the controller class at runtime:
26
- #
26
+ #
27
27
  # <%= render_component :controller => GreeterController, :action => "hello_world" %>
28
28
  #
29
29
  # == When to use components
30
30
  #
31
31
  # Components should be used with care. They're significantly slower than simply splitting reusable parts into partials and
32
32
  # conceptually more complicated. Don't use components as a way of separating concerns inside a single application. Instead,
33
- # reserve components to those rare cases where you truly have reusable view and controller elements that can be employed
33
+ # reserve components to those rare cases where you truly have reusable view and controller elements that can be employed
34
34
  # across many applications at once.
35
35
  #
36
36
  # So to repeat: Components are a special-purpose approach that can often be replaced with better use of partials and filters.
37
37
  module Components
38
38
  def self.included(base) #:nodoc:
39
- base.send :include, InstanceMethods
40
- base.extend(ClassMethods)
39
+ base.class_eval do
40
+ include InstanceMethods
41
+ extend ClassMethods
41
42
 
42
- base.helper do
43
- def render_component(options)
44
- @controller.send(:render_component_as_string, options)
43
+ helper do
44
+ def render_component(options)
45
+ @controller.send!(:render_component_as_string, options)
46
+ end
45
47
  end
46
- end
47
-
48
- # If this controller was instantiated to process a component request,
49
- # +parent_controller+ points to the instantiator of this controller.
50
- base.send :attr_accessor, :parent_controller
51
-
52
- base.class_eval do
48
+
49
+ # If this controller was instantiated to process a component request,
50
+ # +parent_controller+ points to the instantiator of this controller.
51
+ attr_accessor :parent_controller
52
+
53
53
  alias_method_chain :process_cleanup, :components
54
54
  alias_method_chain :set_session_options, :components
55
55
  alias_method_chain :flash, :components
56
56
 
57
- alias_method :component_request?, :parent_controller
57
+ alias_method :component_request?, :parent_controller
58
58
  end
59
59
  end
60
60
 
@@ -65,23 +65,6 @@ module ActionController #:nodoc:
65
65
  controller.parent_controller = parent_controller
66
66
  controller.process(request, response)
67
67
  end
68
-
69
- # Set the template root to be one directory behind the root dir of the controller. Examples:
70
- # /code/weblog/components/admin/users_controller.rb with Admin::UsersController
71
- # will use /code/weblog/components as template root
72
- # and find templates in /code/weblog/components/admin/users/
73
- #
74
- # /code/weblog/components/admin/parties/users_controller.rb with Admin::Parties::UsersController
75
- # will also use /code/weblog/components as template root
76
- # and find templates in /code/weblog/components/admin/parties/users/
77
- def uses_component_template_root
78
- path_of_calling_controller = File.dirname(caller[1].split(/:\d+:/, 2).first)
79
- path_of_controller_root = path_of_calling_controller.sub(/#{Regexp.escape(File.dirname(controller_path))}$/, "")
80
-
81
- self.template_root = path_of_controller_root
82
- end
83
-
84
- deprecate :uses_component_template_root => 'Components are deprecated and will be removed in Rails 2.0.'
85
68
  end
86
69
 
87
70
  module InstanceMethods
@@ -90,12 +73,12 @@ module ActionController #:nodoc:
90
73
  flash.discard if component_request?
91
74
  process_without_components(request, response, method, *arguments)
92
75
  end
93
-
76
+
94
77
  protected
95
78
  # Renders the component specified as the response for the current method
96
79
  def render_component(options) #:doc:
97
80
  component_logging(options) do
98
- render_text(component_response(options, true).body, response.headers["Status"])
81
+ render_for_text(component_response(options, true).body, response.headers["Status"])
99
82
  end
100
83
  end
101
84