actionpack_csi 2.3.5.p6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. data/CHANGELOG +5184 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +409 -0
  4. data/RUNNING_UNIT_TESTS +24 -0
  5. data/Rakefile +160 -0
  6. data/install.rb +30 -0
  7. data/lib/action_controller/assertions/dom_assertions.rb +55 -0
  8. data/lib/action_controller/assertions/model_assertions.rb +21 -0
  9. data/lib/action_controller/assertions/response_assertions.rb +160 -0
  10. data/lib/action_controller/assertions/routing_assertions.rb +146 -0
  11. data/lib/action_controller/assertions/selector_assertions.rb +638 -0
  12. data/lib/action_controller/assertions/tag_assertions.rb +127 -0
  13. data/lib/action_controller/base.rb +1423 -0
  14. data/lib/action_controller/benchmarking.rb +107 -0
  15. data/lib/action_controller/caching/actions.rb +177 -0
  16. data/lib/action_controller/caching/fragments.rb +120 -0
  17. data/lib/action_controller/caching/pages.rb +152 -0
  18. data/lib/action_controller/caching/sweeper.rb +45 -0
  19. data/lib/action_controller/caching/sweeping.rb +55 -0
  20. data/lib/action_controller/caching.rb +71 -0
  21. data/lib/action_controller/cgi_ext/cookie.rb +112 -0
  22. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  23. data/lib/action_controller/cgi_ext/stdinput.rb +24 -0
  24. data/lib/action_controller/cgi_ext.rb +15 -0
  25. data/lib/action_controller/cgi_process.rb +77 -0
  26. data/lib/action_controller/cookies.rb +95 -0
  27. data/lib/action_controller/dispatcher.rb +133 -0
  28. data/lib/action_controller/failsafe.rb +86 -0
  29. data/lib/action_controller/filters.rb +680 -0
  30. data/lib/action_controller/flash.rb +171 -0
  31. data/lib/action_controller/headers.rb +33 -0
  32. data/lib/action_controller/helpers.rb +225 -0
  33. data/lib/action_controller/http_authentication.rb +309 -0
  34. data/lib/action_controller/integration.rb +692 -0
  35. data/lib/action_controller/layout.rb +286 -0
  36. data/lib/action_controller/middleware_stack.rb +119 -0
  37. data/lib/action_controller/middlewares.rb +14 -0
  38. data/lib/action_controller/mime_responds.rb +193 -0
  39. data/lib/action_controller/mime_type.rb +212 -0
  40. data/lib/action_controller/mime_types.rb +21 -0
  41. data/lib/action_controller/params_parser.rb +77 -0
  42. data/lib/action_controller/performance_test.rb +15 -0
  43. data/lib/action_controller/polymorphic_routes.rb +189 -0
  44. data/lib/action_controller/rack_lint_patch.rb +36 -0
  45. data/lib/action_controller/record_identifier.rb +104 -0
  46. data/lib/action_controller/reloader.rb +54 -0
  47. data/lib/action_controller/request.rb +493 -0
  48. data/lib/action_controller/request_forgery_protection.rb +113 -0
  49. data/lib/action_controller/rescue.rb +183 -0
  50. data/lib/action_controller/resources.rb +682 -0
  51. data/lib/action_controller/response.rb +239 -0
  52. data/lib/action_controller/routing/builder.rb +197 -0
  53. data/lib/action_controller/routing/optimisations.rb +130 -0
  54. data/lib/action_controller/routing/recognition_optimisation.rb +167 -0
  55. data/lib/action_controller/routing/route.rb +265 -0
  56. data/lib/action_controller/routing/route_set.rb +502 -0
  57. data/lib/action_controller/routing/routing_ext.rb +49 -0
  58. data/lib/action_controller/routing/segments.rb +343 -0
  59. data/lib/action_controller/routing.rb +388 -0
  60. data/lib/action_controller/session/abstract_store.rb +181 -0
  61. data/lib/action_controller/session/cookie_store.rb +221 -0
  62. data/lib/action_controller/session/mem_cache_store.rb +51 -0
  63. data/lib/action_controller/session_management.rb +54 -0
  64. data/lib/action_controller/status_codes.rb +88 -0
  65. data/lib/action_controller/streaming.rb +181 -0
  66. data/lib/action_controller/string_coercion.rb +29 -0
  67. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  68. data/lib/action_controller/templates/rescues/_trace.erb +26 -0
  69. data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
  70. data/lib/action_controller/templates/rescues/layout.erb +29 -0
  71. data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
  72. data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
  73. data/lib/action_controller/templates/rescues/template_error.erb +21 -0
  74. data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
  75. data/lib/action_controller/test_case.rb +209 -0
  76. data/lib/action_controller/test_process.rb +580 -0
  77. data/lib/action_controller/translation.rb +13 -0
  78. data/lib/action_controller/uploaded_file.rb +44 -0
  79. data/lib/action_controller/url_rewriter.rb +216 -0
  80. data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
  81. data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
  82. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  83. data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
  84. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
  85. data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
  86. data/lib/action_controller/vendor/html-scanner.rb +16 -0
  87. data/lib/action_controller/verification.rb +130 -0
  88. data/lib/action_controller.rb +113 -0
  89. data/lib/action_pack/version.rb +9 -0
  90. data/lib/action_pack.rb +24 -0
  91. data/lib/action_view/base.rb +362 -0
  92. data/lib/action_view/erb/util.rb +44 -0
  93. data/lib/action_view/helpers/active_record_helper.rb +305 -0
  94. data/lib/action_view/helpers/asset_tag_helper.rb +694 -0
  95. data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
  96. data/lib/action_view/helpers/benchmark_helper.rb +54 -0
  97. data/lib/action_view/helpers/cache_helper.rb +39 -0
  98. data/lib/action_view/helpers/capture_helper.rb +136 -0
  99. data/lib/action_view/helpers/date_helper.rb +988 -0
  100. data/lib/action_view/helpers/debug_helper.rb +38 -0
  101. data/lib/action_view/helpers/form_helper.rb +1074 -0
  102. data/lib/action_view/helpers/form_options_helper.rb +600 -0
  103. data/lib/action_view/helpers/form_tag_helper.rb +487 -0
  104. data/lib/action_view/helpers/javascript_helper.rb +208 -0
  105. data/lib/action_view/helpers/number_helper.rb +308 -0
  106. data/lib/action_view/helpers/prototype_helper.rb +1305 -0
  107. data/lib/action_view/helpers/raw_output_helper.rb +9 -0
  108. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  109. data/lib/action_view/helpers/record_tag_helper.rb +58 -0
  110. data/lib/action_view/helpers/sanitize_helper.rb +259 -0
  111. data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
  112. data/lib/action_view/helpers/tag_helper.rb +150 -0
  113. data/lib/action_view/helpers/text_helper.rb +587 -0
  114. data/lib/action_view/helpers/translation_helper.rb +39 -0
  115. data/lib/action_view/helpers/url_helper.rb +639 -0
  116. data/lib/action_view/helpers.rb +59 -0
  117. data/lib/action_view/inline_template.rb +19 -0
  118. data/lib/action_view/locale/en.yml +117 -0
  119. data/lib/action_view/partials.rb +240 -0
  120. data/lib/action_view/paths.rb +69 -0
  121. data/lib/action_view/reloadable_template.rb +117 -0
  122. data/lib/action_view/renderable.rb +95 -0
  123. data/lib/action_view/renderable_partial.rb +47 -0
  124. data/lib/action_view/safe_buffer.rb +28 -0
  125. data/lib/action_view/template.rb +252 -0
  126. data/lib/action_view/template_error.rb +99 -0
  127. data/lib/action_view/template_handler.rb +34 -0
  128. data/lib/action_view/template_handlers/builder.rb +17 -0
  129. data/lib/action_view/template_handlers/erb.rb +22 -0
  130. data/lib/action_view/template_handlers/rjs.rb +13 -0
  131. data/lib/action_view/template_handlers.rb +48 -0
  132. data/lib/action_view/test_case.rb +162 -0
  133. data/lib/action_view.rb +58 -0
  134. data/lib/actionpack.rb +2 -0
  135. data/test/abstract_unit.rb +61 -0
  136. data/test/active_record_unit.rb +104 -0
  137. data/test/activerecord/active_record_store_test.rb +174 -0
  138. data/test/activerecord/render_partial_with_record_identification_test.rb +188 -0
  139. data/test/adv_attr_test.rb +20 -0
  140. data/test/controller/action_pack_assertions_test.rb +543 -0
  141. data/test/controller/addresses_render_test.rb +37 -0
  142. data/test/controller/assert_select_test.rb +734 -0
  143. data/test/controller/base_test.rb +217 -0
  144. data/test/controller/benchmark_test.rb +32 -0
  145. data/test/controller/caching_test.rb +729 -0
  146. data/test/controller/capture_test.rb +66 -0
  147. data/test/controller/content_type_test.rb +168 -0
  148. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  149. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  150. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  151. data/test/controller/cookie_test.rb +134 -0
  152. data/test/controller/deprecation/deprecated_base_methods_test.rb +32 -0
  153. data/test/controller/dispatcher_test.rb +144 -0
  154. data/test/controller/dom_assertions_test.rb +53 -0
  155. data/test/controller/failsafe_test.rb +60 -0
  156. data/test/controller/fake_controllers.rb +33 -0
  157. data/test/controller/fake_models.rb +19 -0
  158. data/test/controller/filter_params_test.rb +52 -0
  159. data/test/controller/filters_test.rb +885 -0
  160. data/test/controller/flash_test.rb +147 -0
  161. data/test/controller/header_test.rb +14 -0
  162. data/test/controller/helper_test.rb +224 -0
  163. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  164. data/test/controller/html-scanner/document_test.rb +148 -0
  165. data/test/controller/html-scanner/node_test.rb +89 -0
  166. data/test/controller/html-scanner/sanitizer_test.rb +274 -0
  167. data/test/controller/html-scanner/tag_node_test.rb +238 -0
  168. data/test/controller/html-scanner/text_node_test.rb +50 -0
  169. data/test/controller/html-scanner/tokenizer_test.rb +131 -0
  170. data/test/controller/http_basic_authentication_test.rb +113 -0
  171. data/test/controller/http_digest_authentication_test.rb +254 -0
  172. data/test/controller/integration_test.rb +483 -0
  173. data/test/controller/layout_test.rb +215 -0
  174. data/test/controller/logging_test.rb +46 -0
  175. data/test/controller/middleware_stack_test.rb +90 -0
  176. data/test/controller/mime_responds_test.rb +536 -0
  177. data/test/controller/mime_type_test.rb +93 -0
  178. data/test/controller/polymorphic_routes_test.rb +297 -0
  179. data/test/controller/rack_test.rb +311 -0
  180. data/test/controller/record_identifier_test.rb +139 -0
  181. data/test/controller/redirect_test.rb +285 -0
  182. data/test/controller/reloader_test.rb +124 -0
  183. data/test/controller/render_test.rb +1762 -0
  184. data/test/controller/request/json_params_parsing_test.rb +65 -0
  185. data/test/controller/request/multipart_params_parsing_test.rb +162 -0
  186. data/test/controller/request/query_string_parsing_test.rb +120 -0
  187. data/test/controller/request/test_request_test.rb +35 -0
  188. data/test/controller/request/url_encoded_params_parsing_test.rb +146 -0
  189. data/test/controller/request/xml_params_parsing_test.rb +103 -0
  190. data/test/controller/request_forgery_protection_test.rb +265 -0
  191. data/test/controller/request_test.rb +395 -0
  192. data/test/controller/rescue_test.rb +536 -0
  193. data/test/controller/resources_test.rb +1393 -0
  194. data/test/controller/routing_test.rb +2591 -0
  195. data/test/controller/selector_test.rb +628 -0
  196. data/test/controller/send_file_test.rb +171 -0
  197. data/test/controller/session/cookie_store_test.rb +216 -0
  198. data/test/controller/session/mem_cache_store_test.rb +127 -0
  199. data/test/controller/session/test_session_test.rb +58 -0
  200. data/test/controller/test_test.rb +700 -0
  201. data/test/controller/translation_test.rb +26 -0
  202. data/test/controller/url_rewriter_test.rb +385 -0
  203. data/test/controller/verification_test.rb +270 -0
  204. data/test/controller/view_paths_test.rb +141 -0
  205. data/test/controller/webservice_test.rb +273 -0
  206. data/test/fixtures/_top_level_partial.html.erb +1 -0
  207. data/test/fixtures/_top_level_partial_only.erb +1 -0
  208. data/test/fixtures/addresses/list.erb +1 -0
  209. data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
  210. data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
  211. data/test/fixtures/companies.yml +24 -0
  212. data/test/fixtures/company.rb +10 -0
  213. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
  214. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
  215. data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
  216. data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
  217. data/test/fixtures/customers/_customer.html.erb +1 -0
  218. data/test/fixtures/db_definitions/sqlite.sql +49 -0
  219. data/test/fixtures/developer.rb +9 -0
  220. data/test/fixtures/developers/_developer.erb +1 -0
  221. data/test/fixtures/developers.yml +21 -0
  222. data/test/fixtures/developers_projects.yml +13 -0
  223. data/test/fixtures/failsafe/500.html +1 -0
  224. data/test/fixtures/fun/games/_game.erb +1 -0
  225. data/test/fixtures/fun/games/hello_world.erb +1 -0
  226. data/test/fixtures/fun/serious/games/_game.erb +1 -0
  227. data/test/fixtures/functional_caching/_partial.erb +3 -0
  228. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
  229. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
  230. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
  231. data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
  232. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
  233. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
  234. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
  235. data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
  236. data/test/fixtures/helpers/abc_helper.rb +5 -0
  237. data/test/fixtures/helpers/fun/games_helper.rb +3 -0
  238. data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
  239. data/test/fixtures/layout_tests/abs_path_layout.rhtml +1 -0
  240. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  241. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  242. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
  243. data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
  244. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
  245. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  246. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
  247. data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
  248. data/test/fixtures/layouts/_column.html.erb +2 -0
  249. data/test/fixtures/layouts/block_with_layout.erb +3 -0
  250. data/test/fixtures/layouts/builder.builder +3 -0
  251. data/test/fixtures/layouts/default_html.html.erb +1 -0
  252. data/test/fixtures/layouts/partial_with_layout.erb +3 -0
  253. data/test/fixtures/layouts/standard.erb +1 -0
  254. data/test/fixtures/layouts/talk_from_action.erb +2 -0
  255. data/test/fixtures/layouts/xhr.html.erb +2 -0
  256. data/test/fixtures/layouts/yield.erb +2 -0
  257. data/test/fixtures/mascot.rb +3 -0
  258. data/test/fixtures/mascots/_mascot.html.erb +1 -0
  259. data/test/fixtures/mascots.yml +4 -0
  260. data/test/fixtures/multipart/binary_file +0 -0
  261. data/test/fixtures/multipart/boundary_problem_file +10 -0
  262. data/test/fixtures/multipart/bracketed_param +5 -0
  263. data/test/fixtures/multipart/empty +10 -0
  264. data/test/fixtures/multipart/hello.txt +1 -0
  265. data/test/fixtures/multipart/large_text_file +10 -0
  266. data/test/fixtures/multipart/mixed_files +0 -0
  267. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  268. data/test/fixtures/multipart/none +9 -0
  269. data/test/fixtures/multipart/single_parameter +5 -0
  270. data/test/fixtures/multipart/text_file +10 -0
  271. data/test/fixtures/override/test/hello_world.erb +1 -0
  272. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  273. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  274. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  275. data/test/fixtures/post_test/post/index.html.erb +1 -0
  276. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  277. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  278. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  279. data/test/fixtures/project.rb +3 -0
  280. data/test/fixtures/projects/_project.erb +1 -0
  281. data/test/fixtures/projects.yml +7 -0
  282. data/test/fixtures/public/404.html +1 -0
  283. data/test/fixtures/public/500.da.html +1 -0
  284. data/test/fixtures/public/500.html +1 -0
  285. data/test/fixtures/public/absolute/test.css +23 -0
  286. data/test/fixtures/public/absolute/test.js +63 -0
  287. data/test/fixtures/public/images/rails.png +0 -0
  288. data/test/fixtures/public/javascripts/application.js +1 -0
  289. data/test/fixtures/public/javascripts/bank.js +1 -0
  290. data/test/fixtures/public/javascripts/controls.js +1 -0
  291. data/test/fixtures/public/javascripts/dragdrop.js +1 -0
  292. data/test/fixtures/public/javascripts/effects.js +1 -0
  293. data/test/fixtures/public/javascripts/prototype.js +1 -0
  294. data/test/fixtures/public/javascripts/robber.js +1 -0
  295. data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
  296. data/test/fixtures/public/javascripts/version.1.0.js +1 -0
  297. data/test/fixtures/public/stylesheets/bank.css +1 -0
  298. data/test/fixtures/public/stylesheets/robber.css +1 -0
  299. data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
  300. data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
  301. data/test/fixtures/quiz/questions/_question.html.erb +1 -0
  302. data/test/fixtures/replies/_reply.erb +1 -0
  303. data/test/fixtures/replies.yml +15 -0
  304. data/test/fixtures/reply.rb +7 -0
  305. data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
  306. data/test/fixtures/respond_to/all_types_with_layout.js.rjs +1 -0
  307. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  308. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  309. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  310. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  311. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  312. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  313. data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
  314. data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
  315. data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
  316. data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
  317. data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
  318. data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
  319. data/test/fixtures/scope/test/modgreet.erb +1 -0
  320. data/test/fixtures/shared.html.erb +1 -0
  321. data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
  322. data/test/fixtures/test/_counter.html.erb +1 -0
  323. data/test/fixtures/test/_customer.erb +1 -0
  324. data/test/fixtures/test/_customer_counter.erb +1 -0
  325. data/test/fixtures/test/_customer_greeting.erb +1 -0
  326. data/test/fixtures/test/_customer_with_var.erb +1 -0
  327. data/test/fixtures/test/_form.erb +1 -0
  328. data/test/fixtures/test/_from_helper.erb +1 -0
  329. data/test/fixtures/test/_hash_greeting.erb +1 -0
  330. data/test/fixtures/test/_hash_object.erb +2 -0
  331. data/test/fixtures/test/_hello.builder +1 -0
  332. data/test/fixtures/test/_labelling_form.erb +1 -0
  333. data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
  334. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  335. data/test/fixtures/test/_local_inspector.html.erb +1 -0
  336. data/test/fixtures/test/_one.html.erb +1 -0
  337. data/test/fixtures/test/_partial.erb +1 -0
  338. data/test/fixtures/test/_partial.html.erb +1 -0
  339. data/test/fixtures/test/_partial.js.erb +1 -0
  340. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  341. data/test/fixtures/test/_partial_only.erb +1 -0
  342. data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
  343. data/test/fixtures/test/_person.erb +2 -0
  344. data/test/fixtures/test/_raise.html.erb +1 -0
  345. data/test/fixtures/test/_two.html.erb +1 -0
  346. data/test/fixtures/test/action_talk_to_layout.erb +2 -0
  347. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  348. data/test/fixtures/test/capturing.erb +4 -0
  349. data/test/fixtures/test/content_for.erb +2 -0
  350. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  351. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  352. data/test/fixtures/test/delete_with_js.rjs +2 -0
  353. data/test/fixtures/test/dont_pick_me +1 -0
  354. data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
  355. data/test/fixtures/test/enum_rjs_test.rjs +6 -0
  356. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  357. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  358. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  359. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  360. data/test/fixtures/test/greeting.erb +1 -0
  361. data/test/fixtures/test/greeting.js.rjs +1 -0
  362. data/test/fixtures/test/hello.builder +4 -0
  363. data/test/fixtures/test/hello_world.da.html.erb +1 -0
  364. data/test/fixtures/test/hello_world.erb +1 -0
  365. data/test/fixtures/test/hello_world.erb~ +1 -0
  366. data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
  367. data/test/fixtures/test/hello_world_container.builder +3 -0
  368. data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
  369. data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
  370. data/test/fixtures/test/hello_xml_world.builder +11 -0
  371. data/test/fixtures/test/hyphen-ated.erb +1 -0
  372. data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
  373. data/test/fixtures/test/list.erb +1 -0
  374. data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
  375. data/test/fixtures/test/malformed/malformed.erb~ +1 -0
  376. data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
  377. data/test/fixtures/test/nested_layout.erb +3 -0
  378. data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
  379. data/test/fixtures/test/potential_conflicts.erb +4 -0
  380. data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
  381. data/test/fixtures/test/render_file_from_template.html.erb +1 -0
  382. data/test/fixtures/test/render_file_with_ivar.erb +1 -0
  383. data/test/fixtures/test/render_file_with_locals.erb +1 -0
  384. data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
  385. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
  386. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
  387. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
  388. data/test/fixtures/test/render_to_string_test.erb +1 -0
  389. data/test/fixtures/test/sub_template_raise.html.erb +1 -0
  390. data/test/fixtures/test/template.erb +1 -0
  391. data/test/fixtures/test/update_element_with_capture.erb +9 -0
  392. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  393. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
  394. data/test/fixtures/test/utf8.html.erb +2 -0
  395. data/test/fixtures/topic.rb +3 -0
  396. data/test/fixtures/topics/_topic.html.erb +1 -0
  397. data/test/fixtures/topics.yml +22 -0
  398. data/test/template/active_record_helper_i18n_test.rb +44 -0
  399. data/test/template/active_record_helper_test.rb +302 -0
  400. data/test/template/asset_tag_helper_test.rb +771 -0
  401. data/test/template/atom_feed_helper_test.rb +315 -0
  402. data/test/template/benchmark_helper_test.rb +86 -0
  403. data/test/template/compiled_templates_test.rb +204 -0
  404. data/test/template/date_helper_i18n_test.rb +121 -0
  405. data/test/template/date_helper_test.rb +2485 -0
  406. data/test/template/erb_util_test.rb +24 -0
  407. data/test/template/form_helper_test.rb +1393 -0
  408. data/test/template/form_options_helper_i18n_test.rb +27 -0
  409. data/test/template/form_options_helper_test.rb +807 -0
  410. data/test/template/form_tag_helper_test.rb +344 -0
  411. data/test/template/javascript_helper_test.rb +106 -0
  412. data/test/template/number_helper_i18n_test.rb +69 -0
  413. data/test/template/number_helper_test.rb +132 -0
  414. data/test/template/prototype_helper_test.rb +639 -0
  415. data/test/template/raw_output_helper_test.rb +21 -0
  416. data/test/template/record_tag_helper_test.rb +58 -0
  417. data/test/template/render_test.rb +290 -0
  418. data/test/template/sanitize_helper_test.rb +57 -0
  419. data/test/template/scriptaculous_helper_test.rb +90 -0
  420. data/test/template/tag_helper_test.rb +98 -0
  421. data/test/template/template_test.rb +32 -0
  422. data/test/template/test_test.rb +54 -0
  423. data/test/template/text_helper_test.rb +543 -0
  424. data/test/template/translation_helper_test.rb +32 -0
  425. data/test/template/url_helper_test.rb +622 -0
  426. data/test/testing_sandbox.rb +15 -0
  427. data/test/view/safe_buffer_test.rb +36 -0
  428. data/test/view/test_case_test.rb +176 -0
  429. metadata +531 -0
