thorero 0.9.4.4 → 0.9.4.5

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 (298) hide show
  1. data/LICENSE +1 -1
  2. data/README +21 -0
  3. data/Rakefile +275 -108
  4. data/TODO +0 -0
  5. data/bin/merb +12 -0
  6. data/bin/merb-specs +5 -0
  7. data/docs/bootloading.dox +58 -0
  8. data/docs/documentation_standards +40 -0
  9. data/docs/merb-core-call-stack-diagram.mmap +0 -0
  10. data/docs/merb-core-call-stack-diagram.pdf +0 -0
  11. data/docs/merb-core-call-stack-diagram.png +0 -0
  12. data/docs/new_render_api +51 -0
  13. data/lib/merb-core.rb +603 -0
  14. data/lib/merb-core/autoload.rb +32 -0
  15. data/lib/merb-core/bootloader.rb +708 -0
  16. data/lib/merb-core/config.rb +303 -0
  17. data/lib/merb-core/constants.rb +43 -0
  18. data/lib/merb-core/controller/abstract_controller.rb +578 -0
  19. data/lib/merb-core/controller/exceptions.rb +302 -0
  20. data/lib/merb-core/controller/merb_controller.rb +256 -0
  21. data/lib/merb-core/controller/mime.rb +106 -0
  22. data/lib/merb-core/controller/mixins/authentication.rb +87 -0
  23. data/lib/merb-core/controller/mixins/controller.rb +290 -0
  24. data/lib/merb-core/controller/mixins/render.rb +481 -0
  25. data/lib/merb-core/controller/mixins/responder.rb +472 -0
  26. data/lib/merb-core/controller/template.rb +254 -0
  27. data/lib/merb-core/core_ext.rb +8 -0
  28. data/lib/merb-core/core_ext/kernel.rb +319 -0
  29. data/lib/merb-core/dispatch/cookies.rb +91 -0
  30. data/lib/merb-core/dispatch/dispatcher.rb +278 -0
  31. data/lib/merb-core/dispatch/exceptions.html.erb +303 -0
  32. data/lib/merb-core/dispatch/request.rb +603 -0
  33. data/lib/merb-core/dispatch/router.rb +179 -0
  34. data/lib/merb-core/dispatch/router/behavior.rb +867 -0
  35. data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
  36. data/lib/merb-core/dispatch/router/route.rb +321 -0
  37. data/lib/merb-core/dispatch/session.rb +78 -0
  38. data/lib/merb-core/dispatch/session/cookie.rb +168 -0
  39. data/lib/merb-core/dispatch/session/memcached.rb +184 -0
  40. data/lib/merb-core/dispatch/session/memory.rb +241 -0
  41. data/lib/merb-core/dispatch/worker.rb +28 -0
  42. data/lib/merb-core/gem_ext/erubis.rb +77 -0
  43. data/lib/{extlib → merb-core}/logger.rb +2 -2
  44. data/lib/merb-core/plugins.rb +59 -0
  45. data/lib/merb-core/rack.rb +21 -0
  46. data/lib/merb-core/rack/adapter.rb +44 -0
  47. data/lib/merb-core/rack/adapter/ebb.rb +25 -0
  48. data/lib/merb-core/rack/adapter/evented_mongrel.rb +26 -0
  49. data/lib/merb-core/rack/adapter/fcgi.rb +17 -0
  50. data/lib/merb-core/rack/adapter/irb.rb +118 -0
  51. data/lib/merb-core/rack/adapter/mongrel.rb +26 -0
  52. data/lib/merb-core/rack/adapter/runner.rb +28 -0
  53. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +26 -0
  54. data/lib/merb-core/rack/adapter/thin.rb +39 -0
  55. data/lib/merb-core/rack/adapter/thin_turbo.rb +24 -0
  56. data/lib/merb-core/rack/adapter/webrick.rb +36 -0
  57. data/lib/merb-core/rack/application.rb +18 -0
  58. data/lib/merb-core/rack/handler/mongrel.rb +97 -0
  59. data/lib/merb-core/rack/middleware.rb +26 -0
  60. data/lib/merb-core/rack/middleware/path_prefix.rb +31 -0
  61. data/lib/merb-core/rack/middleware/profiler.rb +19 -0
  62. data/lib/merb-core/rack/middleware/static.rb +45 -0
  63. data/lib/merb-core/server.rb +252 -0
  64. data/lib/merb-core/tasks/audit.rake +68 -0
  65. data/lib/merb-core/tasks/merb.rb +1 -0
  66. data/lib/merb-core/tasks/merb_rake_helper.rb +12 -0
  67. data/lib/merb-core/test.rb +11 -0
  68. data/lib/merb-core/test/helpers.rb +9 -0
  69. data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
  70. data/lib/merb-core/test/helpers/multipart_request_helper.rb +175 -0
  71. data/lib/merb-core/test/helpers/request_helper.rb +344 -0
  72. data/lib/merb-core/test/helpers/route_helper.rb +33 -0
  73. data/lib/merb-core/test/helpers/view_helper.rb +121 -0
  74. data/lib/merb-core/test/matchers.rb +9 -0
  75. data/lib/merb-core/test/matchers/controller_matchers.rb +319 -0
  76. data/lib/merb-core/test/matchers/route_matchers.rb +136 -0
  77. data/lib/merb-core/test/matchers/view_matchers.rb +335 -0
  78. data/lib/merb-core/test/run_specs.rb +47 -0
  79. data/lib/merb-core/test/tasks/spectasks.rb +68 -0
  80. data/lib/merb-core/test/test_ext/hpricot.rb +32 -0
  81. data/lib/merb-core/test/test_ext/object.rb +14 -0
  82. data/lib/merb-core/test/test_ext/string.rb +14 -0
  83. data/lib/merb-core/vendor/facets.rb +2 -0
  84. data/lib/merb-core/vendor/facets/dictionary.rb +433 -0
  85. data/lib/merb-core/vendor/facets/inflect.rb +345 -0
  86. data/lib/merb-core/version.rb +11 -0
  87. data/spec/private/config/adapter_spec.rb +32 -0
  88. data/spec/private/config/config_spec.rb +202 -0
  89. data/spec/private/config/environment_spec.rb +13 -0
  90. data/spec/private/config/spec_helper.rb +1 -0
  91. data/spec/private/core_ext/kernel_spec.rb +169 -0
  92. data/spec/private/dispatch/bootloader_spec.rb +24 -0
  93. data/spec/private/dispatch/cookies_spec.rb +107 -0
  94. data/spec/private/dispatch/dispatch_spec.rb +35 -0
  95. data/spec/private/dispatch/fixture/app/controllers/application.rb +4 -0
  96. data/spec/private/dispatch/fixture/app/controllers/exceptions.rb +27 -0
  97. data/spec/private/dispatch/fixture/app/controllers/foo.rb +21 -0
  98. data/spec/private/dispatch/fixture/app/helpers/global_helpers.rb +8 -0
  99. data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +37 -0
  100. data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +216 -0
  101. data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +38 -0
  102. data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +40 -0
  103. data/spec/private/dispatch/fixture/app/views/foo/bar.html.erb +0 -0
  104. data/spec/private/dispatch/fixture/app/views/layout/application.html.erb +11 -0
  105. data/spec/private/dispatch/fixture/config/black_hole.rb +12 -0
  106. data/spec/private/dispatch/fixture/config/environments/development.rb +6 -0
  107. data/spec/private/dispatch/fixture/config/environments/production.rb +5 -0
  108. data/spec/private/dispatch/fixture/config/environments/test.rb +6 -0
  109. data/spec/private/dispatch/fixture/config/init.rb +45 -0
  110. data/spec/private/dispatch/fixture/config/rack.rb +11 -0
  111. data/spec/private/dispatch/fixture/config/router.rb +35 -0
  112. data/spec/private/dispatch/fixture/log/merb_test.log +1874 -0
  113. data/spec/private/dispatch/fixture/public/images/merb.jpg +0 -0
  114. data/spec/private/dispatch/fixture/public/merb.fcgi +4 -0
  115. data/spec/private/dispatch/fixture/public/stylesheets/master.css +119 -0
  116. data/spec/private/dispatch/route_params_spec.rb +24 -0
  117. data/spec/private/dispatch/session_mixin_spec.rb +47 -0
  118. data/spec/private/dispatch/spec_helper.rb +1 -0
  119. data/spec/private/plugins/plugin_spec.rb +166 -0
  120. data/spec/private/rack/application_spec.rb +49 -0
  121. data/spec/private/router/behavior_spec.rb +60 -0
  122. data/spec/private/router/fixture/log/merb_test.log +139 -0
  123. data/spec/private/router/route_spec.rb +414 -0
  124. data/spec/private/router/router_spec.rb +175 -0
  125. data/spec/private/vendor/facets/plural_spec.rb +564 -0
  126. data/spec/private/vendor/facets/singular_spec.rb +489 -0
  127. data/spec/public/DEFINITIONS +11 -0
  128. data/spec/public/abstract_controller/controllers/alt_views/layout/application.erb +1 -0
  129. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_string_controller_layout.erb +1 -0
  130. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_template_controller_layout.erb +1 -0
  131. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/index.erb +1 -0
  132. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/show.erb +1 -0
  133. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
  134. data/spec/public/abstract_controller/controllers/alt_views/partial/basic_partial_with_multiple_roots/_partial.erb +1 -0
  135. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_and_custom_location/index.erb +1 -0
  136. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_inherited/index.erb +1 -0
  137. data/spec/public/abstract_controller/controllers/cousins.rb +41 -0
  138. data/spec/public/abstract_controller/controllers/display.rb +54 -0
  139. data/spec/public/abstract_controller/controllers/filters.rb +193 -0
  140. data/spec/public/abstract_controller/controllers/helpers.rb +41 -0
  141. data/spec/public/abstract_controller/controllers/partial.rb +121 -0
  142. data/spec/public/abstract_controller/controllers/render.rb +113 -0
  143. data/spec/public/abstract_controller/controllers/views/helpers/capture/index.erb +1 -0
  144. data/spec/public/abstract_controller/controllers/views/helpers/capture_eq/index.erb +1 -0
  145. data/spec/public/abstract_controller/controllers/views/helpers/capture_with_args/index.erb +1 -0
  146. data/spec/public/abstract_controller/controllers/views/helpers/concat/index.erb +1 -0
  147. data/spec/public/abstract_controller/controllers/views/layout/alt.erb +1 -0
  148. data/spec/public/abstract_controller/controllers/views/layout/custom.erb +1 -0
  149. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object/index.erb +1 -0
  150. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object_with_action/new.erb +1 -0
  151. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template/index.erb +1 -0
  152. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_app_layout/index.erb +0 -0
  153. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_custom_layout/index.erb +1 -0
  154. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
  155. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/show.erb +1 -0
  156. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_two_throw_contents/index.erb +1 -0
  157. data/spec/public/abstract_controller/controllers/views/partial/another_directory/_partial.erb +1 -0
  158. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/_partial.erb +1 -0
  159. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/index.erb +1 -0
  160. data/spec/public/abstract_controller/controllers/views/partial/basic_partial_with_multiple_roots/index.erb +1 -0
  161. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_first.erb +1 -0
  162. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_second.erb +1 -0
  163. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/index.erb +1 -0
  164. data/spec/public/abstract_controller/controllers/views/partial/partial_in_another_directory/index.erb +1 -0
  165. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/_collection.erb +1 -0
  166. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/index.erb +1 -0
  167. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/_collection.erb +1 -0
  168. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/index.erb +1 -0
  169. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/_collection.erb +1 -0
  170. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/index.erb +1 -0
  171. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/_collection.erb +1 -0
  172. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/index.erb +1 -0
  173. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/_variables.erb +1 -0
  174. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/index.erb +1 -0
  175. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/_both.erb +1 -0
  176. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/index.erb +1 -0
  177. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/_partial.erb +1 -0
  178. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/index.erb +1 -0
  179. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/_with_partial.erb +1 -0
  180. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/index.erb +1 -0
  181. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/_with_partial.erb +1 -0
  182. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/index.erb +1 -0
  183. data/spec/public/abstract_controller/controllers/views/partial/with_partial/_with_partial.erb +1 -0
  184. data/spec/public/abstract_controller/controllers/views/partial/with_partial/index.erb +1 -0
  185. data/spec/public/abstract_controller/controllers/views/test_display/foo.html.erb +1 -0
  186. data/spec/public/abstract_controller/controllers/views/test_render/foo.html.erb +0 -0
  187. data/spec/public/abstract_controller/controllers/views/wonderful/index.erb +1 -0
  188. data/spec/public/abstract_controller/display_spec.rb +33 -0
  189. data/spec/public/abstract_controller/filter_spec.rb +106 -0
  190. data/spec/public/abstract_controller/helper_spec.rb +21 -0
  191. data/spec/public/abstract_controller/partial_spec.rb +61 -0
  192. data/spec/public/abstract_controller/render_spec.rb +90 -0
  193. data/spec/public/abstract_controller/spec_helper.rb +31 -0
  194. data/spec/public/boot_loader/boot_loader_spec.rb +33 -0
  195. data/spec/public/boot_loader/spec_helper.rb +1 -0
  196. data/spec/public/controller/authentication_spec.rb +103 -0
  197. data/spec/public/controller/base_spec.rb +36 -0
  198. data/spec/public/controller/controllers/authentication.rb +45 -0
  199. data/spec/public/controller/controllers/base.rb +36 -0
  200. data/spec/public/controller/controllers/display.rb +118 -0
  201. data/spec/public/controller/controllers/redirect.rb +30 -0
  202. data/spec/public/controller/controllers/responder.rb +93 -0
  203. data/spec/public/controller/controllers/url.rb +7 -0
  204. data/spec/public/controller/controllers/views/layout/custom.html.erb +1 -0
  205. data/spec/public/controller/controllers/views/layout/custom_arg.html.erb +1 -0
  206. data/spec/public/controller/controllers/views/layout/custom_arg.json.erb +1 -0
  207. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.html.erb +1 -0
  208. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.xml.erb +1 -0
  209. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +1 -0
  210. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.xml.erb +1 -0
  211. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/index.html.erb +1 -0
  212. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/no_layout.html.erb +1 -0
  213. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template_argument/index.html.erb +1 -0
  214. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/html_default/index.html.erb +1 -0
  215. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/layout/custom.html.erb +1 -0
  216. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.html.erb +1 -0
  217. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.xml.erb +1 -0
  218. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.html.erb +1 -0
  219. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.js.erb +1 -0
  220. data/spec/public/controller/display_spec.rb +84 -0
  221. data/spec/public/controller/redirect_spec.rb +27 -0
  222. data/spec/public/controller/responder_spec.rb +163 -0
  223. data/spec/public/controller/spec_helper.rb +11 -0
  224. data/spec/public/controller/url_spec.rb +180 -0
  225. data/spec/public/core/merb_core_spec.rb +45 -0
  226. data/spec/public/core_ext/class_spec.rb +91 -0
  227. data/spec/public/core_ext/fixtures/core_ext_dependency.rb +2 -0
  228. data/spec/public/core_ext/kernel_spec.rb +9 -0
  229. data/spec/public/core_ext/spec_helper.rb +1 -0
  230. data/spec/public/directory_structure/directory/app/controllers/application.rb +3 -0
  231. data/spec/public/directory_structure/directory/app/controllers/base.rb +13 -0
  232. data/spec/public/directory_structure/directory/app/controllers/custom.rb +19 -0
  233. data/spec/public/directory_structure/directory/app/views/base/template.html.erb +1 -0
  234. data/spec/public/directory_structure/directory/app/views/wonderful/template.erb +1 -0
  235. data/spec/public/directory_structure/directory/config/router.rb +3 -0
  236. data/spec/public/directory_structure/directory/log/merb_test.log +562 -0
  237. data/spec/public/directory_structure/directory_spec.rb +44 -0
  238. data/spec/public/logger/logger_spec.rb +181 -0
  239. data/spec/public/logger/spec_helper.rb +1 -0
  240. data/spec/public/reloading/directory/app/controllers/application.rb +3 -0
  241. data/spec/public/reloading/directory/app/controllers/reload.rb +6 -0
  242. data/spec/public/reloading/directory/config/init.rb +2 -0
  243. data/spec/public/reloading/directory/log/merb_test.log +138 -0
  244. data/spec/public/reloading/reload_spec.rb +103 -0
  245. data/spec/public/request/multipart_spec.rb +41 -0
  246. data/spec/public/request/request_spec.rb +228 -0
  247. data/spec/public/router/default_spec.rb +21 -0
  248. data/spec/public/router/deferred_spec.rb +22 -0
  249. data/spec/public/router/fixation_spec.rb +27 -0
  250. data/spec/public/router/fixture/log/merb_test.log +1556 -0
  251. data/spec/public/router/namespace_spec.rb +113 -0
  252. data/spec/public/router/nested_matches_spec.rb +97 -0
  253. data/spec/public/router/nested_resources_spec.rb +41 -0
  254. data/spec/public/router/resource_spec.rb +37 -0
  255. data/spec/public/router/resources_spec.rb +82 -0
  256. data/spec/public/router/spec_helper.rb +90 -0
  257. data/spec/public/router/special_spec.rb +61 -0
  258. data/spec/public/router/string_spec.rb +61 -0
  259. data/spec/public/template/template_spec.rb +104 -0
  260. data/spec/public/template/templates/error.html.erb +2 -0
  261. data/spec/public/template/templates/template.html.erb +1 -0
  262. data/spec/public/template/templates/template.html.myt +1 -0
  263. data/spec/public/test/controller_matchers_spec.rb +402 -0
  264. data/spec/public/test/controllers/controller_assertion_mock.rb +7 -0
  265. data/spec/public/test/controllers/dispatch_controller.rb +11 -0
  266. data/spec/public/test/controllers/spec_helper_controller.rb +38 -0
  267. data/spec/public/test/multipart_request_helper_spec.rb +159 -0
  268. data/spec/public/test/multipart_upload_text_file.txt +1 -0
  269. data/spec/public/test/request_helper_spec.rb +221 -0
  270. data/spec/public/test/route_helper_spec.rb +71 -0
  271. data/spec/public/test/route_matchers_spec.rb +162 -0
  272. data/spec/public/test/view_helper_spec.rb +96 -0
  273. data/spec/public/test/view_matchers_spec.rb +183 -0
  274. data/spec/spec_helper.rb +68 -0
  275. metadata +493 -41
  276. data/README.txt +0 -3
  277. data/lib/extlib.rb +0 -32
  278. data/lib/extlib/assertions.rb +0 -8
  279. data/lib/extlib/blank.rb +0 -42
  280. data/lib/extlib/class.rb +0 -175
  281. data/lib/extlib/hash.rb +0 -410
  282. data/lib/extlib/hook.rb +0 -366
  283. data/lib/extlib/inflection.rb +0 -141
  284. data/lib/extlib/lazy_array.rb +0 -106
  285. data/lib/extlib/mash.rb +0 -143
  286. data/lib/extlib/module.rb +0 -37
  287. data/lib/extlib/object.rb +0 -165
  288. data/lib/extlib/object_space.rb +0 -13
  289. data/lib/extlib/pathname.rb +0 -5
  290. data/lib/extlib/pooling.rb +0 -233
  291. data/lib/extlib/rubygems.rb +0 -38
  292. data/lib/extlib/simple_set.rb +0 -39
  293. data/lib/extlib/string.rb +0 -132
  294. data/lib/extlib/struct.rb +0 -8
  295. data/lib/extlib/tasks/release.rb +0 -9
  296. data/lib/extlib/time.rb +0 -12
  297. data/lib/extlib/version.rb +0 -3
  298. data/lib/extlib/virtual_file.rb +0 -10
