Browse files

Merge branch 'master' of git://github.com/lifo/docrails

* 'master' of git://github.com/lifo/docrails: (259 commits)
  Fix a small typo
  ensure authors get warnings about broken links, and ensure end users don't
  in guides generator, warn about duplicate header IDs only if WARN_DUPLICATE_HEADERS
  replace edit distance implementation with one written from scratch to avoid license issues
  removes a wrong comment in the finders guide
  updates fxn picture
  thanks but release notes are mostly frozen once they are published, and provide only an overview of the new stuff
  Added extra notes to nested model forms explanation in 2.3 release notes to cover has_one relationships
  clarifies a bit more what's the issue with check boxes and arrays of parameters
  be even more ambiguous about the order of generation of hidden input for check boxes in form helper guide
  this page referred to an :href_options keyword hash, in fact the correct keyword (the one the code responds to) is :html
  update explanation of check box generation according to f400209
  Hidden field with check box goes first.
  update rack fixture to be ruby 1.9 compat
  Better error message to try to figure out why the CI build is failing
  ruby 1.9 compat: Pathname doesn't support =~
  update rack fixture to be ruby 1.9 compat
  update metal fixtures to be ruby 1.9 compat
  Fix brittle Time.now mock
  Ensure our bundled version of rack is at the front of the load path
  ...
  • Loading branch information...
