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,52 @@
|
|
1
|
+
module Merb
|
2
|
+
|
3
|
+
class Router
|
4
|
+
# Cache procs for future reference in eval statement
|
5
|
+
class CachedProc
|
6
|
+
@@index = 0
|
7
|
+
@@list = []
|
8
|
+
|
9
|
+
attr_accessor :cache, :index
|
10
|
+
|
11
|
+
# ==== Parameters
|
12
|
+
# cache<Proc>:: The block of code to cache.
|
13
|
+
def initialize(cache)
|
14
|
+
@cache, @index = cache, CachedProc.register(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
# ==== Returns
|
18
|
+
# String:: The CachedProc object in a format embeddable within a string.
|
19
|
+
def to_s
|
20
|
+
"CachedProc[#{@index}].cache"
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
|
25
|
+
# ==== Parameters
|
26
|
+
# cached_code<CachedProc>:: The cached code to register.
|
27
|
+
#
|
28
|
+
# ==== Returns
|
29
|
+
# Fixnum:: The index of the newly registered CachedProc.
|
30
|
+
def register(cached_code)
|
31
|
+
CachedProc[@@index] = cached_code
|
32
|
+
@@index += 1
|
33
|
+
@@index - 1
|
34
|
+
end
|
35
|
+
|
36
|
+
# Sets the cached code for a specific index.
|
37
|
+
#
|
38
|
+
# ==== Parameters
|
39
|
+
# index<Fixnum>:: The index of the cached code to set.
|
40
|
+
# code<CachedProc>:: The cached code to set.
|
41
|
+
def []=(index, code) @@list[index] = code end
|
42
|
+
|
43
|
+
# ==== Parameters
|
44
|
+
# index<Fixnum>:: The index of the cached code to retrieve.
|
45
|
+
#
|
46
|
+
# ==== Returns
|
47
|
+
# CachedProc:: The cached code at index.
|
48
|
+
def [](index) @@list[index] end
|
49
|
+
end
|
50
|
+
end # CachedProc
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
require 'merb-core/controller/mixins/responder'
|
2
|
+
module Merb
|
3
|
+
|
4
|
+
class Router
|
5
|
+
# Route instances incapsulate information about particular route
|
6
|
+
# definition. Route definition ties
|
7
|
+
# number of conditions (URL match, HTTP request method) with
|
8
|
+
# resulting hash of route parameters:
|
9
|
+
# controller, action, format and named parameters
|
10
|
+
# from the URL.
|
11
|
+
#
|
12
|
+
# The following routes definition:
|
13
|
+
#
|
14
|
+
# Merb::Router.prepare do |r|
|
15
|
+
# r.match("api/:action/:token.:format").to(:controller => "dev").fixatable
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# maps URL matching pattern to controller named "dev"
|
19
|
+
# and specifies fixation for that route. Path and request method are
|
20
|
+
# route conditions, controller name, action name, format and
|
21
|
+
# value of segment we decided to call :token are route parameters.
|
22
|
+
#
|
23
|
+
# ==== How route definitions are used.
|
24
|
+
#
|
25
|
+
# When routes are compiled, each route produces
|
26
|
+
# a string with eval-able if/elsif condition statement.
|
27
|
+
# This statement together with others constructs body
|
28
|
+
# of Merb::Router.match method.
|
29
|
+
# Condition statements are Ruby code in form of string.
|
30
|
+
#
|
31
|
+
# ==== Segments.
|
32
|
+
#
|
33
|
+
# Route definitions use conventional syntax for named parameters.
|
34
|
+
# This splits route path into segments. Static (not changing) segments
|
35
|
+
# represented internally as strings, named parameters are stored
|
36
|
+
# as symbols and called symbol segments. Symbol segments
|
37
|
+
# map to groups in regular expression in resulting condition statement.
|
38
|
+
#
|
39
|
+
# ==== Route conditions.
|
40
|
+
#
|
41
|
+
# Because route conditions include path matching,
|
42
|
+
# regular expression is created from string that uses
|
43
|
+
# :segment format to fetch groups and assign them to
|
44
|
+
# named parameters. This regular expression is used
|
45
|
+
# to produce compiled statement mentioned above.
|
46
|
+
#
|
47
|
+
# Route conditions may also include
|
48
|
+
# user agent. Symbol segments
|
49
|
+
#
|
50
|
+
# Here is example of Route conditions:
|
51
|
+
# {
|
52
|
+
# :path => /^\/continents\/?(\.([^\/.,;?]+))?$/,
|
53
|
+
# :method => /^get$/
|
54
|
+
# }
|
55
|
+
#
|
56
|
+
#
|
57
|
+
# ==== Route parameters.
|
58
|
+
#
|
59
|
+
# Route parameters is a Hash with controller name,
|
60
|
+
# action name and parameters key/value pairs.
|
61
|
+
# It is then merged with request.params hash.
|
62
|
+
#
|
63
|
+
# Example of route parameters:
|
64
|
+
#
|
65
|
+
# {
|
66
|
+
# :action => "\"index\"",
|
67
|
+
# :format => "path2",
|
68
|
+
# :controller => "\"continents\""
|
69
|
+
# }
|
70
|
+
#
|
71
|
+
# Router takes first matching route and uses it's parameters
|
72
|
+
# to dispatch request to certain controller and action.
|
73
|
+
#
|
74
|
+
# ==== Behavior
|
75
|
+
#
|
76
|
+
# Each route has utility collaborator called behavior
|
77
|
+
# that incapsulates additional information about route
|
78
|
+
# (like namespace or if route is deferred) and also
|
79
|
+
# provides utility methods.
|
80
|
+
#
|
81
|
+
# ==== Route registration.
|
82
|
+
#
|
83
|
+
# When route is added to set of routes, it is called route
|
84
|
+
# registration. Registred route knows it's index in routes set.
|
85
|
+
#
|
86
|
+
# ==== Fixation
|
87
|
+
# Fixatable routes allow setting of session key from GET params
|
88
|
+
# found in incoming request. This is very useful to allow certain
|
89
|
+
# URLs to be used by rich media applications and other kinds
|
90
|
+
# of clients that have no other way of passing session identifier.
|
91
|
+
#
|
92
|
+
# ==== Conditional block.
|
93
|
+
# Conditional block is anonymous function that is evaluated
|
94
|
+
# when deferred routes are processed. Unless route is deferred,
|
95
|
+
# it has no condition block.
|
96
|
+
class Route
|
97
|
+
attr_reader :conditions, :conditional_block
|
98
|
+
attr_reader :params, :behavior, :segments, :index, :symbol
|
99
|
+
|
100
|
+
# ==== Parameters
|
101
|
+
# conditions<Hash>:: Conditions for the route.
|
102
|
+
# params<Hash>:: Parameters for the route.
|
103
|
+
# behavior<Merb::Router::Behavior>::
|
104
|
+
# The associated behavior. Defaults to nil.
|
105
|
+
# &conditional_block::
|
106
|
+
# A block with the conditions to be met for the route to take effect.
|
107
|
+
def initialize(conditions, params, behavior = nil, &conditional_block)
|
108
|
+
@conditions, @params, @behavior = conditions, params, behavior
|
109
|
+
@conditional_block = conditional_block
|
110
|
+
@fixation=false
|
111
|
+
if @behavior && (path = @behavior.merged_original_conditions[:path])
|
112
|
+
@segments = segments_from_path(path)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# ==== Returns
|
117
|
+
# Boolean:: True if fixation is allowed.
|
118
|
+
def allow_fixation?
|
119
|
+
@fixation
|
120
|
+
end
|
121
|
+
|
122
|
+
# ==== Parameters
|
123
|
+
# enabled<Boolean>:: True enables fixation on the route.
|
124
|
+
def fixatable(enable=true)
|
125
|
+
@fixation = enable
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
# Concatenates all route segments and returns result.
|
130
|
+
# Symbol segments have colon preserved.
|
131
|
+
#
|
132
|
+
# ==== Returns
|
133
|
+
# String:: The route as a string, e.g. "admin/:controller/:id".
|
134
|
+
def to_s
|
135
|
+
(segments || []).inject('') do |str,seg|
|
136
|
+
str << (seg.is_a?(Symbol) ? ":#{seg}" : seg)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Registers the route in the Router.routes array.
|
141
|
+
# After registration route has index.
|
142
|
+
def register
|
143
|
+
@index = Router.routes.size
|
144
|
+
Router.routes << self
|
145
|
+
self
|
146
|
+
end
|
147
|
+
|
148
|
+
# ==== Returns
|
149
|
+
# Array:: All the symbols in the segments array.
|
150
|
+
def symbol_segments
|
151
|
+
(segments || []).select{ |s| s.is_a?(Symbol) }
|
152
|
+
end
|
153
|
+
|
154
|
+
# Turn a path into string and symbol segments so it can be reconstructed,
|
155
|
+
# as in the case of a named route.
|
156
|
+
#
|
157
|
+
# ==== Parameters
|
158
|
+
# path<String>:: The path to split into segments.
|
159
|
+
#
|
160
|
+
# ==== Returns
|
161
|
+
# Array:: The Symbol and String segments for the path.
|
162
|
+
def segments_from_path(path)
|
163
|
+
# Remove leading ^ and trailing $ from each segment (left-overs from regexp joining)
|
164
|
+
strip = proc { |str| str.gsub(/^\^/, '').gsub(/\$$/, '') }
|
165
|
+
segments = []
|
166
|
+
while match = (path.match(SEGMENT_REGEXP))
|
167
|
+
segments << strip[match.pre_match] unless match.pre_match.empty?
|
168
|
+
segments << match[2].intern
|
169
|
+
path = strip[match.post_match]
|
170
|
+
end
|
171
|
+
segments << strip[path] unless path.empty?
|
172
|
+
segments
|
173
|
+
end
|
174
|
+
|
175
|
+
# Names this route in Router. Name must be a Symbol.
|
176
|
+
#
|
177
|
+
# ==== Parameters
|
178
|
+
# symbol<Symbol>:: The name of the route.
|
179
|
+
#
|
180
|
+
# ==== Raises
|
181
|
+
# ArgumentError:: symbol is not a Symbol.
|
182
|
+
def name(symbol = nil)
|
183
|
+
raise ArgumentError unless (@symbol = symbol).is_a?(Symbol)
|
184
|
+
Router.named_routes[@symbol] = self
|
185
|
+
end
|
186
|
+
|
187
|
+
# ==== Returns
|
188
|
+
# Boolean::
|
189
|
+
# True if this route is a regexp, i.e. its behavior or one of the
|
190
|
+
# behavior's ancestors is a regexp.
|
191
|
+
def regexp?
|
192
|
+
@regexp ||= behavior.regexp? || behavior.ancestors.any? { |a| a.regexp? }
|
193
|
+
end
|
194
|
+
|
195
|
+
# Generates URL using route segments and given parameters.
|
196
|
+
# If parameter value responds to :to_param, it is called.
|
197
|
+
#
|
198
|
+
# ==== Parameters
|
199
|
+
# params<Hash>:: Optional parameters for the route.
|
200
|
+
# fallback<Hash>:: Optional parameters for the fallback route.
|
201
|
+
#
|
202
|
+
# ==== Returns
|
203
|
+
# String::
|
204
|
+
# The URL corresponding to the params, using the stored route segments
|
205
|
+
# for reconstruction of the URL.
|
206
|
+
def generate(params = {}, fallback = {})
|
207
|
+
raise "Cannot generate regexp Routes" if regexp?
|
208
|
+
query_params = params.dup if params.is_a? Hash
|
209
|
+
url = @segments.map do |segment|
|
210
|
+
value =
|
211
|
+
if segment.is_a? Symbol
|
212
|
+
if params.is_a? Hash
|
213
|
+
if segment.to_s =~ /_id/ && params[:id].respond_to?(segment)
|
214
|
+
params[segment] = params[:id].send(segment)
|
215
|
+
end
|
216
|
+
query_params.delete segment
|
217
|
+
params[segment] || fallback[segment]
|
218
|
+
else
|
219
|
+
if segment == :id && params.respond_to?(:to_param)
|
220
|
+
params.to_param
|
221
|
+
elsif segment == :id && params.is_a?(Fixnum)
|
222
|
+
params
|
223
|
+
elsif params.respond_to?(segment)
|
224
|
+
params.send(segment)
|
225
|
+
else
|
226
|
+
fallback[segment]
|
227
|
+
end
|
228
|
+
end
|
229
|
+
elsif segment.respond_to? :to_s
|
230
|
+
segment
|
231
|
+
else
|
232
|
+
raise "Segment type '#{segment.class}' can't be converted to a string"
|
233
|
+
end
|
234
|
+
(value.respond_to?(:to_param) ? value.to_param : value).to_s.unescape_regexp
|
235
|
+
end.join
|
236
|
+
if query_params && format = query_params.delete(:format)
|
237
|
+
format = fallback[:format] if format == :current
|
238
|
+
url += ".#{format}"
|
239
|
+
end
|
240
|
+
if query_params && !query_params.empty?
|
241
|
+
url += "?" + Merb::Request.params_to_query_string(query_params)
|
242
|
+
end
|
243
|
+
url
|
244
|
+
end
|
245
|
+
|
246
|
+
# Generates and returns if statement used to
|
247
|
+
# construct final condition statement of the route.
|
248
|
+
#
|
249
|
+
# ==== Params
|
250
|
+
# params_as_string<String>::
|
251
|
+
# The params hash as a string, e.g. ":foo => 'bar'".
|
252
|
+
#
|
253
|
+
# ==== Returns
|
254
|
+
# Array:: All the conditions as eval'able strings.
|
255
|
+
def if_conditions(params_as_string)
|
256
|
+
cond = []
|
257
|
+
condition_string = proc do |key, value, regexp_string|
|
258
|
+
max = Behavior.count_parens_up_to(value.source, value.source.size)
|
259
|
+
captures = max == 0 ? "" : (1..max).to_a.map{ |n| "#{key}#{n}" }.join(", ") + " = " +
|
260
|
+
(1..max).to_a.map{ |n| "$#{n}"}.join(", ")
|
261
|
+
" (#{value.inspect} =~ #{regexp_string}) #{" && (" + captures + ")" unless captures.empty?}"
|
262
|
+
end
|
263
|
+
@conditions.each_pair do |key, value|
|
264
|
+
|
265
|
+
# Note: =~ is slightly faster than .match
|
266
|
+
cond << case key
|
267
|
+
when :path then condition_string[key, value, "cached_path"]
|
268
|
+
when :method then condition_string[key, value, "cached_method"]
|
269
|
+
else condition_string[key, value, "request.#{key}.to_s"]
|
270
|
+
end
|
271
|
+
end
|
272
|
+
if @conditional_block
|
273
|
+
str = " # #{@conditional_block.inspect.scan(/@([^>]+)/).flatten.first}\n"
|
274
|
+
str << " (block_result = #{CachedProc.new(@conditional_block)}.call(request, params.merge({#{params_as_string}})))" if @conditional_block
|
275
|
+
cond << str
|
276
|
+
end
|
277
|
+
cond
|
278
|
+
end
|
279
|
+
|
280
|
+
# Compiles the route to a form used by Merb::Router. This form sometimes
|
281
|
+
# referred as condition statement of the route.
|
282
|
+
#
|
283
|
+
# ==== Parameters
|
284
|
+
# first<Boolean>::
|
285
|
+
# True if this is the first route in set of routes. Defaults to false.
|
286
|
+
#
|
287
|
+
# ==== Returns
|
288
|
+
# String:: The code corresponding to the route in a form suited for eval.
|
289
|
+
def compile(first = false)
|
290
|
+
code = ""
|
291
|
+
default_params = { :action => "index" }
|
292
|
+
get_value = proc do |key|
|
293
|
+
if default_params.has_key?(key) && params[key][0] != ?"
|
294
|
+
"#{params[key]} || \"#{default_params[key]}\""
|
295
|
+
else
|
296
|
+
"#{params[key]}"
|
297
|
+
end
|
298
|
+
end
|
299
|
+
params_as_string = params.keys.map { |k| "#{k.inspect} => #{get_value[k]}" }.join(', ')
|
300
|
+
code << " els" unless first
|
301
|
+
code << "if # #{@behavior.merged_original_conditions.inspect} \n"
|
302
|
+
code << if_conditions(params_as_string).join(" && ") << "\n"
|
303
|
+
code << " # then\n"
|
304
|
+
if @conditional_block
|
305
|
+
code << " [#{@index.inspect}, block_result]\n"
|
306
|
+
else
|
307
|
+
code << " [#{@index.inspect}, {#{params_as_string}}]\n"
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
# Prints a trace of the behavior for this route.
|
312
|
+
def behavior_trace
|
313
|
+
if @behavior
|
314
|
+
puts @behavior.send(:ancestors).reverse.map{|a| a.inspect}.join("\n"); puts @behavior.inspect; puts
|
315
|
+
else
|
316
|
+
puts "No behavior to trace #{self}"
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end # Route
|
320
|
+
end
|
321
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Merb
|
2
|
+
|
3
|
+
module SessionMixin
|
4
|
+
# Sets the session id cookie, along with the correct
|
5
|
+
# expiry and domain -- used for new or reset sessions
|
6
|
+
def set_session_id_cookie(key)
|
7
|
+
options = {}
|
8
|
+
options[:value] = key
|
9
|
+
options[:expires] = Time.now + _session_expiry if _session_expiry > 0
|
10
|
+
options[:domain] = _session_cookie_domain if _session_cookie_domain
|
11
|
+
cookies[_session_id_key] = options
|
12
|
+
end
|
13
|
+
|
14
|
+
@_finalize_session_exception_callbacks = []
|
15
|
+
@_persist_exception_callbacks = []
|
16
|
+
|
17
|
+
# ==== Returns
|
18
|
+
# String:: A random 32 character string for use as a unique session ID.
|
19
|
+
def rand_uuid
|
20
|
+
values = [
|
21
|
+
rand(0x0010000),
|
22
|
+
rand(0x0010000),
|
23
|
+
rand(0x0010000),
|
24
|
+
rand(0x0010000),
|
25
|
+
rand(0x0010000),
|
26
|
+
rand(0x1000000),
|
27
|
+
rand(0x1000000),
|
28
|
+
]
|
29
|
+
"%04x%04x%04x%04x%04x%06x%06x" % values
|
30
|
+
end
|
31
|
+
|
32
|
+
# Marks this session as needing a new cookie.
|
33
|
+
def needs_new_cookie!
|
34
|
+
@_new_cookie = true
|
35
|
+
end
|
36
|
+
|
37
|
+
# Adds a callback to the list of callbacks run when
|
38
|
+
# exception is raised on session finalization, so
|
39
|
+
# you can recover.
|
40
|
+
#
|
41
|
+
# See session mixins documentation for details on
|
42
|
+
# session finalization.
|
43
|
+
#
|
44
|
+
# ==== Params
|
45
|
+
# &block::
|
46
|
+
# A block to be added to the callbacks that will be executed
|
47
|
+
# if there's exception on session finalization.
|
48
|
+
def finalize_session_exception_callbacks(&block)
|
49
|
+
if block_given?
|
50
|
+
@_finalize_session_exception_callbacks << block
|
51
|
+
else
|
52
|
+
@_finalize_session_exception_callbacks
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Adds a callback to the list of callbacks run when
|
57
|
+
# exception is raised on session persisting, so
|
58
|
+
# you can recover.
|
59
|
+
#
|
60
|
+
# See session mixins documentation for details on
|
61
|
+
# session persisting.
|
62
|
+
#
|
63
|
+
# ==== Params
|
64
|
+
# &block::
|
65
|
+
# A block to be added to the callbacks that will be executed
|
66
|
+
# if there's exception on session persisting.
|
67
|
+
def persist_exception_callbacks(&block)
|
68
|
+
if block_given?
|
69
|
+
@_persist_exception_callbacks << block
|
70
|
+
else
|
71
|
+
@_persist_exception_callbacks
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module_function :rand_uuid, :needs_new_cookie!, :finalize_session_exception_callbacks, :persist_exception_callbacks
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|