@@ -0,0 +1,71 @@
1
+ require 'fileutils'
2
+ require 'uri'
3
+ require 'set'
4
+
5
+ module ActionController #:nodoc:
6
+ # Caching is a cheap way of speeding up slow applications by keeping the result of calculations, renderings, and database calls
7
+ # around for subsequent requests. Action Controller affords you three approaches in varying levels of granularity: Page, Action, Fragment.
8
+ #
9
+ # You can read more about each approach and the sweeping assistance by clicking the modules below.
10
+ #
11
+ # Note: To turn off all caching and sweeping, set Base.perform_caching = false.
12
+ #
13
+ #
14
+ # == Caching stores
15
+ #
16
+ # All the caching stores from ActiveSupport::Cache is available to be used as backends for Action Controller caching. This setting only
17
+ # affects action and fragment caching as page caching is always written to disk.
18
+ #
19
+ # Configuration examples (MemoryStore is the default):
20
+ #
21
+ # ActionController::Base.cache_store = :memory_store
22
+ # ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
23
+ # ActionController::Base.cache_store = :drb_store, "druby://localhost:9192"
24
+ # ActionController::Base.cache_store = :mem_cache_store, "localhost"
25
+ # ActionController::Base.cache_store = :mem_cache_store, Memcached::Rails.new("localhost:11211")
26
+ # ActionController::Base.cache_store = MyOwnStore.new("parameter")
27
+ module Caching
28
+ autoload :Actions, 'action_controller/caching/actions'
29
+ autoload :Fragments, 'action_controller/caching/fragments'
30
+ autoload :Pages, 'action_controller/caching/pages'
31
+ autoload :Sweeper, 'action_controller/caching/sweeper'
32
+ autoload :Sweeping, 'action_controller/caching/sweeping'
33
+
34
+ def self.included(base) #:nodoc:
35
+ base.class_eval do
36
+ @@cache_store = nil
37
+ cattr_reader :cache_store
38
+
39
+ # Defines the storage option for cached fragments
40
+ def self.cache_store=(store_option)
41
+ @@cache_store = ActiveSupport::Cache.lookup_store(store_option)
42
+ end
43
+
44
+ include Pages, Actions, Fragments
45
+ include Sweeping if defined?(ActiveRecord)
46
+
47
+ @@perform_caching = true
48
+ cattr_accessor :perform_caching
49
+
50
+ def self.cache_configured?
51
+ perform_caching && cache_store
52
+ end
53
+ end
54
+ end
55
+
56
+ protected
57
+ # Convenience accessor
58
+ def cache(key, options = {}, &block)
59
+ if cache_configured?
60
+ cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
61
+ else
62
+ yield
63
+ end
64
+ end
65
+
66
+ private
67
+ def cache_configured?
68
+ self.class.cache_configured?
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,112 @@
1
+ require 'delegate'
2
+
3
+ CGI.module_eval { remove_const "Cookie" }
4
+
5
+ # TODO: document how this differs from stdlib CGI::Cookie
6
+ class CGI #:nodoc:
7
+ class Cookie < DelegateClass(Array)
8
+ attr_accessor :name, :value, :path, :domain, :expires
9
+ attr_reader :secure, :http_only
10
+
11
+ # Creates a new CGI::Cookie object.
12
+ #
13
+ # The contents of the cookie can be specified as a +name+ and one
14
+ # or more +value+ arguments. Alternatively, the contents can
15
+ # be specified as a single hash argument. The possible keywords of
16
+ # this hash are as follows:
17
+ #
18
+ # * <tt>:name</tt> - The name of the cookie. Required.
19
+ # * <tt>:value</tt> - The cookie's value or list of values.
20
+ # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the
21
+ # base directory of the CGI script.
22
+ # * <tt>:domain</tt> - The domain for which this cookie applies.
23
+ # * <tt>:expires</tt> - The time at which this cookie expires, as a Time object.
24
+ # * <tt>:secure</tt> - Whether this cookie is a secure cookie or not (defaults to
25
+ # +false+). Secure cookies are only transmitted to HTTPS servers.
26
+ # * <tt>:http_only</tt> - Whether this cookie can be accessed by client side scripts (e.g. document.cookie) or only over HTTP.
27
+ # More details in http://msdn2.microsoft.com/en-us/library/system.web.httpcookie.httponly.aspx. Defaults to +false+.
28
+ #
29
+ # These keywords correspond to attributes of the cookie object.
30
+ def initialize(name = '', *value)
31
+ if name.kind_of?(String)
32
+ @name = name
33
+ @value = Array(value)
34
+ @domain = nil
35
+ @expires = nil
36
+ @secure = false
37
+ @http_only = false
38
+ @path = nil
39
+ else
40
+ @name = name['name']
41
+ @value = (name['value'].kind_of?(String) ? [name['value']] : Array(name['value'])).delete_if(&:blank?)
42
+ @domain = name['domain']
43
+ @expires = name['expires']
44
+ @secure = name['secure'] || false
45
+ @http_only = name['http_only'] || false
46
+ @path = name['path']
47
+ end
48
+
49
+ raise ArgumentError, "`name' required" unless @name
50
+
51
+ # simple support for IE
52
+ unless @path
53
+ %r|^(.*/)|.match(ENV['SCRIPT_NAME'])
54
+ @path = ($1 or '')
55
+ end
56
+
57
+ super(@value)
58
+ end
59
+
60
+ # Sets whether the Cookie is a secure cookie or not.
61
+ def secure=(val)
62
+ @secure = val == true
63
+ end
64
+
65
+ # Sets whether the Cookie is an HTTP only cookie or not.
66
+ def http_only=(val)
67
+ @http_only = val == true
68
+ end
69
+
70
+ # Converts the Cookie to its string representation.
71
+ def to_s
72
+ buf = ''
73
+ buf << @name << '='
74
+ buf << (@value.kind_of?(String) ? CGI::escape(@value) : @value.collect{|v| CGI::escape(v) }.join("&"))
75
+ buf << '; domain=' << @domain if @domain
76
+ buf << '; path=' << @path if @path
77
+ buf << '; expires=' << CGI::rfc1123_date(@expires) if @expires
78
+ buf << '; secure' if @secure
79
+ buf << '; HttpOnly' if @http_only
80
+ buf
81
+ end
82
+
83
+ # FIXME: work around broken 1.8.7 DelegateClass#respond_to?
84
+ def respond_to?(method, include_private = false)
85
+ return true if super(method)
86
+ return __getobj__.respond_to?(method, include_private)
87
+ end
88
+
89
+ # Parses a raw cookie string into a hash of <tt>cookie-name => cookie-object</tt>
90
+ # pairs.
91
+ #
92
+ # cookies = CGI::Cookie::parse("raw_cookie_string")
93
+ # # => { "name1" => cookie1, "name2" => cookie2, ... }
94
+ #
95
+ def self.parse(raw_cookie)
96
+ cookies = Hash.new([])
97
+
98
+ if raw_cookie
99
+ raw_cookie.split(/;\s?/).each do |pairs|
100
+ name, value = pairs.split('=',2)
101
+ next unless name and value
102
+ name = CGI::unescape(name)
103
+ unless cookies.has_key?(name)
104
+ cookies[name] = new(name, CGI::unescape(value))
105
+ end
106
+ end
107
+ end
108
+
109
+ cookies
110
+ end
111
+ end # class Cookie
112
+ end
@@ -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,24 @@
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
+ @stdinput.set_encoding(Encoding::BINARY) if @stdinput.respond_to?(:set_encoding)
20
+ initialize_without_stdinput(type || 'query')
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ require 'action_controller/cgi_ext/stdinput'
2
+ require 'action_controller/cgi_ext/query_extension'
3
+ require 'action_controller/cgi_ext/cookie'
4
+
5
+ class CGI #:nodoc:
6
+ include ActionController::CgiExt::Stdinput
7
+
8
+ class << self
9
+ alias :escapeHTML_fail_on_nil :escapeHTML
10
+
11
+ def escapeHTML(string)
12
+ escapeHTML_fail_on_nil(string) unless string.nil?
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,77 @@
1
+ require 'action_controller/cgi_ext'
2
+
3
+ module ActionController #:nodoc:
4
+ class CGIHandler
5
+ module ProperStream
6
+ def each
7
+ while line = gets
8
+ yield line
9
+ end
10
+ end
11
+
12
+ def read(*args)
13
+ if args.empty?
14
+ super || ""
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
20
+
21
+ def self.dispatch_cgi(app, cgi, out = $stdout)
22
+ env = cgi.__send__(:env_table)
23
+ env.delete "HTTP_CONTENT_LENGTH"
24
+
25
+ cgi.stdinput.extend ProperStream
26
+
27
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
28
+
29
+ env.update({
30
+ "rack.version" => [0,1],
31
+ "rack.input" => cgi.stdinput,
32
+ "rack.errors" => $stderr,
33
+ "rack.multithread" => false,
34
+ "rack.multiprocess" => true,
35
+ "rack.run_once" => false,
36
+ "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
37
+ })
38
+
39
+ env["QUERY_STRING"] ||= ""
40
+ env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
41
+ env["REQUEST_PATH"] ||= "/"
42
+ env.delete "PATH_INFO" if env["PATH_INFO"] == ""
43
+
44
+ status, headers, body = app.call(env)
45
+ begin
46
+ out.binmode if out.respond_to?(:binmode)
47
+ out.sync = false if out.respond_to?(:sync=)
48
+
49
+ headers['Status'] = status.to_s
50
+
51
+ if headers.include?('Set-Cookie')
52
+ headers['cookie'] = headers.delete('Set-Cookie').split("\n")
53
+ end
54
+
55
+ out.write(cgi.header(headers))
56
+
57
+ body.each { |part|
58
+ out.write part
59
+ out.flush if out.respond_to?(:flush)
60
+ }
61
+ ensure
62
+ body.close if body.respond_to?(:close)
63
+ end
64
+ end
65
+ end
66
+
67
+ class CgiRequest #:nodoc:
68
+ DEFAULT_SESSION_OPTIONS = {
69
+ :database_manager => nil,
70
+ :prefix => "ruby_sess.",
71
+ :session_path => "/",
72
+ :session_key => "_session_id",
73
+ :cookie_only => true,
74
+ :session_http_only => true
75
+ }
76
+ end
77
+ end
@@ -0,0 +1,95 @@
1
+ module ActionController #:nodoc:
2
+ # Cookies are read and written through ActionController#cookies.
3
+ #
4
+ # The cookies being read are the ones received along with the request, the cookies
5
+ # being written will be sent out with the response. Reading a cookie does not get
6
+ # the cookie object itself back, just the value it holds.
7
+ #
8
+ # Examples for writing:
9
+ #
10
+ # # Sets a simple session cookie.
11
+ # cookies[:user_name] = "david"
12
+ #
13
+ # # Sets a cookie that expires in 1 hour.
14
+ # cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now }
15
+ #
16
+ # Examples for reading:
17
+ #
18
+ # cookies[:user_name] # => "david"
19
+ # cookies.size # => 2
20
+ #
21
+ # Example for deleting:
22
+ #
23
+ # cookies.delete :user_name
24
+ #
25
+ # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
26
+ #
27
+ # cookies[:key] = {
28
+ # :value => 'a yummy cookie',
29
+ # :expires => 1.year.from_now,
30
+ # :domain => 'domain.com'
31
+ # }
32
+ #
33
+ # cookies.delete(:key, :domain => 'domain.com')
34
+ #
35
+ # The option symbols for setting cookies are:
36
+ #
37
+ # * <tt>:value</tt> - The cookie's value or list of values (as an array).
38
+ # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the root
39
+ # of the application.
40
+ # * <tt>:domain</tt> - The domain for which this cookie applies.
41
+ # * <tt>:expires</tt> - The time at which this cookie expires, as a Time object.
42
+ # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers.
43
+ # Default is +false+.
44
+ # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or
45
+ # only HTTP. Defaults to +false+.
46
+ module Cookies
47
+ def self.included(base)
48
+ base.helper_method :cookies
49
+ end
50
+
51
+ protected
52
+ # Returns the cookie container, which operates as described above.
53
+ def cookies
54
+ @cookies ||= CookieJar.new(self)
55
+ end
56
+ end
57
+
58
+ class CookieJar < Hash #:nodoc:
59
+ def initialize(controller)
60
+ @controller, @cookies = controller, controller.request.cookies
61
+ super()
62
+ update(@cookies)
63
+ end
64
+
65
+ # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
66
+ def [](name)
67
+ super(name.to_s)
68
+ end
69
+
70
+ # Sets the cookie named +name+. The second argument may be the very cookie
71
+ # value, or a hash of options as documented above.
72
+ def []=(key, options)
73
+ if options.is_a?(Hash)
74
+ options.symbolize_keys!
75
+ else
76
+ options = { :value => options }
77
+ end
78
+
79
+ options[:path] = "/" unless options.has_key?(:path)
80
+ super(key.to_s, options[:value])
81
+ @controller.response.set_cookie(key, options)
82
+ end
83
+
84
+ # Removes the cookie on the client machine by setting the value to an empty string
85
+ # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in
86
+ # an options hash to delete cookies with extra data such as a <tt>:path</tt>.
87
+ def delete(key, options = {})
88
+ options.symbolize_keys!
89
+ options[:path] = "/" unless options.has_key?(:path)
90
+ value = super(key.to_s)
91
+ @controller.response.delete_cookie(key, options)
92
+ value
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,133 @@
1
+ module ActionController
2
+ # Dispatches requests to the appropriate controller and takes care of
3
+ # reloading the app after each request when Dependencies.load? is true.
4
+ class Dispatcher
5
+ @@cache_classes = true
6
+
7
+ class << self
8
+ def define_dispatcher_callbacks(cache_classes)
9
+ @@cache_classes = cache_classes
10
+ unless cache_classes
11
+ ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
12
+ end
13
+
14
+ if defined?(ActiveRecord)
15
+ to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
16
+ end
17
+
18
+ after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
19
+
20
+ to_prepare do
21
+ I18n.reload!
22
+ end
23
+ end
24
+
25
+ # DEPRECATE: Remove CGI support
26
+ def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout)
27
+ new(output).dispatch_cgi(cgi, session_options)
28
+ end
29
+
30
+ # Add a preparation callback. Preparation callbacks are run before every
31
+ # request in development mode, and before the first request in production
32
+ # mode.
33
+ #
34
+ # An optional identifier may be supplied for the callback. If provided,
35
+ # to_prepare may be called again with the same identifier to replace the
36
+ # existing callback. Passing an identifier is a suggested practice if the
37
+ # code adding a preparation block may be reloaded.
38
+ def to_prepare(identifier = nil, &block)
39
+ @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
40
+ callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
41
+ @prepare_dispatch_callbacks.replace_or_append!(callback)
42
+ end
43
+
44
+ def run_prepare_callbacks
45
+ if defined?(Rails) && Rails.logger
46
+ logger = Rails.logger
47
+ else
48
+ logger = Logger.new($stderr)
49
+ end
50
+
51
+ new(logger).send :run_callbacks, :prepare_dispatch
52
+ end
53
+
54
+ def reload_application
55
+ # Run prepare callbacks before every request in development mode
56
+ run_prepare_callbacks
57
+
58
+ Routing::Routes.reload
59
+ end
60
+
61
+ def cleanup_application
62
+ # Cleanup the application before processing the current request.
63
+ ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
64
+ ActiveSupport::Dependencies.clear
65
+ ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
66
+ end
67
+ end
68
+
69
+ cattr_accessor :middleware
70
+ self.middleware = MiddlewareStack.new do |middleware|
71
+ middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
72
+ middleware.instance_eval(File.read(middlewares))
73
+ end
74
+
75
+ include ActiveSupport::Callbacks
76
+ define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
77
+
78
+ # DEPRECATE: Remove arguments, since they are only used by CGI
79
+ def initialize(output = $stdout, request = nil, response = nil)
80
+ @output = output
81
+ build_middleware_stack if @@cache_classes
82
+ end
83
+
84
+ def dispatch
85
+ begin
86
+ run_callbacks :before_dispatch
87
+ Routing::Routes.call(@env)
88
+ rescue Exception => exception
89
+ if controller ||= (::ApplicationController rescue Base)
90
+ controller.call_with_exception(@env, exception).to_a
91
+ else
92
+ raise exception
93
+ end
94
+ ensure
95
+ run_callbacks :after_dispatch, :enumerator => :reverse_each
96
+ end
97
+ end
98
+
99
+ # DEPRECATE: Remove CGI support
100
+ def dispatch_cgi(cgi, session_options)
101
+ CGIHandler.dispatch_cgi(self, cgi, @output)
102
+ end
103
+
104
+ def call(env)
105
+ if @@cache_classes
106
+ @app.call(env)
107
+ else
108
+ Reloader.run do
109
+ # When class reloading is turned on, we will want to rebuild the
110
+ # middleware stack every time we process a request. If we don't
111
+ # rebuild the middleware stack, then the stack may contain references
112
+ # to old classes metal classes, which will b0rk class reloading.
113
+ build_middleware_stack
114
+ @app.call(env)
115
+ end
116
+ end
117
+ end
118
+
119
+ def _call(env)
120
+ @env = env
121
+ dispatch
122
+ end
123
+
124
+ def flush_logger
125
+ Base.logger.flush
126
+ end
127
+
128
+ private
129
+ def build_middleware_stack
130
+ @app = @@middleware.build(lambda { |env| self.dup._call(env) })
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,86 @@
1
+ require 'erb'
2
+
3
+ module ActionController
4
+ # The Failsafe middleware is usually the top-most middleware in the Rack
5
+ # middleware chain. It returns the underlying middleware's response, but if
6
+ # the underlying middle raises an exception then Failsafe will log the
7
+ # exception into the Rails log file, and will attempt to return an error
8
+ # message response.
9
+ #
10
+ # Failsafe is a last resort for logging errors and for telling the HTTP
11
+ # client that something went wrong. Do not confuse this with the
12
+ # ActionController::Rescue module, which is responsible for catching
13
+ # exceptions at deeper levels. Unlike Failsafe, which is as simple as
14
+ # possible, Rescue provides features that allow developers to hook into
15
+ # the error handling logic, and can customize the error message response
16
+ # based on the HTTP client's IP.
17
+ class Failsafe
18
+ cattr_accessor :error_file_path
19
+ self.error_file_path = Rails.public_path if defined?(Rails.public_path)
20
+
21
+ def initialize(app)
22
+ @app = app
23
+ end
24
+
25
+ def call(env)
26
+ @app.call(env)
27
+ rescue Exception => exception
28
+ # Reraise exception in test environment
29
+ if defined?(Rails) && Rails.env.test?
30
+ raise exception
31
+ else
32
+ failsafe_response(exception)
33
+ end
34
+ end
35
+
36
+ private
37
+ def failsafe_response(exception)
38
+ log_failsafe_exception(exception)
39
+ [500, {'Content-Type' => 'text/html'}, [failsafe_response_body]]
40
+ rescue Exception => failsafe_error # Logger or IO errors
41
+ $stderr.puts "Error during failsafe response: #{failsafe_error}"
42
+ end
43
+
44
+ def failsafe_response_body
45
+ error_template_path = "#{self.class.error_file_path}/500.html"
46
+ if File.exist?(error_template_path)
47
+ begin
48
+ result = render_template(error_template_path)
49
+ rescue Exception
50
+ result = nil
51
+ end
52
+ else
53
+ result = nil
54
+ end
55
+ if result.nil?
56
+ result = "<html><body><h1>500 Internal Server Error</h1>" <<
57
+ "If you are the administrator of this website, then please read this web " <<
58
+ "application's log file to find out what went wrong.</body></html>"
59
+ end
60
+ result
61
+ end
62
+
63
+ # The default 500.html uses the h() method.
64
+ def h(text) # :nodoc:
65
+ ERB::Util.h(text)
66
+ end
67
+
68
+ def render_template(filename)
69
+ ERB.new(File.read(filename)).result(binding)
70
+ end
71
+
72
+ def log_failsafe_exception(exception)
73
+ message = "/!\\ FAILSAFE /!\\ #{Time.now}\n Status: 500 Internal Server Error\n"
74
+ message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception
75
+ failsafe_logger.fatal(message)
76
+ end
77
+
78
+ def failsafe_logger
79
+ if defined?(Rails) && Rails.logger
80
+ Rails.logger
81
+ else
82
+ Logger.new($stderr)
83
+ end
84
+ end
85
+ end
86
+ end