thorero-core 0.9.4.6
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 +20 -0
- data/README +21 -0
- data/Rakefile +352 -0
- 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/merb-core/logger.rb +202 -0
- 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 +542 -0
|
@@ -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
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
namespace :audit do
|
|
2
|
+
|
|
3
|
+
desc "Print out the named and anonymous routes"
|
|
4
|
+
task :routes => :merb_env do
|
|
5
|
+
seen = []
|
|
6
|
+
unless Merb::Router.named_routes.empty?
|
|
7
|
+
puts "Named Routes"
|
|
8
|
+
Merb::Router.named_routes.each do |name,route|
|
|
9
|
+
puts " #{name}: #{route}"
|
|
10
|
+
seen << route
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
puts "Anonymous Routes"
|
|
14
|
+
(Merb::Router.routes - seen).each do |route|
|
|
15
|
+
puts " #{route}"
|
|
16
|
+
end
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc "Print out all controllers"
|
|
21
|
+
task :controllers => :merb_env do
|
|
22
|
+
puts "\nControllers:\n\n"
|
|
23
|
+
abstract_controller_classes.each do |klass|
|
|
24
|
+
if klass.respond_to?(:subclasses_list)
|
|
25
|
+
puts "#{klass} < #{klass.superclass}"
|
|
26
|
+
subklasses = klass.subclasses_list.sort.map { |x| Object.full_const_get(x) }
|
|
27
|
+
unless subklasses.empty?
|
|
28
|
+
subklasses.each { |subklass| puts "- #{subklass}" }
|
|
29
|
+
else
|
|
30
|
+
puts "~ no subclasses"
|
|
31
|
+
end
|
|
32
|
+
puts
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
desc "Print out controllers and their actions (use CONTROLLER=Foo,Bar to be selective)"
|
|
38
|
+
task :actions => :merb_env do
|
|
39
|
+
puts "\nControllers and their actions:\n\n"
|
|
40
|
+
filter_controllers = ENV['CONTROLLER'] ? ENV['CONTROLLER'].split(',') : nil
|
|
41
|
+
abstract_controllers = abstract_controller_classes
|
|
42
|
+
classes = Merb::AbstractController.subclasses_list.sort.map { |x| Object.full_const_get(x) }
|
|
43
|
+
classes = classes.select { |k| k.name.in?(filter_controllers) } if filter_controllers
|
|
44
|
+
classes.each do |subklass|
|
|
45
|
+
next if subklass.in?(abstract_controllers) || !subklass.respond_to?(:callable_actions)
|
|
46
|
+
puts "#{subklass} < #{subklass.superclass}"
|
|
47
|
+
unless subklass.callable_actions.empty?
|
|
48
|
+
subklass.callable_actions.sort.each do |action, null|
|
|
49
|
+
if subklass.respond_to?(:action_argument_list)
|
|
50
|
+
arguments, defaults = subklass.action_argument_list[action]
|
|
51
|
+
args = arguments.map { |name, value| value ? "#{name} = #{value.inspect}" : name.to_s }.join(', ')
|
|
52
|
+
puts args.empty? ? "- #{action}" : "- #{action}(#{args})"
|
|
53
|
+
else
|
|
54
|
+
puts "- #{action}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
puts "~ no callable actions"
|
|
59
|
+
end
|
|
60
|
+
puts
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def abstract_controller_classes
|
|
65
|
+
ObjectSpace.classes.select { |x| x.superclass == Merb::AbstractController }.sort_by { |x| x.name }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Dir[File.dirname(__FILE__) / '*.rake'].each { |ext| load ext }
|