@@ -0,0 +1,106 @@
1
+ module Merb
2
+ class << self
3
+
4
+ # ==== Returns
5
+ # Hash:: The available mime types.
6
+ def available_mime_types
7
+ ResponderMixin::TYPES
8
+ end
9
+
10
+ # Any specific outgoing headers should be included here. These are not
11
+ # the content-type header but anything in addition to it.
12
+ # +transform_method+ should be set to a symbol of the method used to
13
+ # transform a resource into this mime type.
14
+ # For example for the :xml mime type an object might be transformed by
15
+ # calling :to_xml, or for the :js mime type, :to_json.
16
+ # If there is no transform method, use nil.
17
+ #
18
+ # ==== Autogenerated Methods
19
+ # Adding a mime-type adds a render_type method that sets the content
20
+ # type and calls render.
21
+ #
22
+ # By default this does: def render_all, def render_yaml, def render_text,
23
+ # def render_html, def render_xml, def render_js, and def render_yaml
24
+ #
25
+ # ==== Parameters
26
+ # key<Symbol>:: The name of the mime-type. This is used by the provides API
27
+ # transform_method<~to_s>::
28
+ # The associated method to call on objects to convert them to the
29
+ # appropriate mime-type. For instance, :json would use :to_json as its
30
+ # transform_method.
31
+ # mimes<Array[String]>::
32
+ # A list of possible values sent in the Accept header, such as text/html,
33
+ # that should be associated with this content-type.
34
+ # new_response_headers<Hash>::
35
+ # The response headers to set for the the mime type. For example:
36
+ # 'Content-Type' => 'application/json; charset=utf-8'; As a shortcut for
37
+ # the common charset option, use :charset => 'utf-8', which will be
38
+ # correctly appended to the mimetype itself.
39
+ # &block:: a block which recieves the current controller when the format
40
+ # is set (in the controller's #content_type method)
41
+ def add_mime_type(key, transform_method, mimes, new_response_headers = {}, &block)
42
+ enforce!(key => Symbol, mimes => Array)
43
+
44
+ content_type = new_response_headers["Content-Type"] || mimes.first
45
+
46
+ if charset = new_response_headers.delete(:charset)
47
+ content_type += "; charset=#{charset}"
48
+ end
49
+
50
+ ResponderMixin::TYPES.update(key =>
51
+ {:accepts => mimes,
52
+ :transform_method => transform_method,
53
+ :content_type => content_type,
54
+ :response_headers => new_response_headers,
55
+ :response_block => block })
56
+
57
+ mimes.each do |mime|
58
+ ResponderMixin::MIMES.update(mime => key)
59
+ end
60
+
61
+ Merb::RenderMixin.class_eval <<-EOS, __FILE__, __LINE__
62
+ def render_#{key}(thing = nil, opts = {})
63
+ self.content_type = :#{key}
64
+ render thing, opts
65
+ end
66
+ EOS
67
+ end
68
+
69
+ # Removes a MIME-type from the mime-type list.
70
+ #
71
+ # ==== Parameters
72
+ # key<Symbol>:: The key that represents the mime-type to remove.
73
+ #
74
+ # ==== Notes
75
+ # :all is the key for */*; It can't be removed.
76
+ def remove_mime_type(key)
77
+ return false if key == :all
78
+ ResponderMixin::TYPES.delete(key)
79
+ end
80
+
81
+ # ==== Parameters
82
+ # key<Symbol>:: The key that represents the mime-type.
83
+ #
84
+ # ==== Returns
85
+ # Symbol:: The transform method for the mime type, e.g. :to_json.
86
+ #
87
+ # ==== Raises
88
+ # ArgumentError:: The requested mime type is not valid.
89
+ def mime_transform_method(key)
90
+ raise ArgumentError, ":#{key} is not a valid MIME-type" unless ResponderMixin::TYPES.key?(key)
91
+ ResponderMixin::TYPES[key][:transform_method]
92
+ end
93
+
94
+ # The mime-type for a particular inbound Accepts header.
95
+ #
96
+ # ==== Parameters
97
+ # header<String>:: The name of the header to find the mime-type for.
98
+ #
99
+ # ==== Returns
100
+ # Hash:: The mime type information.
101
+ def mime_by_request_header(header)
102
+ available_mime_types.find {|key,info| info[:accepts].include?(header)}.first
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,87 @@
1
+ module Merb::AuthenticationMixin
2
+
3
+ # Attempts to authenticate the user via HTTP Basic authentication. Takes a
4
+ # block with the username and password, if the block yields false the
5
+ # authentication is not accepted and :halt is thrown.
6
+ #
7
+ # If no block is passed, +basic_authentication+, the +request+ and +authenticate+
8
+ # methods can be chained. These can be used to independently request authentication
9
+ # or confirm it, if more control is desired.
10
+ #
11
+ # ==== Parameters
12
+ # realm<~to_s>:: The realm to authenticate against. Defaults to 'Application'.
13
+ # &authenticator:: A block to check if the authentication is valid.
14
+ #
15
+ # ==== Examples
16
+ # class Application < Merb::Controller
17
+ #
18
+ # before :authenticate
19
+ #
20
+ # protected
21
+ #
22
+ # def authenticate
23
+ # basic_authentication("My App") do |username, password|
24
+ # password == "secret"
25
+ # end
26
+ # end
27
+ #
28
+ # end
29
+ #
30
+ # class Application < Merb::Controller
31
+ #
32
+ # before :authenticate
33
+ #
34
+ # def authenticate
35
+ # user = basic_authentication.authenticate do |username, password|
36
+ # User.authenticate(username, password)
37
+ # end
38
+ #
39
+ # if user
40
+ # @current_user = user
41
+ # else
42
+ # basic_authentication.request
43
+ # end
44
+ # end
45
+ #
46
+ # end
47
+ #
48
+ #---
49
+ # @public
50
+ def basic_authentication(realm = "Application", &authenticator)
51
+ BasicAuthentication.new(self, realm, &authenticator)
52
+ end
53
+
54
+ class BasicAuthentication
55
+ # So we can have access to the status codes
56
+ include Merb::ControllerExceptions
57
+
58
+ def initialize(controller, realm = "Application", &authenticator)
59
+ @controller = controller
60
+ @realm = realm
61
+ authenticate_or_request(&authenticator) if authenticator
62
+ end
63
+
64
+ def authenticate(&authenticator)
65
+ auth = Rack::Auth::Basic::Request.new(@controller.request.env)
66
+
67
+ if auth.provided? and auth.basic?
68
+ authenticator.call(*auth.credentials)
69
+ else
70
+ false
71
+ end
72
+ end
73
+
74
+ def request
75
+ @controller.headers['WWW-Authenticate'] = 'Basic realm="%s"' % @realm
76
+ throw :halt, @controller.render("HTTP Basic: Access denied.\n", :status => Unauthorized.status, :layout => false)
77
+ end
78
+
79
+ protected
80
+
81
+ def authenticate_or_request(&authenticator)
82
+ authenticate(&authenticator) || request
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,290 @@
1
+ module Merb
2
+ # Module that is mixed in to all implemented controllers.
3
+ module ControllerMixin
4
+
5
+ # Enqueu a block to run in a background thread outside of the request
6
+ # response dispatch
7
+ #
8
+ # ==== Parameters
9
+ # takes a block to run later
10
+ #
11
+ # ==== Example
12
+ # run_later do
13
+ # SomeBackgroundTask.run
14
+ # end
15
+ #
16
+ def run_later(&blk)
17
+ Merb::Dispatcher.work_queue << blk
18
+ end
19
+
20
+ # Renders the block given as a parameter using chunked encoding.
21
+ #
22
+ # ==== Parameters
23
+ # &blk::
24
+ # A block that, when called, will use send_chunks to send chunks of data
25
+ # down to the server. The chunking will terminate once the block returns.
26
+ #
27
+ # ==== Examples
28
+ # def stream
29
+ # prefix = '<p>'
30
+ # suffix = "</p>\r\n"
31
+ # render_chunked do
32
+ # IO.popen("cat /tmp/test.log") do |io|
33
+ # done = false
34
+ # until done
35
+ # sleep 0.3
36
+ # line = io.gets.chomp
37
+ #
38
+ # if line == 'EOF'
39
+ # done = true
40
+ # else
41
+ # send_chunk(prefix + line + suffix)
42
+ # end
43
+ # end
44
+ # end
45
+ # end
46
+ # end
47
+ def render_chunked(&blk)
48
+ must_support_streaming!
49
+ headers['Transfer-Encoding'] = 'chunked'
50
+ Proc.new { |response|
51
+ @response = response
52
+ response.send_status_no_connection_close('')
53
+ response.send_header
54
+ blk.call
55
+ response.write("0\r\n\r\n")
56
+ }
57
+ end
58
+
59
+ # Writes a chunk from +render_chunked+ to the response that is sent back to
60
+ # the client. This should only be called within a +render_chunked+ block.
61
+ #
62
+ # ==== Parameters
63
+ # data<String>:: a chunk of data to return.
64
+ def send_chunk(data)
65
+ @response.write('%x' % data.size + "\r\n")
66
+ @response.write(data + "\r\n")
67
+ end
68
+
69
+ # ==== Parameters
70
+ # &blk::
71
+ # A proc that should get called outside the mutex, and which will return
72
+ # the value to render.
73
+ #
74
+ # ==== Returns
75
+ # Proc::
76
+ # A block that Mongrel can call later, allowing Merb to release the
77
+ # thread lock and render another request.
78
+ def render_deferred(&blk)
79
+ must_support_streaming!
80
+ Proc.new {|response|
81
+ result = blk.call
82
+ response.send_status(result.length)
83
+ response.send_header
84
+ response.write(result)
85
+ }
86
+ end
87
+
88
+ # Renders the passed in string, then calls the block outside the mutex and
89
+ # after the string has been returned to the client.
90
+ #
91
+ # ==== Parameters
92
+ # str<String>:: A +String+ to return to the client.
93
+ # &blk:: A block that should get called once the string has been returned.
94
+ #
95
+ # ==== Returns
96
+ # Proc::
97
+ # A block that Mongrel can call after returning the string to the user.
98
+ def render_then_call(str, &blk)
99
+ must_support_streaming!
100
+ Proc.new {|response|
101
+ response.send_status(str.length)
102
+ response.send_header
103
+ response.write(str)
104
+ blk.call
105
+ }
106
+ end
107
+
108
+ # ==== Parameters
109
+ # url<String>::
110
+ # URL to redirect to. It can be either a relative or fully-qualified URL.
111
+ # permanent<Boolean>::
112
+ # When true, return status 301 Moved Permanently
113
+ #
114
+ # ==== Returns
115
+ # String:: Explanation of redirect.
116
+ #
117
+ # ==== Examples
118
+ # redirect("/posts/34")
119
+ # redirect("http://www.merbivore.com/")
120
+ # redirect("http://www.merbivore.com/", true)
121
+ def redirect(url, message = nil)
122
+ if message
123
+ notice = Merb::Request.escape([Marshal.dump(message)].pack("m"))
124
+ url = url =~ /\?/ ? "#{url}&_message=#{notice}" : "#{url}?_message=#{notice}"
125
+ end
126
+ self.status = 302
127
+ Merb.logger.info("Redirecting to: #{url} (#{self.status})")
128
+ headers['Location'] = url
129
+ "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>"
130
+ end
131
+
132
+ def message
133
+ @_message = defined?(@_message) ? @_message : request.message
134
+ end
135
+
136
+ # Sends a file over HTTP. When given a path to a file, it will set the
137
+ # right headers so that the static file is served directly.
138
+ #
139
+ # ==== Parameters
140
+ # file<String>:: Path to file to send to the client.
141
+ # opts<Hash>:: Options for sending the file (see below).
142
+ #
143
+ # ==== Options (opts)
144
+ # :disposition<String>::
145
+ # The disposition of the file send. Defaults to "attachment".
146
+ # :filename<String>::
147
+ # The name to use for the file. Defaults to the filename of file.
148
+ # :type<String>:: The content type.
149
+ #
150
+ # ==== Returns
151
+ # IO:: An I/O stream for the file.
152
+ def send_file(file, opts={})
153
+ opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
154
+ disposition = opts[:disposition].dup || 'attachment'
155
+ disposition << %(; filename="#{opts[:filename] ? opts[:filename] : File.basename(file)}")
156
+ headers.update(
157
+ 'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers
158
+ 'Content-Disposition' => disposition,
159
+ 'Content-Transfer-Encoding' => 'binary'
160
+ )
161
+ File.open(file, 'rb')
162
+ end
163
+
164
+ # Send binary data over HTTP to the user as a file download. May set content type,
165
+ # apparent file name, and specify whether to show data inline or download as an attachment.
166
+ #
167
+ # ==== Parameters
168
+ # data<String>:: Path to file to send to the client.
169
+ # opts<Hash>:: Options for sending the data (see below).
170
+ #
171
+ # ==== Options (opts)
172
+ # :disposition<String>::
173
+ # The disposition of the file send. Defaults to "attachment".
174
+ # :filename<String>::
175
+ # The name to use for the file. Defaults to the filename of file.
176
+ # :type<String>:: The content type.
177
+ def send_data(data, opts={})
178
+ opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
179
+ disposition = opts[:disposition].dup || 'attachment'
180
+ disposition << %(; filename="#{opts[:filename]}") if opts[:filename]
181
+ headers.update(
182
+ 'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers
183
+ 'Content-Disposition' => disposition,
184
+ 'Content-Transfer-Encoding' => 'binary'
185
+ )
186
+ data
187
+ end
188
+
189
+ # Streams a file over HTTP.
190
+ #
191
+ # ==== Parameters
192
+ # opts<Hash>:: Options for the file streaming (see below).
193
+ # &stream::
194
+ # A block that, when called, will return an object that responds to
195
+ # +get_lines+ for streaming.
196
+ #
197
+ # ==== Options
198
+ # :disposition<String>::
199
+ # The disposition of the file send. Defaults to "attachment".
200
+ # :type<String>:: The content type.
201
+ # :content_length<Numeric>:: The length of the content to send.
202
+ # :filename<String>:: The name to use for the streamed file.
203
+ #
204
+ # ==== Examples
205
+ # stream_file({ :filename => file_name, :type => content_type,
206
+ # :content_length => content_length }) do |response|
207
+ # AWS::S3::S3Object.stream(user.folder_name + "-" + user_file.unique_id, bucket_name) do |chunk|
208
+ # response.write chunk
209
+ # end
210
+ # end
211
+ def stream_file(opts={}, &stream)
212
+ must_support_streaming!
213
+ opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
214
+ disposition = opts[:disposition].dup || 'attachment'
215
+ disposition << %(; filename="#{opts[:filename]}")
216
+ headers.update(
217
+ 'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers
218
+ 'Content-Disposition' => disposition,
219
+ 'Content-Transfer-Encoding' => 'binary',
220
+ 'CONTENT-LENGTH' => opts[:content_length]
221
+ )
222
+ Proc.new{|response|
223
+ response.send_status(opts[:content_length])
224
+ response.send_header
225
+ stream.call(response)
226
+ }
227
+ end
228
+
229
+ # Uses the nginx specific +X-Accel-Redirect+ header to send a file directly
230
+ # from nginx. For more information, see the nginx wiki:
231
+ # http://wiki.codemongers.com/NginxXSendfile
232
+ #
233
+ # ==== Parameters
234
+ # file<String>:: Path to file to send to the client.
235
+ def nginx_send_file(file)
236
+ headers['X-Accel-Redirect'] = file
237
+ return ' '
238
+ end
239
+
240
+ # Sets a cookie to be included in the response.
241
+ #
242
+ # If you need to set a cookie, then use the +cookies+ hash.
243
+ #
244
+ # ==== Parameters
245
+ # name<~to_s>:: A name for the cookie.
246
+ # value<~to_s>:: A value for the cookie.
247
+ # expires<~gmtime:~strftime, Hash>:: An expiration time for the cookie, or a hash of cookie options.
248
+ # ---
249
+ # @public
250
+ def set_cookie(name, value, expires)
251
+ options = expires.is_a?(Hash) ? expires : {:expires => expires}
252
+ cookies.set_cookie(name, value, options)
253
+ end
254
+
255
+ # Marks a cookie as deleted and gives it an expires stamp in the past. This
256
+ # method is used primarily internally in Merb.
257
+ #
258
+ # Use the +cookies+ hash to manipulate cookies instead.
259
+ #
260
+ # ==== Parameters
261
+ # name<~to_s>:: A name for the cookie to delete.
262
+ def delete_cookie(name)
263
+ set_cookie(name, nil, Merb::Const::COOKIE_EXPIRED_TIME)
264
+ end
265
+
266
+ # Escapes the string representation of +obj+ and escapes it for use in XML.
267
+ #
268
+ # ==== Parameter
269
+ # obj<~to_s>:: The object to escape for use in XML.
270
+ #
271
+ # ==== Returns
272
+ # String:: The escaped object.
273
+ def escape_xml(obj)
274
+ Erubis::XmlHelper.escape_xml(obj.to_s)
275
+ end
276
+ alias h escape_xml
277
+ alias html_escape escape_xml
278
+
279
+ private
280
+ # Checks whether streaming is supported by the current Rack adapter.
281
+ #
282
+ # ==== Raises
283
+ # NotImplemented:: The Rack adapter doens't support streaming.
284
+ def must_support_streaming!
285
+ unless request.env['rack.streaming']
286
+ raise(Merb::ControllerExceptions::NotImplemented, "Current Rack adapter does not support streaming")
287
+ end
288
+ end
289
+ end
290
+ end