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,302 @@
|
|
1
|
+
module Merb
|
2
|
+
# ControllerExceptions are a way of simplifying controller code by placing
|
3
|
+
# exceptional logic back into the MVC pattern.
|
4
|
+
#
|
5
|
+
# When a ControllerException is raised within your application merb will
|
6
|
+
# attempt to re-route the request to your Exceptions controller to render
|
7
|
+
# the error in a friendly mannor.
|
8
|
+
#
|
9
|
+
# For example you might have an action in your app that raises NotFound
|
10
|
+
# if a some resource was not available
|
11
|
+
#
|
12
|
+
|
13
|
+
# def show
|
14
|
+
# product = Product.find(params[:id])
|
15
|
+
# raise NotFound if product.nil?
|
16
|
+
# [...]
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# This would halt execution of your action and re-route it over to your
|
20
|
+
# Exceptions controller which might look something like
|
21
|
+
#
|
22
|
+
# class Exceptions < Application
|
23
|
+
|
24
|
+
# def not_found
|
25
|
+
# render :layout => :none
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# As usual the not_found action will look for a template in
|
30
|
+
# app/views/exceptions/not_found.html.erb
|
31
|
+
#
|
32
|
+
# Note: All standard ControllerExceptions have an HTTP status code associated
|
33
|
+
# with them which is sent to the browser when the action it is rendered.
|
34
|
+
#
|
35
|
+
# Note: If you do not specifiy how to handle raised ControllerExceptions
|
36
|
+
# or an unhandlable exception occurs within your customised exception action
|
37
|
+
# then they will be rendered using the built-in error template
|
38
|
+
# in development mode this "built in" template will show stack-traces for
|
39
|
+
# any of the ServerError family of exceptions (you can force the stack-trace
|
40
|
+
# to display in production mode using the :exception_details config option in
|
41
|
+
# merb.yml)
|
42
|
+
#
|
43
|
+
#
|
44
|
+
# ==== Internal Exceptions
|
45
|
+
#
|
46
|
+
# Any other rogue errors (not ControllerExceptions) that occur during the
|
47
|
+
# execution of you app will be converted into the ControllerException
|
48
|
+
# InternalServerError, and like all ControllerExceptions can be caught
|
49
|
+
# on your Exceptions controller.
|
50
|
+
#
|
51
|
+
# InternalServerErrors return status 500, a common use for cusomizing this
|
52
|
+
# action might be to send emails to the development team, warning that their
|
53
|
+
# application have exploded. Mock example:
|
54
|
+
#
|
55
|
+
|
56
|
+
# def internal_server_error
|
57
|
+
# MySpecialMailer.deliver(
|
58
|
+
# "team@cowboys.com",
|
59
|
+
# "Exception occured at #{Time.now}",
|
60
|
+
# params[:exception])
|
61
|
+
# render 'Something is wrong, but the team are on it!'
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# Note: The special param[:exception] is available in all Exception actions
|
65
|
+
# and contains the ControllerException that was raised (this is handy if
|
66
|
+
# you want to display the associated message or display more detailed info)
|
67
|
+
#
|
68
|
+
#
|
69
|
+
# ==== Extending ControllerExceptions
|
70
|
+
#
|
71
|
+
# To extend the use of the ControllerExceptions one may extend any of the
|
72
|
+
# HTTPError classes.
|
73
|
+
#
|
74
|
+
# As an example we can create an exception called AdminAccessRequired.
|
75
|
+
#
|
76
|
+
# class AdminAccessRequired < Merb::ControllerExceptions::Unauthorized; end
|
77
|
+
#
|
78
|
+
# Add the required action to our Exceptions controller
|
79
|
+
#
|
80
|
+
# class Exceptions < Application
|
81
|
+
|
82
|
+
# def admin_access_required
|
83
|
+
# render
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# In app/views/exceptions/admin_access_required.rhtml
|
88
|
+
#
|
89
|
+
# <h1>You're not an administrator!</h1>
|
90
|
+
# <p>You tried to access <%= @tried_to_access %> but that URL is
|
91
|
+
# restricted to administrators.</p>
|
92
|
+
#
|
93
|
+
module ControllerExceptions
|
94
|
+
|
95
|
+
# Mapping of status code names to their numeric value.
|
96
|
+
STATUS_CODES = {}
|
97
|
+
|
98
|
+
class Base < StandardError #:doc:
|
99
|
+
|
100
|
+
# ==== Returns
|
101
|
+
# String:: The snake cased name of the error without the namespace.
|
102
|
+
def name; self.class.name; end
|
103
|
+
|
104
|
+
# === Returns
|
105
|
+
# Integer:: The status-code of the error.
|
106
|
+
def status; self.class.status; end
|
107
|
+
alias :to_i :status
|
108
|
+
|
109
|
+
class << self
|
110
|
+
|
111
|
+
# ==== Returns
|
112
|
+
# String:: The snake cased name of the class without the namespace.
|
113
|
+
def name
|
114
|
+
self.to_s.split('::').last.snake_case
|
115
|
+
end
|
116
|
+
|
117
|
+
# Get the actual status-code for an Exception class.
|
118
|
+
#
|
119
|
+
# As usual, this can come from a constant upwards in
|
120
|
+
# the inheritance chain.
|
121
|
+
#
|
122
|
+
# ==== Returns
|
123
|
+
# Fixnum:: The status code of this exception.
|
124
|
+
def status
|
125
|
+
const_get(:STATUS) rescue 0
|
126
|
+
end
|
127
|
+
alias :to_i :status
|
128
|
+
|
129
|
+
# Set the actual status-code for an Exception class.
|
130
|
+
#
|
131
|
+
# If possible, set the STATUS constant, and update
|
132
|
+
# any previously registered (inherited) status-code.
|
133
|
+
#
|
134
|
+
# ==== Parameters
|
135
|
+
# num<~to_i>:: The status code
|
136
|
+
def status=(num)
|
137
|
+
unless self.status?
|
138
|
+
register_status_code(self, num)
|
139
|
+
self.const_set(:STATUS, num.to_i)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# See if a status-code has been defined (on self explicitly).
|
144
|
+
#
|
145
|
+
# ==== Returns
|
146
|
+
# Boolean:: Whether the a status code has been set
|
147
|
+
def status?
|
148
|
+
self.const_defined?(:STATUS)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Registers any subclasses with status codes for easy lookup by
|
152
|
+
# set_status in Merb::Controller.
|
153
|
+
#
|
154
|
+
# Inheritance ensures this method gets inherited by any subclasses, so
|
155
|
+
# it goes all the way down the chain of inheritance.
|
156
|
+
#
|
157
|
+
# ==== Parameters
|
158
|
+
#
|
159
|
+
# subclass<Merb::ControllerExceptions::Base>::
|
160
|
+
# The Exception class that is inheriting from Merb::ControllerExceptions::Base
|
161
|
+
def inherited(subclass)
|
162
|
+
# don't set the constant yet - any class methods will be called after self.inherited
|
163
|
+
# unless self.status = ... is set explicitly, the status code will be inherited
|
164
|
+
register_status_code(subclass, self.status) if self.status?
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
# Register the status-code for an Exception class.
|
170
|
+
#
|
171
|
+
# ==== Parameters
|
172
|
+
# num<~to_i>:: The status code
|
173
|
+
def register_status_code(klass, code)
|
174
|
+
STATUS_CODES[klass.name.to_sym] = code.to_i
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
class Informational < Merb::ControllerExceptions::Base; end
|
181
|
+
|
182
|
+
class Continue < Merb::ControllerExceptions::Informational; self.status = 100; end
|
183
|
+
|
184
|
+
class SwitchingProtocols < Merb::ControllerExceptions::Informational; self.status = 101; end
|
185
|
+
|
186
|
+
class Successful < Merb::ControllerExceptions::Base; end
|
187
|
+
|
188
|
+
class OK < Merb::ControllerExceptions::Successful; self.status = 200; end
|
189
|
+
|
190
|
+
class Created < Merb::ControllerExceptions::Successful; self.status = 201; end
|
191
|
+
|
192
|
+
class Accepted < Merb::ControllerExceptions::Successful; self.status = 202; end
|
193
|
+
|
194
|
+
class NonAuthoritativeInformation < Merb::ControllerExceptions::Successful; self.status = 203; end
|
195
|
+
|
196
|
+
class NoContent < Merb::ControllerExceptions::Successful; self.status = 204; end
|
197
|
+
|
198
|
+
class ResetContent < Merb::ControllerExceptions::Successful; self.status = 205; end
|
199
|
+
|
200
|
+
class PartialContent < Merb::ControllerExceptions::Successful; self.status = 206; end
|
201
|
+
|
202
|
+
class Redirection < Merb::ControllerExceptions::Base; end
|
203
|
+
|
204
|
+
class MultipleChoices < Merb::ControllerExceptions::Redirection; self.status = 300; end
|
205
|
+
|
206
|
+
class MovedPermanently < Merb::ControllerExceptions::Redirection; self.status = 301; end
|
207
|
+
|
208
|
+
class MovedTemporarily < Merb::ControllerExceptions::Redirection; self.status = 302; end
|
209
|
+
|
210
|
+
class SeeOther < Merb::ControllerExceptions::Redirection; self.status = 303; end
|
211
|
+
|
212
|
+
class NotModified < Merb::ControllerExceptions::Redirection; self.status = 304; end
|
213
|
+
|
214
|
+
class UseProxy < Merb::ControllerExceptions::Redirection; self.status = 305; end
|
215
|
+
|
216
|
+
class TemporaryRedirect < Merb::ControllerExceptions::Redirection; self.status = 307; end
|
217
|
+
|
218
|
+
class ClientError < Merb::ControllerExceptions::Base; end
|
219
|
+
|
220
|
+
class BadRequest < Merb::ControllerExceptions::ClientError; self.status = 400; end
|
221
|
+
|
222
|
+
class MultiPartParseError < Merb::ControllerExceptions::BadRequest; end
|
223
|
+
|
224
|
+
class Unauthorized < Merb::ControllerExceptions::ClientError; self.status = 401; end
|
225
|
+
|
226
|
+
class PaymentRequired < Merb::ControllerExceptions::ClientError; self.status = 402; end
|
227
|
+
|
228
|
+
class Forbidden < Merb::ControllerExceptions::ClientError; self.status = 403; end
|
229
|
+
|
230
|
+
class NotFound < Merb::ControllerExceptions::ClientError; self.status = 404; end
|
231
|
+
|
232
|
+
class ActionNotFound < Merb::ControllerExceptions::NotFound; end
|
233
|
+
|
234
|
+
class TemplateNotFound < Merb::ControllerExceptions::NotFound; end
|
235
|
+
|
236
|
+
class LayoutNotFound < Merb::ControllerExceptions::NotFound; end
|
237
|
+
|
238
|
+
class MethodNotAllowed < Merb::ControllerExceptions::ClientError; self.status = 405; end
|
239
|
+
|
240
|
+
class NotAcceptable < Merb::ControllerExceptions::ClientError; self.status = 406; end
|
241
|
+
|
242
|
+
class ProxyAuthenticationRequired < Merb::ControllerExceptions::ClientError; self.status = 407; end
|
243
|
+
|
244
|
+
class RequestTimeout < Merb::ControllerExceptions::ClientError; self.status = 408; end
|
245
|
+
|
246
|
+
class Conflict < Merb::ControllerExceptions::ClientError; self.status = 409; end
|
247
|
+
|
248
|
+
class Gone < Merb::ControllerExceptions::ClientError; self.status = 410; end
|
249
|
+
|
250
|
+
class LengthRequired < Merb::ControllerExceptions::ClientError; self.status = 411; end
|
251
|
+
|
252
|
+
class PreconditionFailed < Merb::ControllerExceptions::ClientError; self.status = 412; end
|
253
|
+
|
254
|
+
class RequestEntityTooLarge < Merb::ControllerExceptions::ClientError; self.status = 413; end
|
255
|
+
|
256
|
+
class RequestURITooLarge < Merb::ControllerExceptions::ClientError; self.status = 414; end
|
257
|
+
|
258
|
+
class UnsupportedMediaType < Merb::ControllerExceptions::ClientError; self.status = 415; end
|
259
|
+
|
260
|
+
class RequestRangeNotSatisfiable < Merb::ControllerExceptions::ClientError; self.status = 416; end
|
261
|
+
|
262
|
+
class ExpectationFailed < Merb::ControllerExceptions::ClientError; self.status = 417; end
|
263
|
+
|
264
|
+
class ServerError < Merb::ControllerExceptions::Base; end
|
265
|
+
|
266
|
+
class NotImplemented < Merb::ControllerExceptions::ServerError; self.status = 501; end
|
267
|
+
|
268
|
+
class BadGateway < Merb::ControllerExceptions::ServerError; self.status = 502; end
|
269
|
+
|
270
|
+
class ServiceUnavailable < Merb::ControllerExceptions::ServerError; self.status = 503; end
|
271
|
+
|
272
|
+
class GatewayTimeout < Merb::ControllerExceptions::ServerError; self.status = 504; end
|
273
|
+
|
274
|
+
class HTTPVersionNotSupported < Merb::ControllerExceptions::ServerError; self.status = 505; end
|
275
|
+
|
276
|
+
class InternalServerError < Merb::ControllerExceptions::ServerError #:doc:
|
277
|
+
self.status = 500;
|
278
|
+
# DEFAULT_TEMPLATE = ::Merb::Dispatcher::DEFAULT_ERROR_TEMPLATE
|
279
|
+
def initialize(exception = nil)
|
280
|
+
@exception = exception
|
281
|
+
@coderay = CodeRay rescue nil
|
282
|
+
end
|
283
|
+
|
284
|
+
def backtrace
|
285
|
+
@exception ? @exception.backtrace : backtrace
|
286
|
+
end
|
287
|
+
|
288
|
+
def message
|
289
|
+
@exception ? @exception.message : message
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
# Required to show exceptions in the log file
|
295
|
+
#
|
296
|
+
# e<Exception>:: The exception that a message is being generated for
|
297
|
+
def self.exception(e)
|
298
|
+
"#{ e.message } - (#{ e.class })\n" <<
|
299
|
+
"#{(e.backtrace or []).join("\n")}"
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
class Merb::Controller < Merb::AbstractController
|
2
|
+
|
3
|
+
class_inheritable_accessor :_hidden_actions, :_shown_actions
|
4
|
+
self._hidden_actions ||= []
|
5
|
+
self._shown_actions ||= []
|
6
|
+
|
7
|
+
cattr_accessor :_subclasses, :_session_id_key, :_session_secret_key, :_session_expiry, :_session_cookie_domain
|
8
|
+
self._subclasses = Set.new
|
9
|
+
|
10
|
+
def self.subclasses_list() _subclasses end
|
11
|
+
|
12
|
+
self._session_secret_key = nil
|
13
|
+
self._session_id_key = Merb::Config[:session_id_key] || '_session_id'
|
14
|
+
self._session_expiry = Merb::Config[:session_expiry] || Merb::Const::WEEK * 2
|
15
|
+
self._session_cookie_domain = Merb::Config[:session_cookie_domain]
|
16
|
+
|
17
|
+
include Merb::ResponderMixin
|
18
|
+
include Merb::ControllerMixin
|
19
|
+
include Merb::AuthenticationMixin
|
20
|
+
|
21
|
+
attr_accessor :route
|
22
|
+
|
23
|
+
class << self
|
24
|
+
|
25
|
+
# ==== Parameters
|
26
|
+
# klass<Merb::Controller>::
|
27
|
+
# The Merb::Controller inheriting from the base class.
|
28
|
+
def inherited(klass)
|
29
|
+
_subclasses << klass.to_s
|
30
|
+
super
|
31
|
+
klass._template_root = Merb.dir_for(:view) unless self._template_root
|
32
|
+
end
|
33
|
+
|
34
|
+
# Hide each of the given methods from being callable as actions.
|
35
|
+
#
|
36
|
+
# ==== Parameters
|
37
|
+
# *names<~to-s>:: Actions that should be added to the list.
|
38
|
+
#
|
39
|
+
# ==== Returns
|
40
|
+
# Array[String]::
|
41
|
+
# An array of actions that should not be possible to dispatch to.
|
42
|
+
#
|
43
|
+
#---
|
44
|
+
# @public
|
45
|
+
def hide_action(*names)
|
46
|
+
self._hidden_actions = self._hidden_actions | names.map { |n| n.to_s }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Makes each of the given methods being callable as actions. You can use
|
50
|
+
# this to make methods included from modules callable as actions.
|
51
|
+
#
|
52
|
+
# ==== Parameters
|
53
|
+
# *names<~to-s>:: Actions that should be added to the list.
|
54
|
+
#
|
55
|
+
# ==== Returns
|
56
|
+
# Array[String]::
|
57
|
+
# An array of actions that should be dispatched to even if they would not
|
58
|
+
# otherwise be.
|
59
|
+
#
|
60
|
+
# ==== Example
|
61
|
+
# module Foo
|
62
|
+
# def self.included(base)
|
63
|
+
# base.show_action(:foo)
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# def foo
|
67
|
+
# # some actiony stuff
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# def foo_helper
|
71
|
+
# # this should not be an action
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
#---
|
76
|
+
# @public
|
77
|
+
def show_action(*names)
|
78
|
+
self._shown_actions = self._shown_actions | names.map {|n| n.to_s}
|
79
|
+
end
|
80
|
+
|
81
|
+
# The list of actions that are callable, after taking defaults,
|
82
|
+
# _hidden_actions and _shown_actions into consideration. It is calculated
|
83
|
+
# once, the first time an action is dispatched for this controller.
|
84
|
+
#
|
85
|
+
# ==== Returns
|
86
|
+
# SimpleSet[String]:: A set of actions that should be callable.
|
87
|
+
def callable_actions
|
88
|
+
@callable_actions ||= Extlib::SimpleSet.new(_callable_methods)
|
89
|
+
end
|
90
|
+
|
91
|
+
# This is a stub method so plugins can implement param filtering if they want.
|
92
|
+
#
|
93
|
+
# ==== Parameters
|
94
|
+
# params<Hash{Symbol => String}>:: A list of params
|
95
|
+
#
|
96
|
+
# ==== Returns
|
97
|
+
# Hash{Symbol => String}:: A new list of params, filtered as desired
|
98
|
+
#---
|
99
|
+
# @semipublic
|
100
|
+
def _filter_params(params)
|
101
|
+
params
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# All methods that are callable as actions.
|
107
|
+
#
|
108
|
+
# ==== Returns
|
109
|
+
# Array:: A list of method names that are also actions
|
110
|
+
def _callable_methods
|
111
|
+
callables = []
|
112
|
+
klass = self
|
113
|
+
begin
|
114
|
+
callables << (klass.public_instance_methods(false) + klass._shown_actions) - klass._hidden_actions
|
115
|
+
klass = klass.superclass
|
116
|
+
end until klass == Merb::AbstractController || klass == Object
|
117
|
+
callables.flatten.reject{|action| action =~ /^_.*/}
|
118
|
+
end
|
119
|
+
|
120
|
+
end # class << self
|
121
|
+
|
122
|
+
# The location to look for a template for a particular controller, context,
|
123
|
+
# and mime-type. This is overridden from AbstractController, which defines a
|
124
|
+
# version of this that does not involve mime-types.
|
125
|
+
#
|
126
|
+
# ==== Parameters
|
127
|
+
# context<~to_s>:: The name of the action or template basename that will be rendered.
|
128
|
+
# type<~to_s>::
|
129
|
+
# The mime-type of the template that will be rendered. Defaults to nil.
|
130
|
+
# controller<~to_s>::
|
131
|
+
# The name of the controller that will be rendered. Defaults to
|
132
|
+
# controller_name.
|
133
|
+
#
|
134
|
+
# ==== Notes
|
135
|
+
# By default, this renders ":controller/:action.:type". To change this,
|
136
|
+
# override it in your application class or in individual controllers.
|
137
|
+
#
|
138
|
+
#---
|
139
|
+
# @public
|
140
|
+
def _template_location(context, type = nil, controller = controller_name)
|
141
|
+
_conditionally_append_extension(controller ? "#{controller}/#{context}" : "#{context}", type)
|
142
|
+
end
|
143
|
+
|
144
|
+
# The location to look for a template and mime-type. This is overridden
|
145
|
+
# from AbstractController, which defines a version of this that does not
|
146
|
+
# involve mime-types.
|
147
|
+
#
|
148
|
+
# ==== Parameters
|
149
|
+
# template<String>::
|
150
|
+
# The absolute path to a template - without mime and template extension.
|
151
|
+
# The mime-type extension is optional - it will be appended from the
|
152
|
+
# current content type if it hasn't been added already.
|
153
|
+
# type<~to_s>::
|
154
|
+
# The mime-type of the template that will be rendered. Defaults to nil.
|
155
|
+
#
|
156
|
+
# @public
|
157
|
+
def _absolute_template_location(template, type)
|
158
|
+
_conditionally_append_extension(template, type)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Build a new controller.
|
162
|
+
#
|
163
|
+
# Sets the variables that came in through the dispatch as available to
|
164
|
+
# the controller.
|
165
|
+
#
|
166
|
+
# This method uses the :session_id_cookie_only and :query_string_whitelist
|
167
|
+
# configuration options. See CONFIG for more details.
|
168
|
+
#
|
169
|
+
# ==== Parameters
|
170
|
+
# request<Merb::Request>:: The Merb::Request that came in from Mongrel.
|
171
|
+
# status<Integer>:: An integer code for the status. Defaults to 200.
|
172
|
+
# headers<Hash{header => value}>::
|
173
|
+
# A hash of headers to start the controller with. These headers can be
|
174
|
+
# overridden later by the #headers method.
|
175
|
+
#---
|
176
|
+
# @semipublic
|
177
|
+
def initialize(request, status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
|
178
|
+
super()
|
179
|
+
@request, @_status, @headers = request, status, headers
|
180
|
+
end
|
181
|
+
|
182
|
+
# Dispatch the action.
|
183
|
+
#
|
184
|
+
# ==== Parameters
|
185
|
+
# action<~to_s>:: An action to dispatch to. Defaults to :index.
|
186
|
+
#
|
187
|
+
# ==== Returns
|
188
|
+
# String:: The string sent to the logger for time spent.
|
189
|
+
#
|
190
|
+
# ==== Raises
|
191
|
+
# ActionNotFound:: The requested action was not found in class.
|
192
|
+
#---
|
193
|
+
# @semipublic
|
194
|
+
def _dispatch(action=:index)
|
195
|
+
start = Time.now
|
196
|
+
if self.class.callable_actions.include?(action.to_s)
|
197
|
+
super(action)
|
198
|
+
else
|
199
|
+
raise ActionNotFound, "Action '#{action}' was not found in #{self.class}"
|
200
|
+
end
|
201
|
+
@_benchmarks[:action_time] = Time.now - start
|
202
|
+
end
|
203
|
+
|
204
|
+
attr_reader :request, :headers
|
205
|
+
|
206
|
+
def status
|
207
|
+
@_status
|
208
|
+
end
|
209
|
+
|
210
|
+
# Set the response status code.
|
211
|
+
#
|
212
|
+
# ==== Parameters
|
213
|
+
# s<Fixnum, Symbol>:: A status-code or named http-status
|
214
|
+
def status=(s)
|
215
|
+
if s.is_a?(Symbol) && STATUS_CODES.key?(s)
|
216
|
+
@_status = STATUS_CODES[s]
|
217
|
+
elsif s.is_a?(Fixnum)
|
218
|
+
@_status = s
|
219
|
+
else
|
220
|
+
raise ArgumentError, "Status should be of type Fixnum or Symbol, was #{s.class}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# ==== Returns
|
225
|
+
# Hash:: The parameters from the request object
|
226
|
+
def params() request.params end
|
227
|
+
|
228
|
+
# ==== Returns
|
229
|
+
# Merb::Cookies::
|
230
|
+
# A new Merb::Cookies instance representing the cookies that came in
|
231
|
+
# from the request object
|
232
|
+
#
|
233
|
+
# ==== Notes
|
234
|
+
# Headers are passed into the cookie object so that you can do:
|
235
|
+
# cookies[:foo] = "bar"
|
236
|
+
def cookies() @_cookies ||= _setup_cookies end
|
237
|
+
|
238
|
+
# ==== Returns
|
239
|
+
# Hash:: The session that was extracted from the request object.
|
240
|
+
def session() request.session end
|
241
|
+
|
242
|
+
# Hide any methods that may have been exposed as actions before.
|
243
|
+
hide_action(*_callable_methods)
|
244
|
+
|
245
|
+
private
|
246
|
+
|
247
|
+
# If not already added, add the proper mime extension to the template path.
|
248
|
+
def _conditionally_append_extension(template, type = nil)
|
249
|
+
type && !template.match(/\.#{type.to_s.escape_regexp}$/) ? "#{template}.#{type}" : template
|
250
|
+
end
|
251
|
+
|
252
|
+
# Create a default cookie jar, and pre-set a fixation cookie if fixation is enabled.
|
253
|
+
def _setup_cookies
|
254
|
+
::Merb::Cookies.new(request.cookies, @headers)
|
255
|
+
end
|
256
|
+
end
|