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.
- data/LICENSE +1 -1
- data/README +21 -0
- data/Rakefile +275 -108
- data/TODO +0 -0
- data/bin/merb +12 -0
- data/bin/merb-specs +5 -0
- data/docs/bootloading.dox +58 -0
- data/docs/documentation_standards +40 -0
- data/docs/merb-core-call-stack-diagram.mmap +0 -0
- data/docs/merb-core-call-stack-diagram.pdf +0 -0
- data/docs/merb-core-call-stack-diagram.png +0 -0
- data/docs/new_render_api +51 -0
- data/lib/merb-core.rb +603 -0
- data/lib/merb-core/autoload.rb +32 -0
- data/lib/merb-core/bootloader.rb +708 -0
- data/lib/merb-core/config.rb +303 -0
- data/lib/merb-core/constants.rb +43 -0
- data/lib/merb-core/controller/abstract_controller.rb +578 -0
- data/lib/merb-core/controller/exceptions.rb +302 -0
- data/lib/merb-core/controller/merb_controller.rb +256 -0
- data/lib/merb-core/controller/mime.rb +106 -0
- data/lib/merb-core/controller/mixins/authentication.rb +87 -0
- data/lib/merb-core/controller/mixins/controller.rb +290 -0
- data/lib/merb-core/controller/mixins/render.rb +481 -0
- data/lib/merb-core/controller/mixins/responder.rb +472 -0
- data/lib/merb-core/controller/template.rb +254 -0
- data/lib/merb-core/core_ext.rb +8 -0
- data/lib/merb-core/core_ext/kernel.rb +319 -0
- data/lib/merb-core/dispatch/cookies.rb +91 -0
- data/lib/merb-core/dispatch/dispatcher.rb +278 -0
- data/lib/merb-core/dispatch/exceptions.html.erb +303 -0
- data/lib/merb-core/dispatch/request.rb +603 -0
- data/lib/merb-core/dispatch/router.rb +179 -0
- data/lib/merb-core/dispatch/router/behavior.rb +867 -0
- data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
- data/lib/merb-core/dispatch/router/route.rb +321 -0
- data/lib/merb-core/dispatch/session.rb +78 -0
- data/lib/merb-core/dispatch/session/cookie.rb +168 -0
- data/lib/merb-core/dispatch/session/memcached.rb +184 -0
- data/lib/merb-core/dispatch/session/memory.rb +241 -0
- data/lib/merb-core/dispatch/worker.rb +28 -0
- data/lib/merb-core/gem_ext/erubis.rb +77 -0
- data/lib/{extlib → merb-core}/logger.rb +2 -2
- data/lib/merb-core/plugins.rb +59 -0
- data/lib/merb-core/rack.rb +21 -0
- data/lib/merb-core/rack/adapter.rb +44 -0
- data/lib/merb-core/rack/adapter/ebb.rb +25 -0
- data/lib/merb-core/rack/adapter/evented_mongrel.rb +26 -0
- data/lib/merb-core/rack/adapter/fcgi.rb +17 -0
- data/lib/merb-core/rack/adapter/irb.rb +118 -0
- data/lib/merb-core/rack/adapter/mongrel.rb +26 -0
- data/lib/merb-core/rack/adapter/runner.rb +28 -0
- data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +26 -0
- data/lib/merb-core/rack/adapter/thin.rb +39 -0
- data/lib/merb-core/rack/adapter/thin_turbo.rb +24 -0
- data/lib/merb-core/rack/adapter/webrick.rb +36 -0
- data/lib/merb-core/rack/application.rb +18 -0
- data/lib/merb-core/rack/handler/mongrel.rb +97 -0
- data/lib/merb-core/rack/middleware.rb +26 -0
- data/lib/merb-core/rack/middleware/path_prefix.rb +31 -0
- data/lib/merb-core/rack/middleware/profiler.rb +19 -0
- data/lib/merb-core/rack/middleware/static.rb +45 -0
- data/lib/merb-core/server.rb +252 -0
- data/lib/merb-core/tasks/audit.rake +68 -0
- data/lib/merb-core/tasks/merb.rb +1 -0
- data/lib/merb-core/tasks/merb_rake_helper.rb +12 -0
- data/lib/merb-core/test.rb +11 -0
- data/lib/merb-core/test/helpers.rb +9 -0
- data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
- data/lib/merb-core/test/helpers/multipart_request_helper.rb +175 -0
- data/lib/merb-core/test/helpers/request_helper.rb +344 -0
- data/lib/merb-core/test/helpers/route_helper.rb +33 -0
- data/lib/merb-core/test/helpers/view_helper.rb +121 -0
- data/lib/merb-core/test/matchers.rb +9 -0
- data/lib/merb-core/test/matchers/controller_matchers.rb +319 -0
- data/lib/merb-core/test/matchers/route_matchers.rb +136 -0
- data/lib/merb-core/test/matchers/view_matchers.rb +335 -0
- data/lib/merb-core/test/run_specs.rb +47 -0
- data/lib/merb-core/test/tasks/spectasks.rb +68 -0
- data/lib/merb-core/test/test_ext/hpricot.rb +32 -0
- data/lib/merb-core/test/test_ext/object.rb +14 -0
- data/lib/merb-core/test/test_ext/string.rb +14 -0
- data/lib/merb-core/vendor/facets.rb +2 -0
- data/lib/merb-core/vendor/facets/dictionary.rb +433 -0
- data/lib/merb-core/vendor/facets/inflect.rb +345 -0
- data/lib/merb-core/version.rb +11 -0
- data/spec/private/config/adapter_spec.rb +32 -0
- data/spec/private/config/config_spec.rb +202 -0
- data/spec/private/config/environment_spec.rb +13 -0
- data/spec/private/config/spec_helper.rb +1 -0
- data/spec/private/core_ext/kernel_spec.rb +169 -0
- data/spec/private/dispatch/bootloader_spec.rb +24 -0
- data/spec/private/dispatch/cookies_spec.rb +107 -0
- data/spec/private/dispatch/dispatch_spec.rb +35 -0
- data/spec/private/dispatch/fixture/app/controllers/application.rb +4 -0
- data/spec/private/dispatch/fixture/app/controllers/exceptions.rb +27 -0
- data/spec/private/dispatch/fixture/app/controllers/foo.rb +21 -0
- data/spec/private/dispatch/fixture/app/helpers/global_helpers.rb +8 -0
- data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +37 -0
- data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +216 -0
- data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +38 -0
- data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +40 -0
- data/spec/private/dispatch/fixture/app/views/foo/bar.html.erb +0 -0
- data/spec/private/dispatch/fixture/app/views/layout/application.html.erb +11 -0
- data/spec/private/dispatch/fixture/config/black_hole.rb +12 -0
- data/spec/private/dispatch/fixture/config/environments/development.rb +6 -0
- data/spec/private/dispatch/fixture/config/environments/production.rb +5 -0
- data/spec/private/dispatch/fixture/config/environments/test.rb +6 -0
- data/spec/private/dispatch/fixture/config/init.rb +45 -0
- data/spec/private/dispatch/fixture/config/rack.rb +11 -0
- data/spec/private/dispatch/fixture/config/router.rb +35 -0
- data/spec/private/dispatch/fixture/log/merb_test.log +1874 -0
- data/spec/private/dispatch/fixture/public/images/merb.jpg +0 -0
- data/spec/private/dispatch/fixture/public/merb.fcgi +4 -0
- data/spec/private/dispatch/fixture/public/stylesheets/master.css +119 -0
- data/spec/private/dispatch/route_params_spec.rb +24 -0
- data/spec/private/dispatch/session_mixin_spec.rb +47 -0
- data/spec/private/dispatch/spec_helper.rb +1 -0
- data/spec/private/plugins/plugin_spec.rb +166 -0
- data/spec/private/rack/application_spec.rb +49 -0
- data/spec/private/router/behavior_spec.rb +60 -0
- data/spec/private/router/fixture/log/merb_test.log +139 -0
- data/spec/private/router/route_spec.rb +414 -0
- data/spec/private/router/router_spec.rb +175 -0
- data/spec/private/vendor/facets/plural_spec.rb +564 -0
- data/spec/private/vendor/facets/singular_spec.rb +489 -0
- data/spec/public/DEFINITIONS +11 -0
- data/spec/public/abstract_controller/controllers/alt_views/layout/application.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_string_controller_layout.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_template_controller_layout.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/show.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/partial/basic_partial_with_multiple_roots/_partial.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_and_custom_location/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_inherited/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/cousins.rb +41 -0
- data/spec/public/abstract_controller/controllers/display.rb +54 -0
- data/spec/public/abstract_controller/controllers/filters.rb +193 -0
- data/spec/public/abstract_controller/controllers/helpers.rb +41 -0
- data/spec/public/abstract_controller/controllers/partial.rb +121 -0
- data/spec/public/abstract_controller/controllers/render.rb +113 -0
- data/spec/public/abstract_controller/controllers/views/helpers/capture/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/helpers/capture_eq/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/helpers/capture_with_args/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/helpers/concat/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/layout/alt.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/layout/custom.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object_with_action/new.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_app_layout/index.erb +0 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_custom_layout/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/show.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_two_throw_contents/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/another_directory/_partial.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/basic_partial/_partial.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/basic_partial/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/basic_partial_with_multiple_roots/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_first.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_second.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/nested_partial/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_in_another_directory/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/_collection.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/_collection.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/_collection.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/_collection.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/_variables.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/_both.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/_partial.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/_with_partial.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/_with_partial.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_partial/_with_partial.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/partial/with_partial/index.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/test_display/foo.html.erb +1 -0
- data/spec/public/abstract_controller/controllers/views/test_render/foo.html.erb +0 -0
- data/spec/public/abstract_controller/controllers/views/wonderful/index.erb +1 -0
- data/spec/public/abstract_controller/display_spec.rb +33 -0
- data/spec/public/abstract_controller/filter_spec.rb +106 -0
- data/spec/public/abstract_controller/helper_spec.rb +21 -0
- data/spec/public/abstract_controller/partial_spec.rb +61 -0
- data/spec/public/abstract_controller/render_spec.rb +90 -0
- data/spec/public/abstract_controller/spec_helper.rb +31 -0
- data/spec/public/boot_loader/boot_loader_spec.rb +33 -0
- data/spec/public/boot_loader/spec_helper.rb +1 -0
- data/spec/public/controller/authentication_spec.rb +103 -0
- data/spec/public/controller/base_spec.rb +36 -0
- data/spec/public/controller/controllers/authentication.rb +45 -0
- data/spec/public/controller/controllers/base.rb +36 -0
- data/spec/public/controller/controllers/display.rb +118 -0
- data/spec/public/controller/controllers/redirect.rb +30 -0
- data/spec/public/controller/controllers/responder.rb +93 -0
- data/spec/public/controller/controllers/url.rb +7 -0
- data/spec/public/controller/controllers/views/layout/custom.html.erb +1 -0
- data/spec/public/controller/controllers/views/layout/custom_arg.html.erb +1 -0
- data/spec/public/controller/controllers/views/layout/custom_arg.json.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.xml.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.xml.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/index.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/no_layout.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template_argument/index.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/html_default/index.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/layout/custom.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.xml.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.html.erb +1 -0
- data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.js.erb +1 -0
- data/spec/public/controller/display_spec.rb +84 -0
- data/spec/public/controller/redirect_spec.rb +27 -0
- data/spec/public/controller/responder_spec.rb +163 -0
- data/spec/public/controller/spec_helper.rb +11 -0
- data/spec/public/controller/url_spec.rb +180 -0
- data/spec/public/core/merb_core_spec.rb +45 -0
- data/spec/public/core_ext/class_spec.rb +91 -0
- data/spec/public/core_ext/fixtures/core_ext_dependency.rb +2 -0
- data/spec/public/core_ext/kernel_spec.rb +9 -0
- data/spec/public/core_ext/spec_helper.rb +1 -0
- data/spec/public/directory_structure/directory/app/controllers/application.rb +3 -0
- data/spec/public/directory_structure/directory/app/controllers/base.rb +13 -0
- data/spec/public/directory_structure/directory/app/controllers/custom.rb +19 -0
- data/spec/public/directory_structure/directory/app/views/base/template.html.erb +1 -0
- data/spec/public/directory_structure/directory/app/views/wonderful/template.erb +1 -0
- data/spec/public/directory_structure/directory/config/router.rb +3 -0
- data/spec/public/directory_structure/directory/log/merb_test.log +562 -0
- data/spec/public/directory_structure/directory_spec.rb +44 -0
- data/spec/public/logger/logger_spec.rb +181 -0
- data/spec/public/logger/spec_helper.rb +1 -0
- data/spec/public/reloading/directory/app/controllers/application.rb +3 -0
- data/spec/public/reloading/directory/app/controllers/reload.rb +6 -0
- data/spec/public/reloading/directory/config/init.rb +2 -0
- data/spec/public/reloading/directory/log/merb_test.log +138 -0
- data/spec/public/reloading/reload_spec.rb +103 -0
- data/spec/public/request/multipart_spec.rb +41 -0
- data/spec/public/request/request_spec.rb +228 -0
- data/spec/public/router/default_spec.rb +21 -0
- data/spec/public/router/deferred_spec.rb +22 -0
- data/spec/public/router/fixation_spec.rb +27 -0
- data/spec/public/router/fixture/log/merb_test.log +1556 -0
- data/spec/public/router/namespace_spec.rb +113 -0
- data/spec/public/router/nested_matches_spec.rb +97 -0
- data/spec/public/router/nested_resources_spec.rb +41 -0
- data/spec/public/router/resource_spec.rb +37 -0
- data/spec/public/router/resources_spec.rb +82 -0
- data/spec/public/router/spec_helper.rb +90 -0
- data/spec/public/router/special_spec.rb +61 -0
- data/spec/public/router/string_spec.rb +61 -0
- data/spec/public/template/template_spec.rb +104 -0
- data/spec/public/template/templates/error.html.erb +2 -0
- data/spec/public/template/templates/template.html.erb +1 -0
- data/spec/public/template/templates/template.html.myt +1 -0
- data/spec/public/test/controller_matchers_spec.rb +402 -0
- data/spec/public/test/controllers/controller_assertion_mock.rb +7 -0
- data/spec/public/test/controllers/dispatch_controller.rb +11 -0
- data/spec/public/test/controllers/spec_helper_controller.rb +38 -0
- data/spec/public/test/multipart_request_helper_spec.rb +159 -0
- data/spec/public/test/multipart_upload_text_file.txt +1 -0
- data/spec/public/test/request_helper_spec.rb +221 -0
- data/spec/public/test/route_helper_spec.rb +71 -0
- data/spec/public/test/route_matchers_spec.rb +162 -0
- data/spec/public/test/view_helper_spec.rb +96 -0
- data/spec/public/test/view_matchers_spec.rb +183 -0
- data/spec/spec_helper.rb +68 -0
- metadata +493 -41
- data/README.txt +0 -3
- data/lib/extlib.rb +0 -32
- data/lib/extlib/assertions.rb +0 -8
- data/lib/extlib/blank.rb +0 -42
- data/lib/extlib/class.rb +0 -175
- data/lib/extlib/hash.rb +0 -410
- data/lib/extlib/hook.rb +0 -366
- data/lib/extlib/inflection.rb +0 -141
- data/lib/extlib/lazy_array.rb +0 -106
- data/lib/extlib/mash.rb +0 -143
- data/lib/extlib/module.rb +0 -37
- data/lib/extlib/object.rb +0 -165
- data/lib/extlib/object_space.rb +0 -13
- data/lib/extlib/pathname.rb +0 -5
- data/lib/extlib/pooling.rb +0 -233
- data/lib/extlib/rubygems.rb +0 -38
- data/lib/extlib/simple_set.rb +0 -39
- data/lib/extlib/string.rb +0 -132
- data/lib/extlib/struct.rb +0 -8
- data/lib/extlib/tasks/release.rb +0 -9
- data/lib/extlib/time.rb +0 -12
- data/lib/extlib/version.rb +0 -3
- 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
|