2 parents 4b6458b + f7bdfe8 commit 76556b08bb8d22dccd7c44e302f625442c5cc8f0 @packagethief packagethief committed Mar 24, 2009
Showing with 5,593 additions and 2,482 deletions.
  1. +1 −4 actionmailer/CHANGELOG
  2. +1 −1 actionmailer/Rakefile
  3. +2 −1 actionmailer/lib/action_mailer.rb
  4. +1 −1 actionmailer/lib/action_mailer/base.rb
  5. +4 −1 actionmailer/lib/action_mailer/part.rb
  6. +1 −1 actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb
  7. +1 −1 actionmailer/lib/action_mailer/version.rb
  8. +29 −1 actionmailer/test/mail_layout_test.rb
  9. +2 −1 actionmailer/test/mail_service_test.rb
  10. +4 −4 actionmailer/test/test_helper_test.rb
  11. +9 −4 actionpack/CHANGELOG
  12. +1 −2 actionpack/Rakefile
  13. +6 −1 actionpack/lib/action_controller.rb
  14. +43 −11 actionpack/lib/action_controller/base.rb
  15. +10 −17 actionpack/lib/action_controller/caching/actions.rb
  16. +0 −7 actionpack/lib/action_controller/dispatcher.rb
  17. +51 −21 actionpack/lib/action_controller/http_authentication.rb
  18. +16 −9 actionpack/lib/action_controller/layout.rb
  19. +5 −2 actionpack/lib/action_controller/polymorphic_routes.rb
  20. +2 −1 actionpack/lib/action_controller/request.rb
  21. +8 −7 actionpack/lib/action_controller/resources.rb
  22. +1 −1 actionpack/lib/action_controller/routing.rb
  23. +2 −1 actionpack/lib/action_controller/routing/builder.rb
  24. +0 −1 actionpack/lib/action_controller/routing/recognition_optimisation.rb
  25. +11 −3 actionpack/lib/action_controller/routing/segments.rb
  26. +1 −1 actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
  27. +3 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
  28. +2 −2 actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb
  29. +1 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb
  30. +1 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb
  31. +1 −5 actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb
  32. +49 −0 actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
  33. +5 −3 actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb
  34. +23 −0 actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb
  35. +2 −2 actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb
  36. +4 −2 actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb
  37. +1 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
  38. +4 −0 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
  39. +3 −0 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
  40. +5 −2 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
  41. +3 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
  42. +3 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
  43. +3 −0 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
  44. +8 −2 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
  45. +22 −36 actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
  46. +2 −0 actionpack/lib/action_controller/vendor/rack-1.0/rack/response.rb
  47. +1 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb
  48. +5 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
  49. +14 −1 actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
  50. +1 −1 actionpack/lib/action_pack/version.rb
  51. +19 −5 actionpack/lib/action_view/base.rb
  52. +2 −2 actionpack/lib/action_view/helpers/active_record_helper.rb
  53. +2 −2 actionpack/lib/action_view/helpers/date_helper.rb
  54. +104 −63 actionpack/lib/action_view/helpers/form_helper.rb
  55. +2 −2 actionpack/lib/action_view/helpers/form_tag_helper.rb
  56. +4 −2 actionpack/lib/action_view/helpers/number_helper.rb
  57. +1 −1 actionpack/lib/action_view/helpers/prototype_helper.rb
  58. +6 −5 actionpack/lib/action_view/helpers/text_helper.rb
  59. +4 −4 actionpack/lib/action_view/paths.rb
  60. +11 −15 actionpack/lib/action_view/renderable.rb
  61. +16 −9 actionpack/lib/action_view/template.rb
  62. +46 −0 actionpack/test/activerecord/active_record_store_test.rb
  63. +33 −28 actionpack/test/controller/assert_select_test.rb
  64. +14 −0 actionpack/test/controller/caching_test.rb
  65. +8 −0 actionpack/test/controller/fake_models.rb
  66. +1 −1 actionpack/test/controller/html-scanner/document_test.rb
  67. +46 −7 actionpack/test/controller/http_digest_authentication_test.rb
  68. +3 −3 actionpack/test/controller/integration_test.rb
  69. +11 −1 actionpack/test/controller/layout_test.rb
  70. +1 −1 actionpack/test/controller/mime_responds_test.rb
  71. +85 −0 actionpack/test/controller/polymorphic_routes_test.rb
  72. +2 −2 actionpack/test/controller/redirect_test.rb
  73. +128 −11 actionpack/test/controller/render_test.rb
  74. +1 −1 actionpack/test/controller/request/multipart_params_parsing_test.rb
  75. +9 −9 actionpack/test/controller/request_forgery_protection_test.rb
  76. +3 −3 actionpack/test/controller/request_test.rb
  77. +73 −11 actionpack/test/controller/resources_test.rb
  78. +83 −29 actionpack/test/controller/routing_test.rb
  79. +3 −3 actionpack/test/controller/selector_test.rb
  80. +1 −1 actionpack/test/controller/send_file_test.rb
  81. +14 −16 actionpack/test/controller/session/cookie_store_test.rb
  82. +24 −16 actionpack/test/controller/session/mem_cache_store_test.rb
  83. +1 −1 actionpack/test/controller/url_rewriter_test.rb
  84. +1 −0 actionpack/test/fixtures/layouts/default_html.html.erb
  85. +2 −0 actionpack/test/fixtures/layouts/xhr.html.erb
  86. +1 −0 actionpack/test/fixtures/quiz/questions/_question.html.erb
  87. +1 −0 actionpack/test/fixtures/test/malformed/malformed.en.html.erb~
  88. +1 −0 actionpack/test/fixtures/test/malformed/malformed.erb~
  89. +1 −0 actionpack/test/fixtures/test/malformed/malformed.html.erb~
  90. +34 −0 actionpack/test/template/active_record_helper_test.rb
  91. +41 −0 actionpack/test/template/form_helper_test.rb
  92. +9 −2 actionpack/test/template/form_tag_helper_test.rb
  93. +0 −5 actionpack/test/template/javascript_helper_test.rb
  94. +1 −0 actionpack/test/template/number_helper_test.rb
  95. +14 −0 actionpack/test/template/render_test.rb
  96. +6 −0 actionpack/test/template/text_helper_test.rb
  97. +1 −1 actionpack/test/template/url_helper_test.rb
  98. +1 −1 activemodel/test/state_machine/event_test.rb
  99. +2 −5 activerecord/CHANGELOG
  100. +1 −1 activerecord/Rakefile
  101. +24 −127 activerecord/lib/active_record/associations.rb
  102. +37 −20 activerecord/lib/active_record/associations/association_collection.rb
  103. +2 −2 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
  104. +2 −2 activerecord/lib/active_record/associations/has_many_association.rb
  105. +5 −5 activerecord/lib/active_record/associations/has_many_through_association.rb
  106. +11 −2 activerecord/lib/active_record/associations/has_one_association.rb
  107. +182 −58 activerecord/lib/active_record/autosave_association.rb
  108. +19 −20 activerecord/lib/active_record/base.rb
  109. +29 −18 activerecord/lib/active_record/batches.rb
  110. +18 −8 activerecord/lib/active_record/calculations.rb
  111. +16 −0 activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
  112. +1 −1 activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
  113. +40 −24 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
  114. +33 −0 activerecord/lib/active_record/locking/optimistic.rb
  115. +23 −7 activerecord/lib/active_record/named_scope.rb
  116. +1 −1 activerecord/lib/active_record/reflection.rb
  117. +12 −6 activerecord/lib/active_record/serializers/xml_serializer.rb
  118. +7 −3 activerecord/lib/active_record/session_store.rb
  119. +13 −0 activerecord/lib/active_record/test_case.rb
  120. +10 −5 activerecord/lib/active_record/validations.rb
  121. +1 −1 activerecord/lib/active_record/version.rb
  122. +35 −131 activerecord/test/cases/associations/belongs_to_associations_test.rb
  123. +29 −0 activerecord/test/cases/associations/eager_load_nested_include_test.rb
  124. +4 −4 activerecord/test/cases/associations/eager_test.rb
  125. +36 −1 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
  126. +80 −142 activerecord/test/cases/associations/has_many_associations_test.rb
  127. +28 −1 activerecord/test/cases/associations/has_many_through_associations_test.rb
  128. +39 −92 activerecord/test/cases/associations/has_one_associations_test.rb
  129. +18 −2 activerecord/test/cases/associations/has_one_through_associations_test.rb
  130. +1 −1 activerecord/test/cases/attribute_methods_test.rb
  131. +501 −8 activerecord/test/cases/autosave_association_test.rb
  132. +21 −23 activerecord/test/cases/base_test.rb
  133. +15 −3 activerecord/test/cases/batches_test.rb
  134. +23 −2 activerecord/test/cases/calculations_test.rb
  135. +2 −2 activerecord/test/cases/callbacks_test.rb
  136. +25 −0 activerecord/test/cases/connection_pool_test.rb
  137. +1 −1 activerecord/test/cases/dirty_test.rb
  138. +47 −32 activerecord/test/cases/finder_test.rb
  139. +2 −2 activerecord/test/cases/fixtures_test.rb
  140. +2 −2 activerecord/test/cases/inheritance_test.rb
  141. +23 −5 activerecord/test/cases/locking_test.rb
  142. +38 −8 activerecord/test/cases/method_scoping_test.rb
  143. +45 −21 activerecord/test/cases/migration_test.rb
  144. +47 −8 activerecord/test/cases/named_scope_test.rb
  145. +4 −3 activerecord/test/cases/reflection_test.rb
  146. +11 −6 activerecord/test/cases/transactions_test.rb
  147. +27 −21 activerecord/test/cases/validations_test.rb
  148. +12 −1 activerecord/test/cases/xml_serialization_test.rb
  149. +4 −0 activerecord/test/fixtures/toys.yml
  150. +2 −0 activerecord/test/models/company.rb
  151. +3 −0 activerecord/test/models/event.rb
  152. +2 −1 activerecord/test/models/owner.rb
  153. +2 −1 activerecord/test/models/pet.rb
  154. +48 −1 activerecord/test/models/pirate.rb
  155. +6 −0 activerecord/test/models/post.rb
  156. +6 −0 activerecord/test/models/reply.rb
  157. +11 −1 activerecord/test/models/topic.rb
  158. +4 −0 activerecord/test/models/toy.rb
  159. +9 −0 activerecord/test/schema/schema.rb
  160. +2 −2 activeresource/CHANGELOG
  161. +1 −1 activeresource/Rakefile
  162. +1 −1 activeresource/lib/active_resource/version.rb
  163. +1 −0 activeresource/test/abstract_unit.rb
  164. +4 −4 activeresource/test/authorization_test.rb
  165. +11 −11 activeresource/test/base_test.rb
  166. +6 −4 activesupport/CHANGELOG
  167. +2 −3 activesupport/lib/active_support/core_ext/array/conversions.rb
  168. +3 −2 activesupport/lib/active_support/core_ext/hash/conversions.rb
  169. +6 −0 activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
  170. +2 −2 activesupport/lib/active_support/core_ext/string/inflections.rb
  171. +1 −1 activesupport/lib/active_support/duration.rb
  172. +7 −5 activesupport/lib/active_support/inflector.rb
  173. +20 −2 activesupport/lib/active_support/json/decoding.rb
  174. +4 −0 activesupport/lib/active_support/memoizable.rb
  175. +14 −2 activesupport/lib/active_support/multibyte/chars.rb
  176. +2 −2 activesupport/lib/active_support/ordered_hash.rb
  177. +1 −1 activesupport/lib/active_support/test_case.rb
  178. +6 −1 activesupport/lib/active_support/testing/setup_and_teardown.rb
  179. +2 −2 activesupport/lib/active_support/vendor.rb
  180. +0 −3 activesupport/lib/active_support/vendor/i18n-0.1.1/.gitignore
  181. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/MIT-LICENSE
  182. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/README.textile
  183. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/Rakefile
  184. +2 −2 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/i18n.gemspec
  185. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/lib/i18n.rb
  186. +1 −9 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/lib/i18n/backend/simple.rb
  187. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/lib/i18n/exceptions.rb
  188. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/test/all.rb
  189. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/test/i18n_exceptions_test.rb
  190. +2 −2 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/test/i18n_test.rb
  191. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/test/locale/en.rb
  192. 0 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/test/locale/en.yml
  193. +56 −12 activesupport/lib/active_support/vendor/{i18n-0.1.1 → i18n-0.1.3}/test/simple_backend_test.rb
  194. +1 −1 activesupport/lib/active_support/version.rb
  195. +23 −105 activesupport/lib/active_support/xml_mini.rb
  196. +133 −0 activesupport/lib/active_support/xml_mini/libxml.rb
  197. +77 −0 activesupport/lib/active_support/xml_mini/nokogiri.rb
  198. +108 −0 activesupport/lib/active_support/xml_mini/rexml.rb
  199. +3 −3 activesupport/test/core_ext/class_test.rb
  200. +24 −2 activesupport/test/core_ext/hash_ext_test.rb
  201. +2 −2 activesupport/test/core_ext/load_error_test.rb
  202. +2 −2 activesupport/test/core_ext/module/synchronization_test.rb
  203. +5 −5 activesupport/test/core_ext/module_test.rb
  204. +2 −2 activesupport/test/core_ext/object_and_class_ext_test.rb
  205. +18 −0 activesupport/test/core_ext/string_ext_test.rb
  206. +1 −1 activesupport/test/core_ext/time_with_zone_test.rb
  207. +11 −11 activesupport/test/dependencies_test.rb
  208. +10 −4 activesupport/test/inflector_test.rb
  209. +16 −0 activesupport/test/inflector_test_cases.rb
  210. +6 −2 activesupport/test/json/decoding_test.rb
  211. +1 −1 activesupport/test/json/encoding_test.rb
  212. +22 −1 activesupport/test/memoizable_test.rb
  213. +1 −1 activesupport/test/message_encryptor_test.rb
  214. +1 −1 activesupport/test/message_verifier_test.rb
  215. +26 −22 activesupport/test/multibyte_chars_test.rb
  216. +12 −2 activesupport/test/ordered_hash_test.rb
  217. +1 −1 activesupport/test/string_inquirer_test.rb
  218. +1 −1 activesupport/test/time_zone_test.rb
  219. +157 −0 activesupport/test/xml_mini/nokogiri_engine_test.rb
  220. +15 −0 activesupport/test/xml_mini/rexml_engine_test.rb
  221. +5 −1 railties/CHANGELOG
  222. +14 −9 railties/Rakefile
  223. +4 −0 railties/builtin/rails_info/rails/info.rb
  224. +1 −0 railties/environments/boot.rb
  225. BIN railties/guides/images/error_messages.png
  226. BIN railties/guides/images/fxn.jpg
  227. +1 −0 railties/guides/rails_guides.rb
  228. +22 −4 railties/guides/rails_guides/generator.rb
  229. +1 −1 railties/guides/rails_guides/indexer.rb
  230. +29 −0 railties/guides/rails_guides/levenshtein.rb
  231. +79 −35 railties/guides/source/2_3_release_notes.textile
  232. +16 −16 railties/guides/source/action_controller_overview.textile
  233. +17 −13 railties/guides/source/action_mailer_basics.textile
  234. +4 −4 railties/guides/source/active_record_basics.textile
  235. +119 −52 railties/guides/source/active_record_querying.textile
  236. +123 −111 railties/guides/source/activerecord_validations_callbacks.textile
  237. +40 −40 railties/guides/source/association_basics.textile
  238. +79 −71 railties/guides/source/caching_with_rails.textile
  239. +23 −20 railties/guides/source/command_line.textile
  240. +8 −14 railties/guides/source/contribute.textile
  241. +23 −10 railties/guides/source/credits.erb.textile
  242. +6 −6 railties/guides/source/debugging_rails_applications.textile
  243. +27 −27 railties/guides/source/form_helpers.textile
  244. +6 −6 railties/guides/source/getting_started.textile
  245. +108 −108 railties/guides/source/i18n.textile
  246. +3 −3 railties/guides/source/index.erb.textile
  247. +9 −9 railties/guides/source/layout.html.erb
  248. +39 −25 railties/guides/source/layouts_and_rendering.textile
  249. +23 −23 railties/guides/source/migrations.textile
  250. +222 −0 railties/guides/source/nested_model_forms.textile
  251. +28 −28 railties/guides/source/performance_testing.textile
  252. +17 −17 railties/guides/source/plugins.textile
  253. +4 −4 railties/guides/source/rails_on_rack.textile
  254. +17 −17 railties/guides/source/routing.textile
  255. +35 −37 railties/guides/source/security.textile
  256. +15 −15 railties/guides/source/testing.textile
  257. +4 −3 railties/lib/commands/plugin.rb
  258. +1 −0 railties/lib/console_app.rb
  259. +26 −2 railties/lib/initializer.rb
  260. +19 −4 railties/lib/rails/backtrace_cleaner.rb
  261. +124 −94 railties/lib/rails/gem_dependency.rb
  262. +6 −2 railties/lib/rails/plugin.rb
  263. +5 −2 railties/lib/rails/plugin/loader.rb
  264. +21 −6 railties/lib/rails/rack/metal.rb
  265. +13 −4 railties/lib/rails/rack/static.rb
  266. +1 −1 railties/lib/rails/version.rb
  267. +6 −2 railties/lib/rails_generator/commands.rb
  268. +26 −6 railties/lib/rails_generator/generators/applications/app/template_runner.rb
  269. +32 −47 railties/lib/tasks/gems.rake
  270. +1 −1 railties/lib/tasks/testing.rake
  271. +2 −0 railties/test/abstract_unit.rb
  272. +49 −16 railties/test/backtrace_cleaner_test.rb
  273. +2 −0 railties/test/boot_test.rb
  274. +22 −20 railties/test/console_app_test.rb
  275. +5 −0 railties/test/fixtures/metal/multiplemetals/app/metal/metal_a.rb
  276. +5 −0 railties/test/fixtures/metal/multiplemetals/app/metal/metal_b.rb
  277. +5 −0 railties/test/fixtures/metal/pluralmetal/app/metal/legacy_routes.rb
  278. +5 −0 railties/test/fixtures/metal/singlemetal/app/metal/foo_metal.rb
  279. +7 −0 railties/test/fixtures/metal/subfolders/app/metal/Folder/metal_a.rb
  280. +7 −0 railties/test/fixtures/metal/subfolders/app/metal/Folder/metal_b.rb
  281. +10 −0 railties/test/fixtures/plugins/engines/engine/app/metal/engine_metal.rb
  282. +1 −1 railties/test/fixtures/plugins/engines/engine/init.rb
  283. +1 −0 railties/test/fixtures/public/foo/bar.html
  284. +1 −0 railties/test/fixtures/public/foo/index.html
  285. +1 −0 railties/test/fixtures/public/index.html
  286. +10 −7 railties/test/gem_dependency_test.rb
  287. +16 −0 railties/test/generators/rails_template_runner_test.rb
  288. +73 −10 railties/test/initializer_test.rb
  289. +72 −0 railties/test/metal_test.rb
  290. +2 −2 railties/test/plugin_loader_test.rb
  291. +1 −1 railties/test/plugin_locator_test.rb
  292. +6 −6 railties/test/plugin_test.rb
  293. +46 −0 railties/test/rack_static_test.rb
  294. +1 −1 railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification
View
5 actionmailer/CHANGELOG
@@ -1,10 +1,7 @@
-*Edge*
+*2.3.2 [Final] (March 15, 2009)*
* Fixed that ActionMailer should send correctly formatted Return-Path in MAIL FROM for SMTP #1842 [Matt Jones]
-
-*2.3.0 [RC1] (February 1st, 2009)*
-
* Fixed RFC-2045 quoted-printable bug #1421 [squadette]
* Fixed that no body charset would be set when there are attachments present #740 [Paweł Kondzior]
View
2 actionmailer/Rakefile
@@ -55,7 +55,7 @@ spec = Gem::Specification.new do |s|
s.rubyforge_project = "actionmailer"
s.homepage = "http://www.rubyonrails.org"
- s.add_dependency('actionpack', '= 2.3.0' + PKG_BUILD)
+ s.add_dependency('actionpack', '= 2.3.2' + PKG_BUILD)
s.has_rdoc = true
s.requirements << 'none'
View
3 actionmailer/lib/action_mailer.rb
@@ -58,4 +58,5 @@ module Net
end
autoload :MailHelper, 'action_mailer/mail_helper'
-autoload :TMail, 'action_mailer/vendor/tmail'
+
+require 'action_mailer/vendor/tmail'
View
2 actionmailer/lib/action_mailer/base.rb
@@ -479,7 +479,7 @@ def create!(method_name, *parameters) #:nodoc:
)
end
unless @parts.empty?
- @content_type = "multipart/alternative"
+ @content_type = "multipart/alternative" if @content_type !~ /^multipart/
@parts = sort_parts(@parts, @implicit_parts_order)
end
end
View
5 actionmailer/lib/action_mailer/part.rb
@@ -88,7 +88,10 @@ def to_mail(defaults)
part.parts << prt
end
- part.set_content_type(real_content_type, nil, ctype_attrs) if real_content_type =~ /multipart/
+ if real_content_type =~ /multipart/
+ ctype_attrs.delete 'charset'
+ part.set_content_type(real_content_type, nil, ctype_attrs)
+ end
end
headers.each { |k,v| part[k] = v }
View
2 actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb
@@ -1150,7 +1150,7 @@ def test_format_style
assert_equal(Text::Format::JUSTIFY, @format_o.format_style)
assert_match(/^of freedom, and that government of the people, by the people, for the$/,
@format_o.format(GETTYSBURG).split("\n")[-3])
- assert_raises(ArgumentError) { @format_o.format_style = 33 }
+ assert_raise(ArgumentError) { @format_o.format_style = 33 }
end
def test_tag_paragraph
View
2 actionmailer/lib/action_mailer/version.rb
@@ -2,7 +2,7 @@ module ActionMailer
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
- TINY = 0
+ TINY = 2
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
30 actionmailer/test/mail_layout_test.rb
@@ -21,10 +21,12 @@ def nolayout(recipient)
body render(:inline => "Hello, <%= @world %>", :layout => false, :body => { :world => "Earth" })
end
- def multipart(recipient)
+ def multipart(recipient, type = nil)
recipients recipient
subject "You have a mail"
from "tester@example.com"
+
+ content_type(type) if type
end
end
@@ -64,6 +66,19 @@ def test_should_pickup_default_layout
def test_should_pickup_multipart_layout
mail = AutoLayoutMailer.create_multipart(@recipient)
+ assert_equal "multipart/alternative", mail.content_type
+ assert_equal 2, mail.parts.size
+
+ assert_equal 'text/plain', mail.parts.first.content_type
+ assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body
+
+ assert_equal 'text/html', mail.parts.last.content_type
+ assert_equal "Hello from layout text/html multipart", mail.parts.last.body
+ end
+
+ def test_should_pickup_multipartmixed_layout
+ mail = AutoLayoutMailer.create_multipart(@recipient, "multipart/mixed")
+ assert_equal "multipart/mixed", mail.content_type
assert_equal 2, mail.parts.size
assert_equal 'text/plain', mail.parts.first.content_type
@@ -73,6 +88,19 @@ def test_should_pickup_multipart_layout
assert_equal "Hello from layout text/html multipart", mail.parts.last.body
end
+ def test_should_fix_multipart_layout
+ mail = AutoLayoutMailer.create_multipart(@recipient, "text/plain")
+ assert_equal "multipart/alternative", mail.content_type
+ assert_equal 2, mail.parts.size
+
+ assert_equal 'text/plain', mail.parts.first.content_type
+ assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body
+
+ assert_equal 'text/html', mail.parts.last.content_type
+ assert_equal "Hello from layout text/html multipart", mail.parts.last.body
+ end
+
+
def test_should_pickup_layout_given_to_render
mail = AutoLayoutMailer.create_spam(@recipient)
assert_equal "Spammer layout Hello, Earth", mail.body.strip
View
3 actionmailer/test/mail_service_test.rb
@@ -330,6 +330,7 @@ def test_nested_parts
assert_equal "multipart/mixed", created.content_type
assert_equal "multipart/alternative", created.parts.first.content_type
assert_equal "bar", created.parts.first.header['foo'].to_s
+ assert_nil created.parts.first.charset
assert_equal "text/plain", created.parts.first.parts.first.content_type
assert_equal "text/html", created.parts.first.parts[1].content_type
assert_equal "application/octet-stream", created.parts[1].content_type
@@ -1068,7 +1069,7 @@ def test_should_not_respond_to_method_where_deliver_is_not_a_suffix
end
def test_should_still_raise_exception_with_expected_message_when_calling_an_undefined_method
- error = assert_raises NoMethodError do
+ error = assert_raise NoMethodError do
RespondToMailer.not_a_method
end
View
8 actionmailer/test/test_helper_test.rb
@@ -26,7 +26,7 @@ def test_mailer_class_is_correctly_inferred
end
def test_determine_default_mailer_raises_correct_error
- assert_raises(ActionMailer::NonInferrableMailerError) do
+ assert_raise(ActionMailer::NonInferrableMailerError) do
self.class.determine_default_mailer("NotAMailerTest")
end
end
@@ -84,7 +84,7 @@ def test_assert_no_emails
end
def test_assert_emails_too_few_sent
- error = assert_raises ActiveSupport::TestCase::Assertion do
+ error = assert_raise ActiveSupport::TestCase::Assertion do
assert_emails 2 do
TestHelperMailer.deliver_test
end
@@ -94,7 +94,7 @@ def test_assert_emails_too_few_sent
end
def test_assert_emails_too_many_sent
- error = assert_raises ActiveSupport::TestCase::Assertion do
+ error = assert_raise ActiveSupport::TestCase::Assertion do
assert_emails 1 do
TestHelperMailer.deliver_test
TestHelperMailer.deliver_test
@@ -105,7 +105,7 @@ def test_assert_emails_too_many_sent
end
def test_assert_no_emails_failure
- error = assert_raises ActiveSupport::TestCase::Assertion do
+ error = assert_raise ActiveSupport::TestCase::Assertion do
assert_no_emails do
TestHelperMailer.deliver_test
end
View
13 actionpack/CHANGELOG
@@ -1,14 +1,19 @@
-*Edge*
+*2.3.2 [Final] (March 15, 2009)*
+
+* Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #<Post:0x23150b8>") [DHH]
+
+* Added ability to pass in :public => true to fresh_when, stale?, and expires_in to make the request proxy cachable #2095 [Gregg Pollack]
+
+* Fixed that passing a custom form builder would be forwarded to nested fields_for calls #2023 [Eloy Duran/Nate Wiger]
+
+* Form option helpers now support disabled option tags and the use of lambdas for selecting/disabling option tags from collections #837 [Tekin]
* Added partial scoping to TranslationHelper#translate, so if you call translate(".foo") from the people/index.html.erb template, you'll actually be calling I18n.translate("people.index.foo") [DHH]
* Fix a syntax error in current_page?() that was prevent matches against URL's with multiple query parameters #1385, #1868 [chris finne/Andrew White]
* Added localized rescue template when I18n.locale is set (ex: public/404.da.html) #1835 [José Valim]
-
-*2.3.0 [RC1] (February 1st, 2009)*
-
* Make the form_for and fields_for helpers support the new Active Record nested update options. #1202 [Eloy Duran]
<% form_for @person do |person_form| %>
View
3 actionpack/Rakefile
@@ -80,8 +80,7 @@ spec = Gem::Specification.new do |s|
s.has_rdoc = true
s.requirements << 'none'
- s.add_dependency('activesupport', '= 2.3.0' + PKG_BUILD)
- s.add_dependency('rack', '>= 0.9.0')
+ s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)
s.require_path = 'lib'
s.autorequire = 'action_controller'
View
7 actionpack/lib/action_controller.rb
@@ -31,7 +31,12 @@
end
end
-require 'action_controller/vendor/rack-1.0/rack'
+begin
+ gem 'rack', '~> 1.0.0'
+ require 'rack'
+rescue Gem::LoadError
+ require 'action_controller/vendor/rack-1.0/rack'
+end
module ActionController
# TODO: Review explicit to see if they will automatically be handled by
View
54 actionpack/lib/action_controller/base.rb
@@ -22,7 +22,7 @@ class MethodNotAllowed < ActionControllerError #:nodoc:
attr_reader :allowed_methods
def initialize(*allowed_methods)
- super("Only #{allowed_methods.to_sentence} requests are allowed.")
+ super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.")
@allowed_methods = allowed_methods
end
@@ -908,12 +908,14 @@ def render(options = nil, extra_options = {}, &block) #:doc:
end
options = extra_options
+ elsif !options.is_a?(Hash)
+ extra_options[:partial] = options
+ options = extra_options
end
layout = pick_layout(options)
response.layout = layout.path_without_format_and_extension if layout
logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger && layout
- layout = layout.path_without_format_and_extension if layout
if content_type = options[:content_type]
response.content_type = content_type.to_s
@@ -1101,7 +1103,6 @@ def redirect_to(options = {}, response_status = {}) #:doc:
end
response.redirected_to = options
- logger.info("Redirected to #{options}") if logger && logger.info?
case options
# The scheme name consist of a letter followed by any combination of
@@ -1124,6 +1125,7 @@ def redirect_to(options = {}, response_status = {}) #:doc:
def redirect_to_full_url(url, status)
raise DoubleRenderError if performed?
+ logger.info("Redirected to #{url}") if logger && logger.info?
response.redirect(url, interpret_status(status))
@performed_redirect = true
end
@@ -1133,6 +1135,11 @@ def redirect_to_full_url(url, status)
# request is considered stale and should be generated from scratch. Otherwise,
# it's fresh and we don't need to generate anything and a reply of "304 Not Modified" is sent.
#
+ # Parameters:
+ # * <tt>:etag</tt>
+ # * <tt>:last_modified</tt>
+ # * <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).
+ #
# Example:
#
# def show
@@ -1153,20 +1160,34 @@ def stale?(options)
# Sets the etag, last_modified, or both on the response and renders a
# "304 Not Modified" response if the request is already fresh.
#
+ # Parameters:
+ # * <tt>:etag</tt>
+ # * <tt>:last_modified</tt>
+ # * <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).
+ #
# Example:
#
# def show
# @article = Article.find(params[:id])
- # fresh_when(:etag => @article, :last_modified => @article.created_at.utc)
+ # fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
# end
#
# This will render the show template if the request isn't sending a matching etag or
# If-Modified-Since header and just a "304 Not Modified" response if there's a match.
+ #
def fresh_when(options)
- options.assert_valid_keys(:etag, :last_modified)
+ options.assert_valid_keys(:etag, :last_modified, :public)
response.etag = options[:etag] if options[:etag]
response.last_modified = options[:last_modified] if options[:last_modified]
+
+ if options[:public]
+ cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
+ cache_control.delete("private")
+ cache_control.delete("no-cache")
+ cache_control << "public"
+ response.headers["Cache-Control"] = cache_control.join(', ')
+ end
if request.fresh?(response)
head :not_modified
@@ -1178,15 +1199,26 @@ def fresh_when(options)
#
# Examples:
# expires_in 20.minutes
- # expires_in 3.hours, :private => false
- # expires in 3.hours, 'max-stale' => 5.hours, :private => nil, :public => true
+ # expires_in 3.hours, :public => true
+ # expires in 3.hours, 'max-stale' => 5.hours, :public => true
#
# This method will overwrite an existing Cache-Control header.
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
def expires_in(seconds, options = {}) #:doc:
- cache_options = { 'max-age' => seconds, 'private' => true }.symbolize_keys.merge!(options.symbolize_keys)
- cache_options.delete_if { |k,v| v.nil? or v == false }
- cache_control = cache_options.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
+ cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
+
+ cache_control << "max-age=#{seconds}"
+ cache_control.delete("no-cache")
+ if options[:public]
+ cache_control.delete("private")
+ cache_control << "public"
+ else
+ cache_control << "private"
+ end
+
+ # This allows for additional headers to be passed through like 'max-stale' => 5.hours
+ 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}"}
+
response.headers["Cache-Control"] = cache_control.join(', ')
end
@@ -1298,7 +1330,7 @@ def perform_action
rescue ActionView::MissingTemplate => e
# Was the implicit template missing, or was it another template?
if e.path == default_template_name
- raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}", caller
+ raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence(:locale => :en)}", caller
else
raise e
end
View
27 actionpack/lib/action_controller/caching/actions.rb
@@ -129,24 +129,23 @@ class ActionCachePath
attr_reader :path, :extension
class << self
- def path_for(controller, options, infer_extension=true)
+ def path_for(controller, options, infer_extension = true)
new(controller, options, infer_extension).path
end
end
# When true, infer_extension will look up the cache path extension from the request's path & format.
- # This is desirable when reading and writing the cache, but not when expiring the cache - expire_action should expire the same files regardless of the request format.
- def initialize(controller, options = {}, infer_extension=true)
- if infer_extension and options.is_a? Hash
- request_extension = extract_extension(controller.request)
- options = options.reverse_merge(:format => request_extension)
+ # This is desirable when reading and writing the cache, but not when expiring the cache -
+ # expire_action should expire the same files regardless of the request format.
+ def initialize(controller, options = {}, infer_extension = true)
+ if infer_extension
+ extract_extension(controller.request)
+ options = options.reverse_merge(:format => @extension) if options.is_a?(Hash)
end
+
path = controller.url_for(options).split('://').last
normalize!(path)
- if infer_extension
- @extension = request_extension
- add_extension!(path, @extension)
- end
+ add_extension!(path, @extension)
@path = URI.unescape(path)
end
@@ -162,13 +161,7 @@ def add_extension!(path, extension)
def extract_extension(request)
# Don't want just what comes after the last '.' to accommodate multi part extensions
# such as tar.gz.
- extension = request.path[/^[^.]+\.(.+)$/, 1]
-
- # If there's no extension in the path, check request.format
- if extension.nil?
- extension = request.cache_format
- end
- extension
+ @extension = request.path[/^[^.]+\.(.+)$/, 1] || request.cache_format
end
end
end
View
7 actionpack/lib/action_controller/dispatcher.rb
@@ -13,7 +13,6 @@ def define_dispatcher_callbacks(cache_classes)
end
if defined?(ActiveRecord)
- after_dispatch :checkin_connections
to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
end
@@ -115,11 +114,5 @@ def _call(env)
def flush_logger
Base.logger.flush
end
-
- def checkin_connections
- # Don't return connection (and peform implicit rollback) if this request is a part of integration test
- return if @env.key?("rack.test")
- ActiveRecord::Base.clear_active_connections!
- end
end
end
View
72 actionpack/lib/action_controller/http_authentication.rb
@@ -68,8 +68,11 @@ module HttpAuthentication
#
# Simple Digest example:
#
+ # require 'digest/md5'
# class PostsController < ApplicationController
- # USERS = {"dhh" => "secret"}
+ # REALM = "SuperSecret"
+ # USERS = {"dhh" => "secret", #plain text password
+ # "dap" => Digest:MD5::hexdigest(["dap",REALM,"secret"].join(":")) #ha1 digest password
#
# before_filter :authenticate, :except => [:index]
#
@@ -83,14 +86,18 @@ module HttpAuthentication
#
# private
# def authenticate
- # authenticate_or_request_with_http_digest(realm) do |username|
+ # authenticate_or_request_with_http_digest(REALM) do |username|
# USERS[username]
# end
# end
# end
#
- # NOTE: The +authenticate_or_request_with_http_digest+ block must return the user's password so the framework can appropriately
- # hash it to check the user's credentials. Returning +nil+ will cause authentication to fail.
+ # NOTE: The +authenticate_or_request_with_http_digest+ block must return the user's password or the ha1 digest hash so the framework can appropriately
+ # hash to check the user's credentials. Returning +nil+ will cause authentication to fail.
+ # Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If
+ # the password file or database is compromised, the attacker would be able to use the ha1 hash to
+ # authenticate as the user at this +realm+, but would not have the user's password to try using at
+ # other sites.
#
# On shared hosts, Apache sometimes doesn't pass authentication headers to
# FCGI instances. If your environment matches this description and you cannot
@@ -177,26 +184,37 @@ def authorization(request)
end
# Raises error unless the request credentials response value matches the expected value.
+ # First try the password as a ha1 digest password. If this fails, then try it as a plain
+ # text password.
def validate_digest_response(request, realm, &password_procedure)
credentials = decode_credentials_header(request)
valid_nonce = validate_nonce(request, credentials[:nonce])
- if valid_nonce && realm == credentials[:realm] && opaque(request.session.session_id) == credentials[:opaque]
+ if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque]
password = password_procedure.call(credentials[:username])
- expected = expected_response(request.env['REQUEST_METHOD'], credentials[:uri], credentials, password)
- expected == credentials[:response]
+
+ [true, false].any? do |password_is_ha1|
+ expected = expected_response(request.env['REQUEST_METHOD'], request.env['REQUEST_URI'], credentials, password, password_is_ha1)
+ expected == credentials[:response]
+ end
end
end
# Returns the expected response for a request of +http_method+ to +uri+ with the decoded +credentials+ and the expected +password+
- def expected_response(http_method, uri, credentials, password)
- ha1 = ::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(':'))
+ # Optional parameter +password_is_ha1+ is set to +true+ by default, since best practice is to store ha1 digest instead
+ # of a plain-text password.
+ def expected_response(http_method, uri, credentials, password, password_is_ha1=true)
+ ha1 = password_is_ha1 ? password : ha1(credentials, password)
ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(':'))
::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(':'))
end
- def encode_credentials(http_method, credentials, password)
- credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password)
+ def ha1(credentials, password)
+ ::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(':'))
+ end
+
+ def encode_credentials(http_method, credentials, password, password_is_ha1)
+ credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password, password_is_ha1)
"Digest " + credentials.sort_by {|x| x[0].to_s }.inject([]) {|a, v| a << "#{v[0]}='#{v[1]}'" }.join(', ')
end
@@ -213,8 +231,7 @@ def decode_credentials(header)
end
def authentication_header(controller, realm)
- session_id = controller.request.session.session_id
- controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce(session_id)}", opaque="#{opaque(session_id)}")
+ controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}")
end
def authentication_request(controller, realm, message = nil)
@@ -252,23 +269,36 @@ def authentication_request(controller, realm, message = nil)
# POST or PUT requests and a time-stamp for GET requests. For more details on the issues involved see Section 4
# of this document.
#
- # The nonce is opaque to the client.
- def nonce(session_id, time = Time.now)
+ # The nonce is opaque to the client. Composed of Time, and hash of Time with secret
+ # key from the Rails session secret generated upon creation of project. Ensures
+ # the time cannot be modifed by client.
+ def nonce(time = Time.now)
t = time.to_i
- hashed = [t, session_id]
+ hashed = [t, secret_key]
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
Base64.encode64("#{t}:#{digest}").gsub("\n", '')
end
- def validate_nonce(request, value)
+ # Might want a shorter timeout depending on whether the request
+ # is a PUT or POST, and if client is browser or web service.
+ # Can be much shorter if the Stale directive is implemented. This would
+ # allow a user to use new nonce without prompting user again for their
+ # username and password.
+ def validate_nonce(request, value, seconds_to_timeout=5*60)
t = Base64.decode64(value).split(":").first.to_i
- nonce(request.session.session_id, t) == value && (t - Time.now.to_i).abs <= 10 * 60
+ nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
end
- # Opaque based on digest of session_id
- def opaque(session_id)
- Base64.encode64(::Digest::MD5::hexdigest(session_id)).gsub("\n", '')
+ # Opaque based on random generation - but changing each request?
+ def opaque()
+ ::Digest::MD5.hexdigest(secret_key)
end
+
+ # Set in /initializers/session_store.rb, and loaded even if sessions are not in use.
+ def secret_key
+ ActionController::Base.session_options[:secret]
+ end
+
end
end
end
View
25 actionpack/lib/action_controller/layout.rb
@@ -198,7 +198,7 @@ def normalize_conditions(conditions)
# is called and the return value is used. Likewise if the layout was specified as an inline method (through a proc or method
# object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
# weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
- def active_layout(passed_layout = nil)
+ def active_layout(passed_layout = nil, options = {})
layout = passed_layout || default_layout
return layout if layout.respond_to?(:render)
@@ -207,21 +207,23 @@ def active_layout(passed_layout = nil)
when Proc then layout.call(self)
else layout
end
-
- find_layout(active_layout, @template.template_format) if active_layout
+
+ find_layout(active_layout, default_template_format, options[:html_fallback]) if active_layout
end
private
def default_layout #:nodoc:
- layout = self.class.read_inheritable_attribute(:layout) unless default_template_format == :js
+ layout = self.class.read_inheritable_attribute(:layout)
return layout unless self.class.read_inheritable_attribute(:auto_layout)
find_layout(layout, default_template_format)
rescue ActionView::MissingTemplate
nil
end
- def find_layout(layout, *formats) #:nodoc:
- view_paths.find_template(layout.to_s =~ /layouts\// ? layout : "layouts/#{layout}", *formats)
+ def find_layout(layout, format, html_fallback=false) #:nodoc:
+ view_paths.find_template(layout.to_s =~ /layouts\// ? layout : "layouts/#{layout}", format, html_fallback)
+ rescue ActionView::MissingTemplate
+ raise if Mime::Type.lookup_by_extension(format.to_s).html?
end
def pick_layout(options)
@@ -232,7 +234,7 @@ def pick_layout(options)
when NilClass, TrueClass
active_layout if action_has_layout? && candidate_for_layout?(:template => default_template_name)
else
- active_layout(layout)
+ active_layout(layout, :html_fallback => true)
end
else
active_layout if action_has_layout? && candidate_for_layout?(options)
@@ -258,7 +260,12 @@ def candidate_for_layout?(options)
template = options[:template] || default_template(options[:action])
if options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty?
begin
- !self.view_paths.find_template(template, default_template_format).exempt_from_layout?
+ template_object = self.view_paths.find_template(template, default_template_format)
+ # this restores the behavior from 2.2.2, where response.template.template_format was reset
+ # to :html for :js requests with a matching html template.
+ # see v2.2.2, ActionView::Base, lines 328-330
+ @real_format = :html if response.template.template_format == :js && template_object.format == "html"
+ !template_object.exempt_from_layout?
rescue ActionView::MissingTemplate
true
end
@@ -268,7 +275,7 @@ def candidate_for_layout?(options)
end
def default_template_format
- response.template.template_format
+ @real_format || response.template.template_format
end
end
end
View
7 actionpack/lib/action_controller/polymorphic_routes.rb
@@ -163,15 +163,18 @@ def build_named_route_call(records, namespace, inflection, options = {})
if parent.is_a?(Symbol) || parent.is_a?(String)
string << "#{parent}_"
else
- string << "#{RecordIdentifier.__send__("singular_class_name", parent)}_"
+ string << "#{RecordIdentifier.__send__("plural_class_name", parent)}".singularize
+ string << "_"
end
end
end
if record.is_a?(Symbol) || record.is_a?(String)
route << "#{record}_"
else
- route << "#{RecordIdentifier.__send__("#{inflection}_class_name", record)}_"
+ route << "#{RecordIdentifier.__send__("plural_class_name", record)}"
+ route = route.singularize if inflection == :singular
+ route << "_"
end
action_prefix(options) + namespace + route + routing_type(options).to_s
View
3 actionpack/lib/action_controller/request.rb
@@ -32,7 +32,7 @@ def key?(key)
# <tt>:get</tt>. If the request \method is not listed in the HTTP_METHODS
# constant above, an UnknownHttpMethod exception is raised.
def request_method
- @request_method ||= HTTP_METHOD_LOOKUP[super] || raise(UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence}")
+ @request_method ||= HTTP_METHOD_LOOKUP[super] || raise(UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
end
# Returns the HTTP request \method used for action processing as a
@@ -442,6 +442,7 @@ def session=(session) #:nodoc:
end
def reset_session
+ @env['rack.session.options'].delete(:id)
@env['rack.session'] = {}
end
View
15 actionpack/lib/action_controller/resources.rb
@@ -91,7 +91,7 @@ def new_path
end
def shallow_path_prefix
- @shallow_path_prefix ||= "#{path_prefix unless @options[:shallow]}"
+ @shallow_path_prefix ||= @options[:shallow] ? @options[:namespace].try(:sub, /\/$/, '') : path_prefix
end
def member_path
@@ -103,7 +103,7 @@ def nesting_path_prefix
end
def shallow_name_prefix
- @shallow_name_prefix ||= "#{name_prefix unless @options[:shallow]}"
+ @shallow_name_prefix ||= @options[:shallow] ? @options[:namespace].try(:gsub, /\//, '_') : name_prefix
end
def nesting_name_prefix
@@ -630,7 +630,7 @@ def map_member_actions(map, resource)
action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
action_path ||= Base.resources_path_names[action] || action
- map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m)
+ map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m, { :force_id => true })
end
end
end
@@ -641,9 +641,9 @@ def map_member_actions(map, resource)
map_resource_routes(map, resource, :destroy, resource.member_path, route_path)
end
- def map_resource_routes(map, resource, action, route_path, route_name = nil, method = nil)
+ def map_resource_routes(map, resource, action, route_path, route_name = nil, method = nil, resource_options = {} )
if resource.has_action?(action)
- action_options = action_options_for(action, resource, method)
+ action_options = action_options_for(action, resource, method, resource_options)
formatted_route_path = "#{route_path}.:format"
if route_name && @set.named_routes[route_name.to_sym].nil?
@@ -660,17 +660,18 @@ def add_conditions_for(conditions, method)
end
end
- def action_options_for(action, resource, method = nil)
+ def action_options_for(action, resource, method = nil, resource_options = {})
default_options = { :action => action.to_s }
require_id = !resource.kind_of?(SingletonResource)
+ force_id = resource_options[:force_id] && !resource.kind_of?(SingletonResource)
case default_options[:action]
when "index", "new"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements)
when "create"; default_options.merge(add_conditions_for(resource.conditions, method || :post)).merge(resource.requirements)
when "show", "edit"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements(require_id))
when "update"; default_options.merge(add_conditions_for(resource.conditions, method || :put)).merge(resource.requirements(require_id))
when "destroy"; default_options.merge(add_conditions_for(resource.conditions, method || :delete)).merge(resource.requirements(require_id))
- else default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements)
+ else default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements(force_id))
end
end
end
View
2 actionpack/lib/action_controller/routing.rb
@@ -267,7 +267,7 @@ module ActionController
module Routing
SEPARATORS = %w( / . ? )
- HTTP_METHODS = [:get, :head, :post, :put, :delete]
+ HTTP_METHODS = [:get, :head, :post, :put, :delete, :options]
ALLOWED_REQUIREMENTS_FOR_OPTIMISATION = [:controller, :action].to_set
View
3 actionpack/lib/action_controller/routing/builder.rb
@@ -159,7 +159,8 @@ def build(path, options)
path = "/#{path}" unless path[0] == ?/
path = "#{path}/" unless path[-1] == ?/
- path = "/#{options[:path_prefix].to_s.gsub(/^\//,'')}#{path}" if options[:path_prefix]
+ prefix = options[:path_prefix].to_s.gsub(/^\//,'')
+ path = "/#{prefix}#{path}" unless prefix.blank?
segments = segments_for_route_path(path)
defaults, requirements, conditions = divide_route_options(segments, options)
View
1 actionpack/lib/action_controller/routing/recognition_optimisation.rb
@@ -98,7 +98,6 @@ def generate_code(list, padding=' ', level = 0)
if Array === item
i += 1
start = (i == 1)
- final = (i == list.size)
tag, sub = item
if tag == :dynamic
body += padding + "#{start ? 'if' : 'elsif'} true\n"
View
14 actionpack/lib/action_controller/routing/segments.rb
@@ -3,7 +3,11 @@ module Routing
class Segment #:nodoc:
RESERVED_PCHAR = ':@&=+$,;'
SAFE_PCHAR = "#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}"
- UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false, 'N').freeze
+ if RUBY_VERSION >= '1.9'
+ UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false).freeze
+ else
+ UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false, 'N').freeze
+ end
# TODO: Convert :is_optional accessor to read only
attr_accessor :is_optional
@@ -314,13 +318,17 @@ def interpolation_chunk
end
def regexp_chunk
- '(\.[^/?\.]+)?'
+ '/|(\.[^/?\.]+)?'
end
def to_s
'(.:format)?'
end
-
+
+ def extract_value
+ "#{local_name} = options[:#{key}] && options[:#{key}].to_s.downcase"
+ end
+
#the value should not include the period (.)
def match_extraction(next_capture)
%[
View
2 actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
@@ -556,7 +556,7 @@ def simple_selector(statement, values, can_negate = true)
end
# Attribute value.
- next if statement.sub!(/^\[\s*([[:alpha:]][\w\-]*)\s*((?:[~|^$*])?=)?\s*('[^']*'|"[^*]"|[^\]]*)\s*\]/) do |match|
+ next if statement.sub!(/^\[\s*([[:alpha:]][\w\-:]*)\s*((?:[~|^$*])?=)?\s*('[^']*'|"[^*]"|[^\]]*)\s*\]/) do |match|
name, equality, value = $1, $2, $3
if value == "?"
value = values.shift
View
4 actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
@@ -23,14 +23,16 @@ def self.version
# Return the Rack release as a dotted string.
def self.release
- "0.4"
+ "1.0 bundled"
end
autoload :Builder, "rack/builder"
autoload :Cascade, "rack/cascade"
+ autoload :Chunked, "rack/chunked"
autoload :CommonLogger, "rack/commonlogger"
autoload :ConditionalGet, "rack/conditionalget"
autoload :ContentLength, "rack/content_length"
+ autoload :ContentType, "rack/content_type"
autoload :File, "rack/file"
autoload :Deflater, "rack/deflater"
autoload :Directory, "rack/directory"
View
4 actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb
@@ -8,8 +8,8 @@ class AbstractHandler
attr_accessor :realm
- def initialize(app, &authenticator)
- @app, @authenticator = app, authenticator
+ def initialize(app, realm=nil, &authenticator)
+ @app, @realm, @authenticator = app, realm, authenticator
end
View
2 actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb
@@ -21,7 +21,7 @@ class MD5 < AbstractHandler
attr_writer :passwords_hashed
- def initialize(app)
+ def initialize(*args)
super
@passwords_hashed = nil
end
View
2 actionpack/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb
@@ -8,7 +8,7 @@ module Digest
class Request < Auth::AbstractRequest
def method
- @env['REQUEST_METHOD']
+ @env['rack.methodoverride.original_method'] || @env['REQUEST_METHOD']
end
def digest?
View
6 actionpack/lib/action_controller/vendor/rack-1.0/rack/builder.rb
@@ -34,11 +34,7 @@ def self.app(&block)
end
def use(middleware, *args, &block)
- @ins << if block_given?
- lambda { |app| middleware.new(app, *args, &block) }
- else
- lambda { |app| middleware.new(app, *args) }
- end
+ @ins << lambda { |app| middleware.new(app, *args, &block) }
end
def run(app)
View
49 actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
@@ -0,0 +1,49 @@
+require 'rack/utils'
+
+module Rack
+
+ # Middleware that applies chunked transfer encoding to response bodies
+ # when the response does not include a Content-Length header.
+ class Chunked
+ include Rack::Utils
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ status, headers, body = @app.call(env)
+ headers = HeaderHash.new(headers)
+
+ if env['HTTP_VERSION'] == 'HTTP/1.0' ||
+ STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
+ headers['Content-Length'] ||
+ headers['Transfer-Encoding']
+ [status, headers.to_hash, body]
+ else
+ dup.chunk(status, headers, body)
+ end
+ end
+
+ def chunk(status, headers, body)
+ @body = body
+ headers.delete('Content-Length')
+ headers['Transfer-Encoding'] = 'chunked'
+ [status, headers.to_hash, self]
+ end
+
+ def each
+ term = "\r\n"
+ @body.each do |chunk|
+ size = bytesize(chunk)
+ next if size == 0
+ yield [size.to_s(16), term, chunk, term].join
+ end
+ yield ["0", term, "", term].join
+ end
+
+ def close
+ @body.close if @body.respond_to?(:close)
+ end
+ end
+end
View
8 actionpack/lib/action_controller/vendor/rack-1.0/rack/content_length.rb
@@ -3,21 +3,23 @@
module Rack
# Sets the Content-Length header on responses with fixed-length bodies.
class ContentLength
+ include Rack::Utils
+
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
- headers = Utils::HeaderHash.new(headers)
+ headers = HeaderHash.new(headers)
- if !Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
+ if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
!headers['Content-Length'] &&
!headers['Transfer-Encoding'] &&
(body.respond_to?(:to_ary) || body.respond_to?(:to_str))
body = [body] if body.respond_to?(:to_str) # rack 0.4 compat
- length = body.to_ary.inject(0) { |len, part| len + part.length }
+ length = body.to_ary.inject(0) { |len, part| len + bytesize(part) }
headers['Content-Length'] = length.to_s
end
View
23 actionpack/lib/action_controller/vendor/rack-1.0/rack/content_type.rb
@@ -0,0 +1,23 @@
+require 'rack/utils'
+
+module Rack
+
+ # Sets the Content-Type header on responses which don't have one.
+ #
+ # Builder Usage:
+ # use Rack::ContentType, "text/plain"
+ #
+ # When no content type argument is provided, "text/html" is assumed.
+ class ContentType
+ def initialize(app, content_type = "text/html")
+ @app, @content_type = app, content_type
+ end
+
+ def call(env)
+ status, headers, body = @app.call(env)
+ headers = Utils::HeaderHash.new(headers)
+ headers['Content-Type'] ||= @content_type
+ [status, headers.to_hash, body]
+ end
+ end
+end
View
4 actionpack/lib/action_controller/vendor/rack-1.0/rack/deflater.rb
@@ -36,12 +36,12 @@ def call(env)
mtime = headers.key?("Last-Modified") ?
Time.httpdate(headers["Last-Modified"]) : Time.now
body = self.class.gzip(body, mtime)
- size = body.respond_to?(:bytesize) ? body.bytesize : body.size
+ size = Rack::Utils.bytesize(body)
headers = headers.merge("Content-Encoding" => "gzip", "Content-Length" => size.to_s)
[status, headers, [body]]
when "deflate"
body = self.class.deflate(body)
- size = body.respond_to?(:bytesize) ? body.bytesize : body.size
+ size = Rack::Utils.bytesize(body)
headers = headers.merge("Content-Encoding" => "deflate", "Content-Length" => size.to_s)
[status, headers, [body]]
when "identity"
View
6 actionpack/lib/action_controller/vendor/rack-1.0/rack/directory.rb
@@ -70,7 +70,7 @@ def check_forbidden
return unless @path_info.include? ".."
body = "Forbidden\n"
- size = body.respond_to?(:bytesize) ? body.bytesize : body.size
+ size = Rack::Utils.bytesize(body)
return [403, {"Content-Type" => "text/plain","Content-Length" => size.to_s}, [body]]
end
@@ -89,6 +89,8 @@ def list_directory
type = stat.directory? ? 'directory' : Mime.mime_type(ext)
size = stat.directory? ? '-' : filesize_format(size)
mtime = stat.mtime.httpdate
+ url << '/' if stat.directory?
+ basename << '/' if stat.directory?
@files << [ url, basename, size, type, mtime ]
end
@@ -120,7 +122,7 @@ def list_path
def entity_not_found
body = "Entity not found: #{@path_info}\n"
- size = body.respond_to?(:bytesize) ? body.bytesize : body.size
+ size = Rack::Utils.bytesize(body)
return [404, {"Content-Type" => "text/plain", "Content-Length" => size.to_s}, [body]]
end
View
2 actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
@@ -60,7 +60,7 @@ def serving
body = self
else
body = [F.read(@path)]
- size = body.first.size
+ size = Utils.bytesize(body.first)
end
[200, {
View
4 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
@@ -1,3 +1,5 @@
+require 'rack/content_length'
+
module Rack
module Handler
class CGI
@@ -6,6 +8,8 @@ def self.run(app, options=nil)
end
def self.serve(app)
+ app = ContentLength.new(app)
+
env = ENV.to_hash
env.delete "HTTP_CONTENT_LENGTH"
View
3 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
@@ -1,5 +1,6 @@
require 'fcgi'
require 'socket'
+require 'rack/content_length'
module Rack
module Handler
@@ -29,6 +30,8 @@ def read(*args)
end
def self.serve(request, app)
+ app = Rack::ContentLength.new(app)
+
env = request.env
env.delete "HTTP_CONTENT_LENGTH"
View
7 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
@@ -1,5 +1,6 @@
require 'lsapi'
-#require 'cgi'
+require 'rack/content_length'
+
module Rack
module Handler
class LSWS
@@ -9,11 +10,13 @@ def self.run(app, options=nil)
end
end
def self.serve(app)
+ app = Rack::ContentLength.new(app)
+
env = ENV.to_hash
env.delete "HTTP_CONTENT_LENGTH"
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
env.update({"rack.version" => [0,1],
- "rack.input" => $stdin,
+ "rack.input" => StringIO.new($stdin.read.to_s),
"rack.errors" => $stderr,
"rack.multithread" => false,
"rack.multiprocess" => true,
View
4 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
@@ -1,5 +1,7 @@
require 'mongrel'
require 'stringio'
+require 'rack/content_length'
+require 'rack/chunked'
module Rack
module Handler
@@ -33,7 +35,7 @@ def self.run(app, options={})
end
def initialize(app)
- @app = app
+ @app = Rack::Chunked.new(Rack::ContentLength.new(app))
end
def process(request, response)
View
4 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
@@ -1,5 +1,7 @@
require 'scgi'
require 'stringio'
+require 'rack/content_length'
+require 'rack/chunked'
module Rack
module Handler
@@ -14,7 +16,7 @@ def self.run(app, options=nil)
end
def initialize(settings = {})
- @app = settings[:app]
+ @app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app]))
@log = Object.new
def @log.info(*args); end
def @log.error(*args); end
View
3 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
@@ -1,9 +1,12 @@
require "thin"
+require "rack/content_length"
+require "rack/chunked"
module Rack
module Handler
class Thin
def self.run(app, options={})
+ app = Rack::Chunked.new(Rack::ContentLength.new(app))
server = ::Thin::Server.new(options[:Host] || '0.0.0.0',
options[:Port] || 8080,
app)
View
10 actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
@@ -1,5 +1,6 @@
require 'webrick'
require 'stringio'
+require 'rack/content_length'
module Rack
module Handler
@@ -14,7 +15,7 @@ def self.run(app, options={})
def initialize(server, app)
super server
- @app = app
+ @app = Rack::ContentLength.new(app)
end
def service(req, res)
@@ -35,7 +36,12 @@ def service(req, res)
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
env["QUERY_STRING"] ||= ""
env["REQUEST_PATH"] ||= "/"
- env.delete "PATH_INFO" if env["PATH_INFO"] == ""
+ if env["PATH_INFO"] == ""
+ env.delete "PATH_INFO"
+ else
+ path, n = req.request_uri.path, env["SCRIPT_NAME"].length
+ env["PATH_INFO"] = path[n, path.length-n]
+ end
status, headers, body = @app.call(env)
begin
View
58 actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
@@ -88,7 +88,9 @@ def check_env(env)
## within the application. This may be an
## empty string, if the request URL targets
## the application root and does not have a
- ## trailing slash.
+ ## trailing slash. This information should be
+ ## decoded by the server if it comes from a
+ ## URL.
## <tt>QUERY_STRING</tt>:: The portion of the request URL that
## follows the <tt>?</tt>, if any. May be
@@ -372,59 +374,43 @@ def check_content_type(status, headers)
## === The Content-Length
def check_content_length(status, headers, env)
- chunked_response = false
- headers.each { |key, value|
- if key.downcase == 'transfer-encoding'
- chunked_response = value.downcase != 'identity'
- end
- }
-
headers.each { |key, value|
if key.downcase == 'content-length'
- ## There must be a <tt>Content-Length</tt>, except when the
- ## +Status+ is 1xx, 204 or 304, in which case there must be none