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,28 @@
1
+ module Merb
2
+
3
+ module Rack
4
+
5
+ class Runner
6
+ # ==== Parameters
7
+ # opts<Hash>:: Options for the runner (see below).
8
+ #
9
+ # ==== Options (opts)
10
+ # :runner_code<String>:: The code to run.
11
+ #
12
+ # ==== Notes
13
+ # If opts[:runner_code] matches a filename, that file will be read and
14
+ # the contents executed. Otherwise the code will be executed directly.
15
+ def self.start(opts={})
16
+ Merb::Server.change_privilege
17
+ if opts[:runner_code]
18
+ if File.exists?(opts[:runner_code])
19
+ eval(File.read(opts[:runner_code]), TOPLEVEL_BINDING, __FILE__, __LINE__)
20
+ else
21
+ eval(opts[:runner_code], TOPLEVEL_BINDING, __FILE__, __LINE__)
22
+ end
23
+ exit
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ require 'swiftcore/swiftiplied_mongrel'
2
+ require 'merb-core/rack/handler/mongrel'
3
+ module Merb
4
+ module Rack
5
+
6
+ class SwiftipliedMongrel < Mongrel
7
+ # Starts Mongrel as swift.
8
+ #
9
+ # ==== Parameters
10
+ # opts<Hash>:: Options for Mongrel (see below).
11
+ #
12
+ # ==== Options (opts)
13
+ # :host<String>:: The hostname that Mongrel should serve.
14
+ # :port<Fixnum>:: The port Mongrel should bind to.
15
+ # :app<String>>:: The application name.
16
+ def self.start(opts={})
17
+ Merb.logger.warn!("Using SwiftipliedMongrel adapter")
18
+ Merb::Dispatcher.use_mutex = false
19
+ server = ::Mongrel::HttpServer.new(opts[:host], opts[:port].to_i)
20
+ Merb::Server.change_privilege
21
+ server.register('/', ::Merb::Rack::Handler::Mongrel.new(opts[:app]))
22
+ server.run.join
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require "thin"
2
+
3
+ module Merb
4
+
5
+ module Rack
6
+
7
+ class Thin
8
+ # start a Thin server on given host and port.
9
+
10
+ # ==== Parameters
11
+ # opts<Hash>:: Options for Thin (see below).
12
+ #
13
+ # ==== Options (opts)
14
+ # :host<String>:: The hostname that Thin should serve.
15
+ # :port<Fixnum>:: The port Thin should bind to.
16
+ # :socket<Fixnum>>:: The socket number that thin should bind to.
17
+ # :socket_file<String>>:: The socket file that thin should attach to.
18
+ # :app<String>>:: The application name.
19
+ def self.start(opts={})
20
+ Merb::Dispatcher.use_mutex = false
21
+ if opts[:socket] || opts[:socket_file]
22
+ socket = opts[:socket] || "0"
23
+ socket_file = opts[:socket_file] || "#{Merb.root}/log/merb.#{socket}.sock"
24
+ Merb.logger.warn!("Using Thin adapter with socket file #{socket_file}.")
25
+ server = ::Thin::Server.new(socket_file, opts[:app], opts)
26
+ else
27
+ Merb.logger.warn!("Using Thin adapter on host #{opts[:host]} and port #{opts[:port]}.")
28
+ if opts[:host].include?('/')
29
+ opts[:host] = "#{opts[:host]}-#{opts[:port]}"
30
+ end
31
+ server = ::Thin::Server.new(opts[:host], opts[:port].to_i, opts[:app], opts)
32
+ end
33
+ Merb::Server.change_privilege
34
+ ::Thin::Logging.silent = true
35
+ server.start
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ require "thin-turbo"
2
+
3
+ module Merb
4
+
5
+ module Rack
6
+
7
+ class ThinTurbo < Thin
8
+ # start a Thin Turbo server on given host and port.
9
+
10
+ # ==== Parameters
11
+ # opts<Hash>:: Options for Thin Turbo (see below).
12
+ #
13
+ # ==== Options (opts)
14
+ # :host<String>:: The hostname that Thin Turbo should serve.
15
+ # :port<Fixnum>:: The port Thin Turbo should bind to.
16
+ # :socket<Fixnum>>:: The socket number that thin should bind to.
17
+ # :socket_file<String>>:: The socket file that thin should attach to.
18
+ # :app<String>>:: The application name.
19
+ def self.start(opts={})
20
+ super(opts.merge(:backend => ::Thin::Backends::Turbo))
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ require 'webrick'
2
+ require 'rack/handler/webrick'
3
+ module Merb
4
+ module Rack
5
+
6
+ class WEBrick
7
+ # start WEBrick server on given host and port.
8
+
9
+ # ==== Parameters
10
+ # opts<Hash>:: Options for WEBrick (see below).
11
+ #
12
+ # ==== Options (opts)
13
+ # :host<String>:: The hostname that WEBrick should serve.
14
+ # :port<Fixnum>:: The port WEBrick should bind to.
15
+ # :app<String>>:: The application name.
16
+ def self.start(opts={})
17
+ Merb.logger.warn!("Using Webrick adapter")
18
+
19
+ options = {
20
+ :Port => opts[:port],
21
+ :BindAddress => opts[:host],
22
+ :Logger => Merb.logger,
23
+ :AccessLog => [
24
+ [Merb.logger, ::WEBrick::AccessLog::COMMON_LOG_FORMAT],
25
+ [Merb.logger, ::WEBrick::AccessLog::REFERER_LOG_FORMAT]
26
+ ]
27
+ }
28
+
29
+ server = ::WEBrick::HTTPServer.new(options)
30
+ Merb::Server.change_privilege
31
+ server.mount("/", ::Rack::Handler::WEBrick, opts[:app])
32
+ server.start
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ module Merb
2
+ module Rack
3
+ class Application
4
+
5
+ def call(env)
6
+ begin
7
+ controller = ::Merb::Dispatcher.handle(env)
8
+ rescue Object => e
9
+ return [500, {"Content-Type"=>"text/html"}, e.message + "<br/>" + e.backtrace.join("<br/>")]
10
+ end
11
+ Merb.logger.info "\n\n"
12
+ Merb.logger.flush
13
+ [controller.status, controller.headers, controller.body]
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,97 @@
1
+ require 'stringio'
2
+ class Mongrel::HttpResponse
3
+ NO_CLOSE_STATUS_FORMAT = "HTTP/1.1 %d %s\r\n".freeze
4
+
5
+ # Sends the status to the client without closing the connection.
6
+ #
7
+ # ==== Parameters
8
+ # content_length<Fixnum>:: The length of the content. Defaults to body length.
9
+ def send_status_no_connection_close(content_length=@body.length)
10
+ unless @status_sent
11
+ write(NO_CLOSE_STATUS_FORMAT % [@status, Mongrel::HTTP_STATUS_CODES[@status]])
12
+ @status_sent = true
13
+ end
14
+ end
15
+ end
16
+
17
+ module Merb
18
+ module Rack
19
+ module Handler
20
+ class Mongrel < ::Mongrel::HttpHandler
21
+ # Runs the server and yields it to a block.
22
+ #
23
+ # ==== Parameters
24
+ # app<Merb::Rack::Application>:: The app that Mongrel should handle.
25
+ # options<Hash>:: Options to pass to Mongrel (see below).
26
+ #
27
+ # ==== Block parameters
28
+ # server<Mongrel::HttpServer>:: The server to run.
29
+ #
30
+ # ==== Options (options)
31
+ # :Host<String>::
32
+ # The hostname on which the app should run. Defaults to "0.0.0.0"
33
+ # :Port<Fixnum>:: The port for the app. Defaults to 8080.
34
+ def self.run(app, options={})
35
+ server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
36
+ options[:Port] || 8080)
37
+ server.register('/', ::Merb::Rack::Handler::Mongrel.new(app))
38
+ yield server if block_given?
39
+ server.run.join
40
+ end
41
+
42
+ # ==== Parameters
43
+ # app<Merb::Rack::Application>:: The app that Mongrel should handle.
44
+ def initialize(app)
45
+ @app = app
46
+ end
47
+
48
+ # ==== Parameters
49
+ # request<Merb::Request>:: The HTTP request to handle.
50
+ # response<HTTPResponse>:: The response object to write response to.
51
+ def process(request, response)
52
+ env = {}.replace(request.params)
53
+ env.delete "HTTP_CONTENT_TYPE"
54
+ env.delete "HTTP_CONTENT_LENGTH"
55
+
56
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
57
+
58
+ env.update({"rack.version" => [0,1],
59
+ "rack.input" => request.body || StringIO.new(""),
60
+ "rack.errors" => STDERR,
61
+
62
+ "rack.multithread" => true,
63
+ "rack.multiprocess" => false, # ???
64
+ "rack.run_once" => false,
65
+
66
+ "rack.url_scheme" => "http",
67
+ "rack.streaming" => true
68
+ })
69
+ env["QUERY_STRING"] ||= ""
70
+ env.delete "PATH_INFO" if env["PATH_INFO"] == ""
71
+
72
+ status, headers, body = @app.call(env)
73
+
74
+ begin
75
+ response.status = status.to_i
76
+ headers.each { |k, vs|
77
+ vs.each { |v|
78
+ response.header[k] = v
79
+ }
80
+ }
81
+
82
+ if Proc === body
83
+ body.call(response)
84
+ else
85
+ body.each { |part|
86
+ response.body << part
87
+ }
88
+ end
89
+ response.finished
90
+ ensure
91
+ body.close if body.respond_to? :close
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,26 @@
1
+ module Merb
2
+ module Rack
3
+ class Middleware
4
+
5
+ def initialize(app)
6
+ @app = app
7
+ end
8
+
9
+ def deferred?(env)
10
+ path = env['PATH_INFO'] ? env['PATH_INFO'].chomp('/') : ""
11
+ if path =~ Merb.deferred_actions
12
+ Merb.logger.info! "Deferring Request: #{path}"
13
+ true
14
+ else
15
+ false
16
+ end
17
+ end
18
+
19
+ def call(env)
20
+ @app.call(env)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,31 @@
1
+ module Merb
2
+ module Rack
3
+ class PathPrefix < Merb::Rack::Middleware
4
+
5
+ def initialize(app, path_prefix = nil)
6
+ super(app)
7
+ @path_prefix = /^#{Regexp.escape(path_prefix)}/
8
+ end
9
+
10
+ def deferred?(env)
11
+ strip_path_prefix(env)
12
+ @app.deferred?(env)
13
+ end
14
+
15
+ def call(env)
16
+ strip_path_prefix(env)
17
+ @app.call(env)
18
+ end
19
+
20
+ def strip_path_prefix(env)
21
+ ['PATH_INFO', 'REQUEST_URI'].each do |path_key|
22
+ if env[path_key] =~ @path_prefix
23
+ env[path_key].sub!(@path_prefix, '')
24
+ env[path_key] = '/' if env[path_key].empty?
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ module Merb
2
+ module Rack
3
+ class Profiler < Merb::Rack::Middleware
4
+
5
+ def initialize(app, min=1, iter=1)
6
+ super(app)
7
+ @min, @iter = min, iter
8
+ end
9
+
10
+ def call(env)
11
+ __profile__("profile_output", @min, @iter) do
12
+ @app.call(env)
13
+ end
14
+ end
15
+
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,45 @@
1
+ module Merb
2
+ module Rack
3
+ class Static < Merb::Rack::Middleware
4
+
5
+ def initialize(app,directory)
6
+ super(app)
7
+ @static_server = ::Rack::File.new(directory)
8
+ end
9
+
10
+ def call(env)
11
+ path = env['PATH_INFO'] ? env['PATH_INFO'].chomp('/') : ""
12
+ cached_path = (path.empty? ? 'index' : path) + '.html'
13
+
14
+ if file_exist?(path) && env['REQUEST_METHOD'] =~ /GET|HEAD/ # Serve the file if it's there and the request method is GET or HEAD
15
+ serve_static(env)
16
+ elsif file_exist?(cached_path) && env['REQUEST_METHOD'] =~ /GET|HEAD/ # Serve the page cache if it's there and the request method is GET or HEAD
17
+ env['PATH_INFO'] = cached_path
18
+ serve_static(env)
19
+ elsif path =~ /favicon\.ico/
20
+ return [404, {"Content-Type"=>"text/html"}, "404 Not Found."]
21
+ else
22
+ @app.call(env)
23
+ end
24
+ end
25
+
26
+ # ==== Parameters
27
+ # path<String>:: The path to the file relative to the server root.
28
+ #
29
+ # ==== Returns
30
+ # Boolean:: True if file exists under the server root and is readable.
31
+ def file_exist?(path)
32
+ full_path = ::File.join(@static_server.root, ::Merb::Request.unescape(path))
33
+ ::File.file?(full_path) && ::File.readable?(full_path)
34
+ end
35
+
36
+ # ==== Parameters
37
+ # env<Hash>:: Environment variables to pass on to the server.
38
+ def serve_static(env)
39
+ env["PATH_INFO"] = ::Merb::Request.unescape(env["PATH_INFO"])
40
+ @static_server.call(env)
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,252 @@
1
+ require 'etc'
2
+ module Merb
3
+
4
+ # Server encapsulates the management of Merb daemons.
5
+ class Server
6
+ class << self
7
+
8
+ # Start a Merb server, in either foreground, daemonized or cluster mode.
9
+ #
10
+ # ==== Parameters
11
+ # port<~to_i>::
12
+ # The port to which the first server instance should bind to.
13
+ # Subsequent server instances bind to the immediately following ports.
14
+ # cluster<~to_i>::
15
+ # Number of servers to run in a cluster.
16
+ #
17
+ # ==== Alternatives
18
+ # If cluster is left out, then one process will be started. This process
19
+ # will be daemonized if Merb::Config[:daemonize] is true.
20
+ def start(port, cluster=nil)
21
+ @port = port
22
+ @cluster = cluster
23
+ if @cluster
24
+ @port.to_i.upto(@port.to_i + @cluster.to_i-1) do |port|
25
+ pidfile = pid_file(port)
26
+ pid = IO.read(pidfile).chomp.to_i if File.exist?(pidfile)
27
+
28
+ unless alive?(port)
29
+ remove_pid_file(port)
30
+ puts "Starting merb server on port #{port}, pid file: #{pidfile} and process id is #{pid}" if Merb::Config[:verbose]
31
+ daemonize(port)
32
+ else
33
+ raise "Merb is already running: port is #{port}, pid file: #{pidfile}, process id is #{pid}"
34
+ end
35
+ end
36
+ elsif Merb::Config[:daemonize]
37
+ pidfile = pid_file(port)
38
+ pid = IO.read(pidfile).chomp.to_i if File.exist?(pidfile)
39
+
40
+ unless alive?(@port)
41
+ remove_pid_file(@port)
42
+ puts "Daemonizing..." if Merb::Config[:verbose]
43
+ daemonize(@port)
44
+ else
45
+ raise "Merb is already running: port is #{port}, pid file: #{pidfile}, process id is #{pid}"
46
+ end
47
+ else
48
+ trap('TERM') { exit }
49
+ trap('INT') { puts "\nExiting"; exit }
50
+ puts "Running bootloaders..." if Merb::Config[:verbose]
51
+ BootLoader.run
52
+ puts "Starting Rack adapter..." if Merb::Config[:verbose]
53
+ Merb.adapter.start(Merb::Config.to_hash)
54
+ end
55
+ end
56
+
57
+ # ==== Parameters
58
+ # port<~to_s>:: The port to check for Merb instances on.
59
+ #
60
+ # ==== Returns
61
+ # Boolean::
62
+ # True if Merb is running on the specified port.
63
+ def alive?(port)
64
+ puts "About to check if port #{port} is alive..." if Merb::Config[:verbose]
65
+ pidfile = pid_file(port)
66
+ puts "Pidfile is #{pidfile}..." if Merb::Config[:verbose]
67
+ pid = IO.read(pidfile).chomp.to_i
68
+ puts "Process id is #{pid}" if Merb::Config[:verbose]
69
+ Process.kill(0, pid)
70
+ true
71
+ rescue
72
+ false
73
+ end
74
+
75
+ # ==== Parameters
76
+ # port<~to_s>:: The port of the Merb process to kill.
77
+ # sig<~to_s>:: The signal to send to the process. Defaults to 9.
78
+ #
79
+ # ==== Alternatives
80
+ # If you pass "all" as the port, the signal will be sent to all Merb
81
+ # processes.
82
+ def kill(port, sig=9)
83
+ Merb::BootLoader::BuildFramework.run
84
+ begin
85
+ pidfiles = port == "all" ?
86
+ pid_files : [ pid_file(port) ]
87
+
88
+ pidfiles.each do |f|
89
+ pid = IO.read(f).chomp.to_i
90
+ begin
91
+ Process.kill(sig, pid)
92
+ FileUtils.rm(f) if File.exist?(f)
93
+ puts "killed PID #{pid} with signal #{sig}"
94
+ rescue Errno::EINVAL
95
+ puts "Failed to kill PID #{pid}: '#{sig}' is an invalid or unsupported signal number."
96
+ rescue Errno::EPERM
97
+ puts "Failed to kill PID #{pid}: Insufficient permissions."
98
+ rescue Errno::ESRCH
99
+ puts "Failed to kill PID #{pid}: Process is deceased or zombie."
100
+ FileUtils.rm f
101
+ rescue Exception => e
102
+ puts "Failed to kill PID #{pid}: #{e.message}"
103
+ end
104
+ end
105
+ ensure
106
+ exit
107
+ end
108
+ end
109
+
110
+ # ==== Parameters
111
+ # port<~to_s>:: The port of the Merb process to daemonize.
112
+ def daemonize(port)
113
+ puts "About to fork..." if Merb::Config[:verbose]
114
+ fork do
115
+ Process.setsid
116
+ exit if fork
117
+ File.umask 0000
118
+ STDIN.reopen "/dev/null"
119
+ STDOUT.reopen "/dev/null", "a"
120
+ STDERR.reopen STDOUT
121
+ trap("TERM") { exit }
122
+ Dir.chdir Merb::Config[:merb_root]
123
+ at_exit { remove_pid_file(port) }
124
+ Merb::Config[:port] = port
125
+ BootLoader.run
126
+ Merb.adapter.start(Merb::Config.to_hash)
127
+ end
128
+ end
129
+
130
+ def change_privilege
131
+ if Merb::Config[:user]
132
+ if Merb::Config[:group]
133
+ puts "About to change privilege to group #{Merb::Config[:group]} and user #{Merb::Config[:user]}" if Merb::Config[:verbose]
134
+ _change_privilege(Merb::Config[:user], Merb::Config[:group])
135
+ else
136
+ puts "About to change privilege to user #{Merb::Config[:user]}" if Merb::Config[:verbose]
137
+ _change_privilege(Merb::Config[:user])
138
+ end
139
+ end
140
+ end
141
+
142
+ # Removes a PID file used by the server from the filesystem.
143
+ # This uses :pid_file options from configuration when provided
144
+ # or merb.<port>.pid in log directory by default.
145
+ #
146
+ # ==== Parameters
147
+ # port<~to_s>::
148
+ # The port of the Merb process to whom the the PID file belongs to.
149
+ #
150
+ # ==== Alternatives
151
+ # If Merb::Config[:pid_file] has been specified, that will be used
152
+ # instead of the port based PID file.
153
+ def remove_pid_file(port)
154
+ pidfile = pid_file(port)
155
+ puts "Removing pid file #{pidfile} (port is #{port})..."
156
+ FileUtils.rm(pidfile) if File.exist?(pidfile)
157
+ end
158
+
159
+ # Stores a PID file on the filesystem.
160
+ # This uses :pid_file options from configuration when provided
161
+ # or merb.<port>.pid in log directory by default.
162
+ #
163
+ # ==== Parameters
164
+ # port<~to_s>::
165
+ # The port of the Merb process to whom the the PID file belongs to.
166
+ #
167
+ # ==== Alternatives
168
+ # If Merb::Config[:pid_file] has been specified, that will be used
169
+ # instead of the port based PID file.
170
+ def store_pid(port)
171
+ pidfile = pid_file(port)
172
+ puts "Storing pid file to #{pidfile}..."
173
+ FileUtils.mkdir_p(File.dirname(pidfile)) unless File.directory?(File.dirname(pidfile))
174
+ puts "Created directory, writing process id..." if Merb::Config[:verbose]
175
+ File.open(pidfile, 'w'){ |f| f.write("#{Process.pid}") }
176
+ end
177
+
178
+ # Gets the pid file for the specified port.
179
+ #
180
+ # ==== Parameters
181
+ # port<~to_s>::
182
+ # The port of the Merb process to whom the the PID file belongs to.
183
+ #
184
+ # ==== Returns
185
+ # String::
186
+ # Location of pid file for specified port. If clustered and pid_file option
187
+ # is specified, it adds the port value to the path.
188
+ def pid_file(port)
189
+ if Merb::Config[:pid_file]
190
+ pidfile = Merb::Config[:pid_file]
191
+ if Merb::Config[:cluster]
192
+ ext = File.extname(Merb::Config[:pid_file])
193
+ base = File.basename(Merb::Config[:pid_file], ext)
194
+ dir = File.dirname(Merb::Config[:pid_file])
195
+ File.join(dir, "#{base}.#{port}#{ext}")
196
+ else
197
+ Merb::Config[:pid_file]
198
+ end
199
+ else
200
+ pidfile = Merb.log_path / "merb.#{port}.pid"
201
+ Merb.log_path / "merb.#{port}.pid"
202
+ end
203
+ end
204
+
205
+ # Get a list of the pid files.
206
+ #
207
+ # ==== Returns
208
+ # Array::
209
+ # List of pid file paths. If not clustered, array contains a single path.
210
+ def pid_files
211
+ if Merb::Config[:pid_file]
212
+ if Merb::Config[:cluster]
213
+ ext = File.extname(Merb::Config[:pid_file])
214
+ base = File.basename(Merb::Config[:pid_file], ext)
215
+ dir = File.dirname(Merb::Config[:pid_file])
216
+ Dir[dir / "#{base}.*#{ext}"]
217
+ else
218
+ [ Merb::Config[:pid_file] ]
219
+ end
220
+ else
221
+ Dir[Merb.log_path / "merb.*.pid"]
222
+ end
223
+ end
224
+
225
+ # Change privileges of the process to the specified user and group.
226
+ #
227
+ # ==== Parameters
228
+ # user<String>:: The user who should own the server process.
229
+ # group<String>:: The group who should own the server process.
230
+ #
231
+ # ==== Alternatives
232
+ # If group is left out, the user will be used as the group.
233
+ def _change_privilege(user, group=user)
234
+
235
+ puts "Changing privileges to #{user}:#{group}"
236
+
237
+ uid, gid = Process.euid, Process.egid
238
+ target_uid = Etc.getpwnam(user).uid
239
+ target_gid = Etc.getgrnam(group).gid
240
+
241
+ if uid != target_uid || gid != target_gid
242
+ # Change process ownership
243
+ Process.initgroups(user, target_gid)
244
+ Process::GID.change_privilege(target_gid)
245
+ Process::UID.change_privilege(target_uid)
246
+ end
247
+ rescue Errno::EPERM => e
248
+ puts "Couldn't change user and group to #{user}:#{group}: #{e}"
249
+ end
250
+ end
251
+ end
252
+ end