merb 0.5.3 → 0.9.2
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 +0 -20
- data/README +0 -277
- data/Rakefile +80 -199
- data/TODO +0 -3
- metadata +19 -438
- data/SVN_REVISION +0 -1
- data/app_generators/merb/USAGE +0 -5
- data/app_generators/merb/merb_generator.rb +0 -108
- data/app_generators/merb/templates/Rakefile +0 -124
- data/app_generators/merb/templates/app/controllers/application.rb +0 -3
- data/app_generators/merb/templates/app/controllers/exceptions.rb +0 -13
- data/app_generators/merb/templates/app/helpers/global_helper.rb +0 -5
- data/app_generators/merb/templates/app/mailers/views/layout/application.html.erb +0 -1
- data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +0 -1
- data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +0 -1
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +0 -216
- data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +0 -38
- data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +0 -40
- data/app_generators/merb/templates/app/views/layout/application.html.erb +0 -11
- data/app_generators/merb/templates/config/boot.rb +0 -11
- data/app_generators/merb/templates/config/dependencies.rb +0 -41
- data/app_generators/merb/templates/config/environments/development.rb +0 -1
- data/app_generators/merb/templates/config/environments/production.rb +0 -1
- data/app_generators/merb/templates/config/environments/test.rb +0 -1
- data/app_generators/merb/templates/config/merb.yml +0 -82
- data/app_generators/merb/templates/config/merb_init.rb +0 -17
- data/app_generators/merb/templates/config/plugins.yml +0 -1
- data/app_generators/merb/templates/config/router.rb +0 -35
- data/app_generators/merb/templates/config/upload.conf +0 -0
- data/app_generators/merb/templates/public/images/merb.jpg +0 -0
- data/app_generators/merb/templates/public/merb.fcgi +0 -6
- data/app_generators/merb/templates/public/stylesheets/master.css +0 -119
- data/app_generators/merb/templates/script/destroy +0 -32
- data/app_generators/merb/templates/script/generate +0 -32
- data/app_generators/merb/templates/script/stop_merb +0 -13
- data/app_generators/merb/templates/script/win_script.cmd +0 -1
- data/app_generators/merb/templates/spec/spec.opts +0 -6
- data/app_generators/merb/templates/spec/spec_helper.rb +0 -15
- data/app_generators/merb/templates/test/test_helper.rb +0 -14
- data/app_generators/merb_plugin/USAGE +0 -5
- data/app_generators/merb_plugin/merb_plugin_generator.rb +0 -68
- data/app_generators/merb_plugin/templates/LICENSE +0 -20
- data/app_generators/merb_plugin/templates/README +0 -4
- data/app_generators/merb_plugin/templates/Rakefile +0 -35
- data/app_generators/merb_plugin/templates/TODO +0 -5
- data/app_generators/merb_plugin/templates/merbtasks.rb +0 -6
- data/app_generators/merb_plugin/templates/sampleplugin.rb +0 -10
- data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +0 -7
- data/app_generators/merb_plugin/templates/spec_helper.rb +0 -2
- data/bin/merb +0 -4
- data/lib/autotest/discover.rb +0 -3
- data/lib/autotest/merb_rspec.rb +0 -80
- data/lib/merb.rb +0 -188
- data/lib/merb/abstract_controller.rb +0 -399
- data/lib/merb/assets.rb +0 -160
- data/lib/merb/assets.rb.orig +0 -119
- data/lib/merb/boot_loader.rb +0 -286
- data/lib/merb/boot_loader.rb.orig +0 -235
- data/lib/merb/caching.rb +0 -5
- data/lib/merb/caching/action_cache.rb +0 -92
- data/lib/merb/caching/fragment_cache.rb +0 -39
- data/lib/merb/caching/store/file_cache.rb +0 -90
- data/lib/merb/caching/store/memory_cache.rb +0 -85
- data/lib/merb/config.rb +0 -290
- data/lib/merb/constants.rb +0 -50
- data/lib/merb/controller.rb +0 -220
- data/lib/merb/cookies.rb +0 -95
- data/lib/merb/core_ext.rb +0 -15
- data/lib/merb/core_ext/array.rb +0 -0
- data/lib/merb/core_ext/class.rb +0 -180
- data/lib/merb/core_ext/enumerable.rb +0 -49
- data/lib/merb/core_ext/get_args.rb +0 -76
- data/lib/merb/core_ext/hash.rb +0 -306
- data/lib/merb/core_ext/inflections.rb +0 -112
- data/lib/merb/core_ext/inflector.rb +0 -275
- data/lib/merb/core_ext/kernel.rb +0 -242
- data/lib/merb/core_ext/mash.rb +0 -88
- data/lib/merb/core_ext/module.rb +0 -67
- data/lib/merb/core_ext/numeric.rb +0 -72
- data/lib/merb/core_ext/object.rb +0 -183
- data/lib/merb/core_ext/string.rb +0 -53
- data/lib/merb/core_ext/symbol.rb +0 -6
- data/lib/merb/dispatcher.rb +0 -109
- data/lib/merb/drb_server.rb +0 -19
- data/lib/merb/erubis_ext.rb +0 -10
- data/lib/merb/exceptions.rb +0 -192
- data/lib/merb/generators/merb_app/merb_app.rb +0 -22
- data/lib/merb/generators/merb_generator_helpers.rb +0 -318
- data/lib/merb/generators/merb_plugin.rb +0 -22
- data/lib/merb/logger.rb +0 -78
- data/lib/merb/mail_controller.rb +0 -268
- data/lib/merb/mailer.rb +0 -87
- data/lib/merb/mixins/basic_authentication.rb +0 -35
- data/lib/merb/mixins/controller.rb +0 -160
- data/lib/merb/mixins/erubis_capture.rb +0 -68
- data/lib/merb/mixins/general_controller.rb +0 -253
- data/lib/merb/mixins/inline_partial.rb +0 -32
- data/lib/merb/mixins/render.rb +0 -465
- data/lib/merb/mixins/responder.rb +0 -449
- data/lib/merb/mixins/view_context.rb +0 -558
- data/lib/merb/mixins/web_controller.rb +0 -36
- data/lib/merb/mongrel_handler.rb +0 -168
- data/lib/merb/part_controller.rb +0 -29
- data/lib/merb/plugins.rb +0 -16
- data/lib/merb/rack_adapter.rb +0 -37
- data/lib/merb/request.rb +0 -465
- data/lib/merb/router.rb +0 -646
- data/lib/merb/server.rb +0 -169
- data/lib/merb/session.rb +0 -23
- data/lib/merb/session/cookie_store.rb +0 -118
- data/lib/merb/session/mem_cache_session.rb +0 -131
- data/lib/merb/session/memory_session.rb +0 -176
- data/lib/merb/template.rb +0 -37
- data/lib/merb/template/erubis.rb +0 -68
- data/lib/merb/template/haml.rb +0 -87
- data/lib/merb/template/markaby.rb +0 -59
- data/lib/merb/template/xml_builder.rb +0 -50
- data/lib/merb/test/fake_request.rb +0 -74
- data/lib/merb/test/helper.rb +0 -260
- data/lib/merb/test/hpricot.rb +0 -136
- data/lib/merb/test/multipart.rb +0 -66
- data/lib/merb/test/rspec.rb +0 -18
- data/lib/merb/test/rspec_matchers/controller_matchers.rb +0 -117
- data/lib/merb/test/rspec_matchers/markup_matchers.rb +0 -98
- data/lib/merb/upload_handler.rb +0 -80
- data/lib/merb/upload_progress.rb +0 -48
- data/lib/merb/version.rb +0 -49
- data/lib/merb/view_context.rb +0 -79
- data/lib/tasks.rb +0 -7
- data/lib/tasks/merb.rake +0 -54
- data/merb_default_generators/model/USAGE +0 -0
- data/merb_default_generators/model/model_generator.rb +0 -16
- data/merb_default_generators/model/templates/new_model_template.erb +0 -5
- data/merb_default_generators/resource_controller/USAGE +0 -0
- data/merb_default_generators/resource_controller/resource_controller_generator.rb +0 -26
- data/merb_default_generators/resource_controller/templates/controller.rb +0 -30
- data/merb_default_generators/resource_controller/templates/edit.html.erb +0 -1
- data/merb_default_generators/resource_controller/templates/helper.rb +0 -5
- data/merb_default_generators/resource_controller/templates/index.html.erb +0 -1
- data/merb_default_generators/resource_controller/templates/new.html.erb +0 -1
- data/merb_default_generators/resource_controller/templates/show.html.erb +0 -1
- data/merb_generators/controller/USAGE +0 -5
- data/merb_generators/controller/controller_generator.rb +0 -16
- data/merb_generators/controller/templates/controller.rb +0 -8
- data/merb_generators/controller/templates/helper.rb +0 -5
- data/merb_generators/controller/templates/index.html.erb +0 -3
- data/merb_generators/part_controller/USAGE +0 -5
- data/merb_generators/part_controller/part_controller_generator.rb +0 -27
- data/merb_generators/part_controller/templates/controller.rb +0 -8
- data/merb_generators/part_controller/templates/helper.rb +0 -5
- data/merb_generators/part_controller/templates/index.html.erb +0 -3
- data/merb_generators/resource/USAGE +0 -0
- data/merb_generators/resource/resource_generator.rb +0 -67
- data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +0 -67
- data/rspec_generators/merb_controller_test/templates/controller_spec.rb +0 -8
- data/rspec_generators/merb_controller_test/templates/edit_spec.rb +0 -12
- data/rspec_generators/merb_controller_test/templates/helper_spec.rb +0 -5
- data/rspec_generators/merb_controller_test/templates/index_spec.rb +0 -12
- data/rspec_generators/merb_controller_test/templates/new_spec.rb +0 -12
- data/rspec_generators/merb_controller_test/templates/show_spec.rb +0 -5
- data/rspec_generators/merb_model_test/merb_model_test_generator.rb +0 -26
- data/rspec_generators/merb_model_test/templates/model_spec_template.erb +0 -7
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/spec/fixtures/config/environments/environment_config_test.yml +0 -1
- data/spec/fixtures/config/merb.yml +0 -18
- data/spec/fixtures/controllers/dispatch_spec_controllers.rb +0 -235
- data/spec/fixtures/controllers/render_spec_controllers.rb +0 -184
- data/spec/fixtures/foo.rb +0 -3
- data/spec/fixtures/mailers/views/layout/application.html.erb +0 -3
- data/spec/fixtures/mailers/views/layout/application.text.erb +0 -3
- data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +0 -1
- data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +0 -1
- data/spec/fixtures/models/router_spec_models.rb +0 -30
- data/spec/fixtures/parts/views/layout/todo_part.html.erb +0 -3
- data/spec/fixtures/parts/views/layout/todo_part.xml.erb +0 -3
- data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +0 -1
- data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +0 -1
- data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +0 -1
- data/spec/fixtures/parts/views/todo_part/list.html.erb +0 -3
- data/spec/fixtures/sample.txt +0 -1
- data/spec/fixtures/views/erubis.html.erb +0 -1
- data/spec/fixtures/views/examples/_erubis.html.erb +0 -1
- data/spec/fixtures/views/examples/_haml.html.haml +0 -1
- data/spec/fixtures/views/examples/_markaby.html.mab +0 -1
- data/spec/fixtures/views/examples/_throw_content.html.erb +0 -6
- data/spec/fixtures/views/examples/hello.xml.builder +0 -1
- data/spec/fixtures/views/examples/js.js.erb +0 -1
- data/spec/fixtures/views/examples/template_catch_content.html.erb +0 -15
- data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +0 -6
- data/spec/fixtures/views/examples/template_throw_content.html.erb +0 -10
- data/spec/fixtures/views/examples/template_throw_content_without_block.html.erb +0 -3
- data/spec/fixtures/views/exceptions/admin_access_required.html.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +0 -1
- data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
- data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +0 -1
- data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +0 -1
- data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +0 -1
- data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
- data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
- data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +0 -1
- data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +0 -1
- data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +0 -1
- data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +0 -4
- data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +0 -1
- data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +0 -1
- data/spec/fixtures/views/haml.html.haml +0 -1
- data/spec/fixtures/views/haml.xml.haml +0 -2
- data/spec/fixtures/views/layout/application.html.erb +0 -1
- data/spec/fixtures/views/layout/application.xml.erb +0 -1
- data/spec/fixtures/views/layout/nested/example.html.erb +0 -1
- data/spec/fixtures/views/markaby.html.mab +0 -1
- data/spec/fixtures/views/nested/example/test.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis_collection.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +0 -1
- data/spec/fixtures/views/partials/_erubis_new.html.erb +0 -1
- data/spec/fixtures/views/partials/_haml.html.haml +0 -1
- data/spec/fixtures/views/partials/_haml_collection.html.haml +0 -1
- data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +0 -1
- data/spec/fixtures/views/partials/_haml_new.html.haml +0 -1
- data/spec/fixtures/views/partials/_markaby.html.mab +0 -1
- data/spec/fixtures/views/partials/_markaby_collection.html.mab +0 -1
- data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +0 -1
- data/spec/fixtures/views/partials/_markaby_new.html.mab +0 -1
- data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +0 -1
- data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +0 -1
- data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +0 -1
- data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +0 -4
- data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +0 -7
- data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +0 -7
- data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +0 -15
- data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +0 -15
- data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +0 -4
- data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +0 -12
- data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +0 -11
- data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +0 -14
- data/spec/fixtures/views/test.dir/the_template.html.erb +0 -1
- data/spec/merb/abstract_controller_spec.rb +0 -38
- data/spec/merb/assets_spec.rb +0 -207
- data/spec/merb/caching_spec.rb +0 -102
- data/spec/merb/config_spec.rb +0 -29
- data/spec/merb/controller_filters_spec.rb +0 -253
- data/spec/merb/controller_spec.rb +0 -126
- data/spec/merb/cookie_store_spec.rb +0 -72
- data/spec/merb/cookies_spec.rb +0 -96
- data/spec/merb/core_ext/class_spec.rb +0 -97
- data/spec/merb/core_ext/enumerable_spec.rb +0 -27
- data/spec/merb/core_ext/hash_spec.rb +0 -251
- data/spec/merb/core_ext/inflector_spec.rb +0 -34
- data/spec/merb/core_ext/kernel_spec.rb +0 -25
- data/spec/merb/core_ext/numeric_spec.rb +0 -26
- data/spec/merb/core_ext/object_spec.rb +0 -47
- data/spec/merb/core_ext/string_spec.rb +0 -22
- data/spec/merb/core_ext/symbol_spec.rb +0 -7
- data/spec/merb/dependency_spec.rb +0 -22
- data/spec/merb/dispatch_spec.rb +0 -528
- data/spec/merb/fake_request_spec.rb +0 -80
- data/spec/merb/generator_spec.rb +0 -248
- data/spec/merb/handler_spec.rb +0 -169
- data/spec/merb/mail_controller_spec.rb +0 -177
- data/spec/merb/mailer_spec.rb +0 -87
- data/spec/merb/multipart_spec.rb +0 -50
- data/spec/merb/part_controller_spec.rb +0 -124
- data/spec/merb/plugins_spec.rb +0 -80
- data/spec/merb/render_spec.rb +0 -469
- data/spec/merb/request_spec.rb +0 -287
- data/spec/merb/responder_spec.rb +0 -562
- data/spec/merb/router_spec.rb +0 -900
- data/spec/merb/server_spec.rb +0 -19
- data/spec/merb/template_spec.rb +0 -41
- data/spec/merb/upload_handler_spec.rb +0 -108
- data/spec/merb/version_spec.rb +0 -33
- data/spec/merb/view_context_spec.rb +0 -366
- data/spec/spec_generator_helper.rb +0 -34
- data/spec/spec_helper.rb +0 -101
- data/spec/spec_helpers/url_shared_behaviour.rb +0 -112
- data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +0 -53
- data/test_unit_generators/merb_controller_test/templates/functional_test.rb +0 -17
- data/test_unit_generators/merb_controller_test/templates/helper_test.rb +0 -9
- data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +0 -29
- data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +0 -9
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Used by secondary actions (a PartsController or the view)
|
|
2
|
-
# to provide the standard objects associated with each request.
|
|
3
|
-
|
|
4
|
-
module Merb
|
|
5
|
-
module WebControllerMixin #:nodoc:
|
|
6
|
-
|
|
7
|
-
def request
|
|
8
|
-
@web_controller.request
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def params
|
|
12
|
-
@web_controller.params
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def cookies
|
|
16
|
-
@web_controller.cookies
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def headers
|
|
20
|
-
@web_controller.headers
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def session
|
|
24
|
-
@web_controller.session
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def response
|
|
28
|
-
@web_controller.response
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def route
|
|
32
|
-
request.route
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end
|
|
36
|
-
end
|
data/lib/merb/mongrel_handler.rb
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
class Mongrel::HttpResponse
|
|
2
|
-
NO_CLOSE_STATUS_FORMAT = "HTTP/1.1 %d %s\r\n".freeze
|
|
3
|
-
def send_status_no_connection_close(content_length=@body.length)
|
|
4
|
-
unless @status_sent
|
|
5
|
-
@header['Content-Length'] = content_length unless @status == 304
|
|
6
|
-
write(NO_CLOSE_STATUS_FORMAT % [@status, Mongrel::HTTP_STATUS_CODES[@status]])
|
|
7
|
-
@status_sent = true
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
class MerbHandler < Mongrel::HttpHandler
|
|
13
|
-
@@file_only_methods = ["GET","HEAD"]
|
|
14
|
-
@@path_prefix = nil
|
|
15
|
-
@@path_prefix_original = nil
|
|
16
|
-
|
|
17
|
-
class << self
|
|
18
|
-
# Use :path_prefix in merb.yml to set this
|
|
19
|
-
def path_prefix() @@path_prefix_original end
|
|
20
|
-
def path_prefix=(prefix)
|
|
21
|
-
@@path_prefix_original = prefix
|
|
22
|
-
@@path_prefix = (prefix.is_a?(String) ? /^#{prefix.escape_regexp}/ : prefix)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Take the name of a directory and use that as the doc root or public
|
|
27
|
-
# directory of your site. This is set to the root of your merb app + '/public'
|
|
28
|
-
# by default.
|
|
29
|
-
def initialize(dir, mongrel_x_sendfile=true, opts = {})
|
|
30
|
-
@files = Mongrel::DirHandler.new(dir,false)
|
|
31
|
-
@mongrel_x_sendfile = mongrel_x_sendfile
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# process incoming http requests and do a number of things
|
|
35
|
-
# 1. Check for rails style cached pages. add .html to the url and see if
|
|
36
|
-
# there is a static file in public that matches. serve that file directly
|
|
37
|
-
# without invoking Merb and be done with it.
|
|
38
|
-
# 2. Serve static asset and html files directly from public/ if they exist.
|
|
39
|
-
# 3. If none of the above apply, we take apart the request url and feed it
|
|
40
|
-
# into Merb::RouteMatcher to let it decide which controller and method will
|
|
41
|
-
# serve the request.
|
|
42
|
-
# 4. After the controller has done its thing, we check for the X-SENDFILE
|
|
43
|
-
# header. if you set this header to the path of a file in your controller
|
|
44
|
-
# then mongrel will serve the file directly and your controller can go on
|
|
45
|
-
# processing other requests.
|
|
46
|
-
def process(request, response)
|
|
47
|
-
return if response.socket.closed?
|
|
48
|
-
|
|
49
|
-
start = Time.now
|
|
50
|
-
benchmarks = {}
|
|
51
|
-
|
|
52
|
-
Merb.logger.info("\nRequest: REQUEST_URI: #{
|
|
53
|
-
request.params[Mongrel::Const::REQUEST_URI]} (#{Time.now.strftime("%Y-%m-%d %H:%M:%S")})")
|
|
54
|
-
|
|
55
|
-
# Truncate the request URI if there's a path prefix so that an app can be
|
|
56
|
-
# hosted inside a subdirectory, for example.
|
|
57
|
-
if @@path_prefix
|
|
58
|
-
if request.params[Mongrel::Const::PATH_INFO] =~ @@path_prefix
|
|
59
|
-
Merb.logger.info("Path prefix #{@@path_prefix.inspect} removed from PATH_INFO and REQUEST_URI.")
|
|
60
|
-
request.params[Mongrel::Const::PATH_INFO].sub!(@@path_prefix, '')
|
|
61
|
-
request.params[Mongrel::Const::REQUEST_URI].sub!(@@path_prefix, '')
|
|
62
|
-
path_info = request.params[Mongrel::Const::PATH_INFO]
|
|
63
|
-
else
|
|
64
|
-
raise "Path prefix is set to '#{@@path_prefix.inspect}', but is not in the REQUEST_URI. "
|
|
65
|
-
end
|
|
66
|
-
else
|
|
67
|
-
path_info = request.params[Mongrel::Const::PATH_INFO]
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Rails style page caching. Check the public dir first for .html pages and
|
|
71
|
-
# serve directly. Otherwise fall back to Merb routing and request
|
|
72
|
-
# dispatching.
|
|
73
|
-
page_cached = path_info + ".html"
|
|
74
|
-
get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD]
|
|
75
|
-
|
|
76
|
-
if get_or_head && @files.can_serve(path_info)
|
|
77
|
-
# File exists as-is so serve it up
|
|
78
|
-
Merb.logger.info("Serving static file: #{path_info}")
|
|
79
|
-
@files.process(request,response)
|
|
80
|
-
elsif get_or_head && @files.can_serve(page_cached)
|
|
81
|
-
# Possible cached page, serve it up
|
|
82
|
-
Merb.logger.info("Serving static file: #{page_cached}")
|
|
83
|
-
request.params[Mongrel::Const::PATH_INFO] = page_cached
|
|
84
|
-
@files.process(request,response)
|
|
85
|
-
else
|
|
86
|
-
# Let Merb:Dispatcher find the route and call the filter chain and action
|
|
87
|
-
controller, action = Merb::Dispatcher.handle(request, response)
|
|
88
|
-
benchmarks.merge!(controller._benchmarks)
|
|
89
|
-
benchmarks[:controller] = controller.class.to_s
|
|
90
|
-
benchmarks[:action] = action
|
|
91
|
-
|
|
92
|
-
Merb.logger.info("Routing to controller: #{controller.class} action: #{action}\nRoute Recognition & Parsing HTTP Input took: #{benchmarks[:setup_time]} seconds")
|
|
93
|
-
|
|
94
|
-
sendfile, clength = nil
|
|
95
|
-
response.status = controller.status
|
|
96
|
-
# Check for the X-SENDFILE header from your Merb::Controller and serve
|
|
97
|
-
# the file directly instead of buffering.
|
|
98
|
-
controller.headers.each do |k, v|
|
|
99
|
-
if k =~ /^X-SENDFILE$/i
|
|
100
|
-
sendfile = v
|
|
101
|
-
elsif k =~ /^CONTENT-LENGTH$/i
|
|
102
|
-
clength = v.to_i
|
|
103
|
-
else
|
|
104
|
-
[*v].each do |vi|
|
|
105
|
-
response.header[k] = vi
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
if sendfile
|
|
111
|
-
if @mongrel_x_sendfile
|
|
112
|
-
# we want to emulate X-Sendfile header internally in mongrel
|
|
113
|
-
benchmarks[:sendfile_time] = Time.now - start
|
|
114
|
-
Merb.logger.info("X-SENDFILE: #{sendfile}\nComplete Request took: #{
|
|
115
|
-
benchmarks[:sendfile_time]} seconds")
|
|
116
|
-
file_status = File.stat(sendfile)
|
|
117
|
-
response.status = 200
|
|
118
|
-
# Set the last modified times as well and etag for all files
|
|
119
|
-
response.header[Mongrel::Const::LAST_MODIFIED] = file_status.mtime.httpdate
|
|
120
|
-
# Calculated the same as apache, not sure how well the works on win32
|
|
121
|
-
response.header[Mongrel::Const::ETAG] = Mongrel::Const::ETAG_FORMAT % [file_status.mtime.to_i, file_status.size, file_status.ino]
|
|
122
|
-
# Send a status with out content length
|
|
123
|
-
response.send_status(file_status.size)
|
|
124
|
-
response.send_header
|
|
125
|
-
response.send_file(sendfile)
|
|
126
|
-
else
|
|
127
|
-
# we want to pass thru the X-Sendfile header so apache or whatever
|
|
128
|
-
# front server can handle it
|
|
129
|
-
response.header['X-Sendfile'] = sendfile
|
|
130
|
-
response.header['Content-length'] = clength || File.size(sendfile)
|
|
131
|
-
response.finished
|
|
132
|
-
end
|
|
133
|
-
elsif controller.body.respond_to? :read
|
|
134
|
-
response.send_status(clength)
|
|
135
|
-
response.send_header
|
|
136
|
-
while chunk = controller.body.read(16384)
|
|
137
|
-
response.write(chunk)
|
|
138
|
-
end
|
|
139
|
-
if controller.body.respond_to? :close
|
|
140
|
-
controller.body.close
|
|
141
|
-
end
|
|
142
|
-
elsif Proc === controller.body
|
|
143
|
-
controller.body.call
|
|
144
|
-
else
|
|
145
|
-
# Render response from successful controller
|
|
146
|
-
body = (controller.body.to_s rescue '')
|
|
147
|
-
response.send_status(body.length)
|
|
148
|
-
response.send_header
|
|
149
|
-
response.write(body)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
total_request_time = Time.now - start
|
|
153
|
-
benchmarks[:total_request_time] = total_request_time
|
|
154
|
-
|
|
155
|
-
Merb.logger.info("Request Times: #{benchmarks.inspect}\nResponse status: #{response.status}\nComplete Request took: #{total_request_time} seconds, #{1.0/total_request_time} Requests/Second\n\n")
|
|
156
|
-
end
|
|
157
|
-
rescue Object => e
|
|
158
|
-
# if an exception is raised here then something is
|
|
159
|
-
# wrong with the dispatcher code so we shouldn't pass the
|
|
160
|
-
# exception back in or we might end up in a loop
|
|
161
|
-
response.send_status(500)
|
|
162
|
-
response.send_header
|
|
163
|
-
response.write("500 Internal Server Error")
|
|
164
|
-
Merb.logger.error(Merb.exception(e))
|
|
165
|
-
ensure
|
|
166
|
-
Merb.logger.flush
|
|
167
|
-
end
|
|
168
|
-
end
|
data/lib/merb/part_controller.rb
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
module Merb
|
|
2
|
-
class PartController < AbstractController
|
|
3
|
-
self._template_root = File.expand_path(self._template_root / "../parts/views")
|
|
4
|
-
include Merb::WebControllerMixin
|
|
5
|
-
|
|
6
|
-
def initialize(web_controller)
|
|
7
|
-
@web_controller = web_controller
|
|
8
|
-
super
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def dispatch(action=:to_s)
|
|
12
|
-
old_action = params[:action]
|
|
13
|
-
params[:action] = action
|
|
14
|
-
super(action)
|
|
15
|
-
params[:action] = old_action
|
|
16
|
-
@_body
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
# This method is here to overwrite the one in the general_controller mixin
|
|
22
|
-
# The method ensures that when a url is generated with a hash, it contains a controller
|
|
23
|
-
def get_controller_for_url_generation(opts)
|
|
24
|
-
controller = opts[:controller] || @web_controller.params[:controller]
|
|
25
|
-
raise "No Controller Specified for url()" unless controller
|
|
26
|
-
controller
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
data/lib/merb/plugins.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module Merb
|
|
2
|
-
module Plugins
|
|
3
|
-
def self.config
|
|
4
|
-
@config ||= File.exists?(Merb.root / "config" / "plugins.yml") ? YAML.load(File.read(Merb.root / "config" / "plugins.yml")) || {} : {}
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
@rakefiles = []
|
|
8
|
-
def self.rakefiles
|
|
9
|
-
@rakefiles
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def self.add_rakefiles(*rakefiles)
|
|
13
|
-
@rakefiles += rakefiles
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
data/lib/merb/rack_adapter.rb
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
module Merb
|
|
2
|
-
module Rack
|
|
3
|
-
|
|
4
|
-
class RequestWrapper
|
|
5
|
-
def initialize(env)
|
|
6
|
-
@env = env
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def params
|
|
10
|
-
@env
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def body
|
|
14
|
-
@env['rack.input']
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
class Adapter
|
|
19
|
-
def call(env)
|
|
20
|
-
env["PATH_INFO"] ||= ""
|
|
21
|
-
env["SCRIPT_NAME"] ||= ""
|
|
22
|
-
if env["REQUEST_URI"] =~ %r{(https?://)[^/](.*)}
|
|
23
|
-
env["REQUEST_URI"] = $2
|
|
24
|
-
end
|
|
25
|
-
request = RequestWrapper.new(env)
|
|
26
|
-
response = StringIO.new
|
|
27
|
-
begin
|
|
28
|
-
controller, action = ::Merb::Dispatcher.handle(request, response)
|
|
29
|
-
rescue Object => e
|
|
30
|
-
return [500, {"Content-Type"=>"text/html"}, "Internal Server Error"]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
[controller.status, controller.headers, controller.body]
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
data/lib/merb/request.rb
DELETED
|
@@ -1,465 +0,0 @@
|
|
|
1
|
-
module Merb
|
|
2
|
-
class Request
|
|
3
|
-
attr_accessor :env, :session
|
|
4
|
-
|
|
5
|
-
# by setting these to false, auto-parsing is disabled; this way you can do your own parsing instead
|
|
6
|
-
cattr_accessor :parse_multipart_params, :parse_json_params, :parse_xml_params
|
|
7
|
-
self.parse_multipart_params = true
|
|
8
|
-
self.parse_json_params = true
|
|
9
|
-
self.parse_xml_params = true
|
|
10
|
-
|
|
11
|
-
def initialize(http_request)
|
|
12
|
-
@env = http_request.params
|
|
13
|
-
@body = http_request.body
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
METHODS = %w{get post put delete head}
|
|
17
|
-
|
|
18
|
-
def method
|
|
19
|
-
@method ||= begin
|
|
20
|
-
request_method = @env['REQUEST_METHOD'].downcase.to_sym
|
|
21
|
-
case request_method
|
|
22
|
-
when :get, :head, :put, :delete
|
|
23
|
-
request_method
|
|
24
|
-
when :post
|
|
25
|
-
if self.class.parse_multipart_params
|
|
26
|
-
m = body_and_query_params.merge(multipart_params)['_method']
|
|
27
|
-
else
|
|
28
|
-
m = body_and_query_params['_method']
|
|
29
|
-
end
|
|
30
|
-
m.downcase! if m
|
|
31
|
-
METHODS.include?(m) ? m.to_sym : :post
|
|
32
|
-
else
|
|
33
|
-
raise "Unknown REQUEST_METHOD: #{@env['REQUEST_METHOD']}"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# create predicate methods for querying the REQUEST_METHOD
|
|
39
|
-
# get? post? head? put? etc
|
|
40
|
-
METHODS.each do |m|
|
|
41
|
-
define_method("#{m}?") { method == m.to_sym }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
# FIXME: symbolize_keys on params is a potential problem. symbols are
|
|
47
|
-
# not garbage collected so a malicious user could send many large query
|
|
48
|
-
# keys to Merb forcing it to eat up memeory.
|
|
49
|
-
|
|
50
|
-
# A hash of parameters passed from the URL like ?blah=hello
|
|
51
|
-
def query_params
|
|
52
|
-
@query_params ||= self.class.query_parse(query_string || '')
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# A hash of parameters passed in the body of the request.
|
|
56
|
-
#
|
|
57
|
-
# Ajax calls from prototype.js and other libraries
|
|
58
|
-
# pass content this way.
|
|
59
|
-
def body_params
|
|
60
|
-
@body_params ||= begin
|
|
61
|
-
if content_type && content_type.match(Merb::Const::FORM_URL_ENCODED_REGEXP) # or content_type.nil?
|
|
62
|
-
self.class.query_parse(raw_post)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def body_and_query_params
|
|
68
|
-
# ^-- FIXME a better name for this method
|
|
69
|
-
@body_and_query_params ||= begin
|
|
70
|
-
h = query_params
|
|
71
|
-
h.merge!(body_params) if body_params
|
|
72
|
-
h.to_mash
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def multipart_params
|
|
77
|
-
@multipart_params ||=
|
|
78
|
-
begin
|
|
79
|
-
if Merb::Const::MULTIPART_REGEXP =~ content_type
|
|
80
|
-
if @body.size <= 0
|
|
81
|
-
{}
|
|
82
|
-
else
|
|
83
|
-
self.class.parse_multipart(@body, $1, content_length)
|
|
84
|
-
end
|
|
85
|
-
else
|
|
86
|
-
{}
|
|
87
|
-
end
|
|
88
|
-
rescue ControllerExceptions::MultiPartParseError => e
|
|
89
|
-
@multipart_params = {}
|
|
90
|
-
raise e
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def json_params
|
|
95
|
-
@json_params ||= begin
|
|
96
|
-
if Merb::Const::JSON_MIME_TYPE_REGEXP.match(content_type)
|
|
97
|
-
JSON.parse(raw_post)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def xml_params
|
|
103
|
-
@xml_params ||= begin
|
|
104
|
-
if Merb::Const::XML_MIME_TYPE_REGEXP.match(content_type)
|
|
105
|
-
Hash.from_xml(raw_post) rescue Mash.new
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
public
|
|
111
|
-
|
|
112
|
-
def params
|
|
113
|
-
@params ||= begin
|
|
114
|
-
h = body_and_query_params.merge(route_params)
|
|
115
|
-
h.merge!(multipart_params) if self.class.parse_multipart_params && multipart_params
|
|
116
|
-
h.merge!(json_params) if self.class.parse_json_params && json_params
|
|
117
|
-
h.merge!(xml_params) if self.class.parse_xml_params && xml_params
|
|
118
|
-
h
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def cookies
|
|
123
|
-
@cookies ||= self.class.query_parse(@env[Merb::Const::HTTP_COOKIE], ';,')
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def route
|
|
127
|
-
@route ||= Merb::Router.routes[route_index]
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# returns two objects, route_index and route_params
|
|
131
|
-
def route_match
|
|
132
|
-
@route_match ||= Merb::Router.match(self, body_and_query_params)
|
|
133
|
-
end
|
|
134
|
-
private :route_match
|
|
135
|
-
|
|
136
|
-
def route_index
|
|
137
|
-
route_match.first
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def route_params
|
|
141
|
-
route_match.last
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def controller_name
|
|
145
|
-
if route_params[:namespace]
|
|
146
|
-
route_params[:namespace] + '/' + route_params[:controller]
|
|
147
|
-
else
|
|
148
|
-
route_params[:controller]
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def controller_class
|
|
153
|
-
begin
|
|
154
|
-
cnt = controller_name.to_const_string
|
|
155
|
-
rescue ::String::InvalidPathConversion
|
|
156
|
-
raise ControllerExceptions::NotFound
|
|
157
|
-
end
|
|
158
|
-
if !Controller._subclasses.include?(cnt)
|
|
159
|
-
raise ControllerExceptions::NotFound, "Controller '#{cnt}' not found"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
begin
|
|
163
|
-
if cnt == "Application"
|
|
164
|
-
raise ControllerExceptions::NotFound, "The 'Application' controller has no public actions"
|
|
165
|
-
end
|
|
166
|
-
return Object.full_const_get(cnt)
|
|
167
|
-
rescue NameError
|
|
168
|
-
raise ControllerExceptions::NotFound
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def action
|
|
173
|
-
route_params[:action]
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def raw_post
|
|
177
|
-
@body.rewind
|
|
178
|
-
res = @body.read
|
|
179
|
-
@body.rewind
|
|
180
|
-
res
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
# Returns true if the request is an Ajax request.
|
|
184
|
-
#
|
|
185
|
-
# Also aliased as the more memorable ajax? and xhr?.
|
|
186
|
-
def xml_http_request?
|
|
187
|
-
not /XMLHttpRequest/i.match(@env['HTTP_X_REQUESTED_WITH']).nil?
|
|
188
|
-
end
|
|
189
|
-
alias xhr? :xml_http_request?
|
|
190
|
-
alias ajax? :xml_http_request?
|
|
191
|
-
|
|
192
|
-
# returns the remote IP address if it can find it.
|
|
193
|
-
def remote_ip
|
|
194
|
-
return @env['HTTP_CLIENT_IP'] if @env.include?('HTTP_CLIENT_IP')
|
|
195
|
-
|
|
196
|
-
if @env.include?(Merb::Const::HTTP_X_FORWARDED_FOR) then
|
|
197
|
-
remote_ips = @env[Merb::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip|
|
|
198
|
-
ip =~ /^unknown$|^(127|10|172\.16|192\.168)\./i
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
return remote_ips.first.strip unless remote_ips.empty?
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
return @env[Merb::Const::REMOTE_ADDR]
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
# returns either 'https://' or 'http://' depending on
|
|
208
|
-
# the HTTPS header
|
|
209
|
-
def protocol
|
|
210
|
-
ssl? ? 'https://' : 'http://'
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# returns true if the request is an SSL request
|
|
214
|
-
def ssl?
|
|
215
|
-
@env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# returns the request HTTP_REFERER.
|
|
219
|
-
def referer
|
|
220
|
-
@env['HTTP_REFERER']
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
# returns he request uri.
|
|
224
|
-
def uri
|
|
225
|
-
@env['REQUEST_URI']
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def user_agent
|
|
229
|
-
@env['HTTP_USER_AGENT']
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
def server_name
|
|
233
|
-
@env['SERVER_NAME']
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
def accept_encoding
|
|
237
|
-
@env['HTTP_ACCEPT_ENCODING']
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def script_name
|
|
241
|
-
@env['SCRIPT_NAME']
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def cache_control
|
|
245
|
-
@env['HTTP_CACHE_CONTROL']
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
def accept_language
|
|
249
|
-
@env['HTTP_ACCEPT_LANGUAGE']
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
def host
|
|
253
|
-
@env['HTTP_HOST']
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
def server_software
|
|
257
|
-
@env['SERVER_SOFTWARE']
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
def keep_alive
|
|
261
|
-
@env['HTTP_KEEP_ALIVE']
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
def accept_charset
|
|
265
|
-
@env['HTTP_ACCEPT_CHARSET']
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
def version
|
|
269
|
-
@env['HTTP_VERSION']
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
def gateway
|
|
273
|
-
@env['GATEWAY_INTERFACE']
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
def accept
|
|
277
|
-
@env['HTTP_ACCEPT'].blank? ? "*/*" : @env['HTTP_ACCEPT']
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
def connection
|
|
281
|
-
@env['HTTP_CONNECTION']
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
def query_string
|
|
285
|
-
@env['QUERY_STRING']
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def content_type
|
|
289
|
-
@env['CONTENT_TYPE']
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
def content_length
|
|
293
|
-
@content_length ||= @env[Merb::Const::CONTENT_LENGTH].to_i
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
# Returns the uri without the query string. Strips trailing '/' and reduces
|
|
297
|
-
# duplicate '/' to a single '/'
|
|
298
|
-
def path
|
|
299
|
-
path = (uri ? uri.split('?').first : '').sub(/\/+/, '/')
|
|
300
|
-
path = path[0..-2] if (path[-1] == ?/) && path.size > 1
|
|
301
|
-
path
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
# returns the PATH_INFO
|
|
305
|
-
def path_info
|
|
306
|
-
@path_info ||= Mongrel::HttpRequest.unescape(@env['PATH_INFO'])
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
# returns the port the server is running on
|
|
310
|
-
def port
|
|
311
|
-
@env['SERVER_PORT'].to_i
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
# returns the full hostname including port
|
|
315
|
-
def host
|
|
316
|
-
@env['HTTP_X_FORWARDED_HOST'] || @env['HTTP_HOST']
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
# returns an array of all the subdomain parts of the host.
|
|
320
|
-
def subdomains(tld_length = 1)
|
|
321
|
-
parts = host.split('.')
|
|
322
|
-
parts[0..-(tld_length+2)]
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
# returns the full domain name without the port number.
|
|
326
|
-
def domain(tld_length = 1)
|
|
327
|
-
host.split('.').last(1 + tld_length).join('.').sub(/:\d+$/,'')
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
class << self
|
|
331
|
-
# Escapes +s+ for use in a URL.
|
|
332
|
-
#
|
|
333
|
-
# ==== Parameter
|
|
334
|
-
#
|
|
335
|
-
# +s+ - String to URL escape.
|
|
336
|
-
#
|
|
337
|
-
def escape(s)
|
|
338
|
-
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
|
|
339
|
-
'%'+$1.unpack('H2'*$1.size).join('%').upcase
|
|
340
|
-
}.tr(' ', '+')
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
# Unescapes a string (i.e., reverse URL escaping).
|
|
344
|
-
#
|
|
345
|
-
# ==== Parameter
|
|
346
|
-
#
|
|
347
|
-
# +s+ - String to unescape.
|
|
348
|
-
#
|
|
349
|
-
def unescape(s)
|
|
350
|
-
s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
|
|
351
|
-
[$1.delete('%')].pack('H*')
|
|
352
|
-
}
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
# parses a query string or the payload of a POST
|
|
356
|
-
# request into the params hash. So for example:
|
|
357
|
-
# /foo?bar=nik&post[title]=heya&post[body]=whatever
|
|
358
|
-
# parses into:
|
|
359
|
-
# {:bar => 'nik', :post => {:title => 'heya', :body => 'whatever'}}
|
|
360
|
-
def query_parse(qs, d = '&;')
|
|
361
|
-
(qs||'').split(/[#{d}] */n).inject({}) { |h,p|
|
|
362
|
-
normalize_params(h, *unescape(p).split('=',2))
|
|
363
|
-
}.to_mash
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
NAME_REGEX = /Content-Disposition:.* name="?([^\";]*)"?/ni.freeze
|
|
367
|
-
CONTENT_TYPE_REGEX = /Content-Type: (.*)\r\n/ni.freeze
|
|
368
|
-
FILENAME_REGEX = /Content-Disposition:.* filename="?([^\";]*)"?/ni.freeze
|
|
369
|
-
CRLF = "\r\n".freeze
|
|
370
|
-
EOL = CRLF
|
|
371
|
-
def parse_multipart(request,boundary, content_length)
|
|
372
|
-
boundary = "--#{boundary}"
|
|
373
|
-
paramhsh = {}
|
|
374
|
-
buf = ""
|
|
375
|
-
input = request
|
|
376
|
-
input.binmode if defined? input.binmode
|
|
377
|
-
boundary_size = boundary.size + EOL.size
|
|
378
|
-
bufsize = 16384
|
|
379
|
-
content_length -= boundary_size
|
|
380
|
-
status = input.read(boundary_size)
|
|
381
|
-
raise ControllerExceptions::MultiPartParseError, "bad content body:\n'#{status}' should == '#{boundary + EOL}'" unless status == boundary + EOL
|
|
382
|
-
rx = /(?:#{EOL})?#{Regexp.quote(boundary,'n')}(#{EOL}|--)/
|
|
383
|
-
loop {
|
|
384
|
-
head = nil
|
|
385
|
-
body = ''
|
|
386
|
-
filename = content_type = name = nil
|
|
387
|
-
read_size = 0
|
|
388
|
-
until head && buf =~ rx
|
|
389
|
-
i = buf.index("\r\n\r\n")
|
|
390
|
-
if( i == nil && read_size == 0 && content_length == 0 )
|
|
391
|
-
content_length = -1
|
|
392
|
-
break
|
|
393
|
-
end
|
|
394
|
-
if !head && i
|
|
395
|
-
head = buf.slice!(0, i+2) # First \r\n
|
|
396
|
-
buf.slice!(0, 2) # Second \r\n
|
|
397
|
-
filename = head[FILENAME_REGEX, 1]
|
|
398
|
-
content_type = head[CONTENT_TYPE_REGEX, 1]
|
|
399
|
-
name = head[NAME_REGEX, 1]
|
|
400
|
-
|
|
401
|
-
if filename && !filename.empty?
|
|
402
|
-
body = Tempfile.new(:Merb)
|
|
403
|
-
body.binmode if defined? body.binmode
|
|
404
|
-
end
|
|
405
|
-
next
|
|
406
|
-
end
|
|
407
|
-
|
|
408
|
-
# Save the read body part.
|
|
409
|
-
if head && (boundary_size+4 < buf.size)
|
|
410
|
-
body << buf.slice!(0, buf.size - (boundary_size+4))
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
read_size = bufsize < content_length ? bufsize : content_length
|
|
414
|
-
if( read_size > 0 )
|
|
415
|
-
c = input.read(read_size)
|
|
416
|
-
raise ControllerExceptions::MultiPartParseError, "bad content body" if c.nil? || c.empty?
|
|
417
|
-
buf << c
|
|
418
|
-
content_length -= c.size
|
|
419
|
-
end
|
|
420
|
-
end
|
|
421
|
-
|
|
422
|
-
# Save the rest.
|
|
423
|
-
if i = buf.index(rx)
|
|
424
|
-
body << buf.slice!(0, i)
|
|
425
|
-
buf.slice!(0, boundary_size+2)
|
|
426
|
-
|
|
427
|
-
content_length = -1 if $1 == "--"
|
|
428
|
-
end
|
|
429
|
-
|
|
430
|
-
if filename && !filename.empty?
|
|
431
|
-
body.rewind
|
|
432
|
-
data = {
|
|
433
|
-
:filename => File.basename(filename),
|
|
434
|
-
:content_type => content_type,
|
|
435
|
-
:tempfile => body,
|
|
436
|
-
:size => File.size(body.path)
|
|
437
|
-
}
|
|
438
|
-
else
|
|
439
|
-
data = body
|
|
440
|
-
end
|
|
441
|
-
paramhsh = normalize_params(paramhsh,name,data)
|
|
442
|
-
break if buf.empty? || content_length == -1
|
|
443
|
-
}
|
|
444
|
-
paramhsh
|
|
445
|
-
end
|
|
446
|
-
|
|
447
|
-
def normalize_params(parms, name, val=nil)
|
|
448
|
-
name =~ %r([\[\]]*([^\[\]]+)\]*)
|
|
449
|
-
key = $1 || ''
|
|
450
|
-
after = $' || ''
|
|
451
|
-
|
|
452
|
-
if after == ""
|
|
453
|
-
parms[key] = val
|
|
454
|
-
elsif after == "[]"
|
|
455
|
-
(parms[key] ||= []) << val
|
|
456
|
-
else
|
|
457
|
-
parms[key] ||= {}
|
|
458
|
-
parms[key] = normalize_params(parms[key], after, val)
|
|
459
|
-
end
|
|
460
|
-
parms
|
|
461
|
-
end
|
|
462
|
-
end
|
|
463
|
-
end
|
|
464
|
-
end
|
|
465
|
-
|