mack 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/README +43 -0
  2. data/bin/mack +60 -0
  3. data/bin/templates/Rakefile.template +6 -0
  4. data/bin/templates/app/controllers/default_controller.rb.template +7 -0
  5. data/bin/templates/app/helpers/application_helper.rb.template +2 -0
  6. data/bin/templates/app/views/default/index.html.erb.template +3 -0
  7. data/bin/templates/app/views/layouts/application.html.erb.template +15 -0
  8. data/bin/templates/config/app_config/default.yml.template +7 -0
  9. data/bin/templates/config/app_config/development.yml.template +0 -0
  10. data/bin/templates/config/app_config/production.yml.template +0 -0
  11. data/bin/templates/config/app_config/test.yml.template +0 -0
  12. data/bin/templates/config/boot.rb.template +6 -0
  13. data/bin/templates/config/database.yml.template +20 -0
  14. data/bin/templates/config/routes.rb.template +7 -0
  15. data/bin/templates/config/thin.ru.template +1 -0
  16. data/bin/templates/config/thin.yml.template +8 -0
  17. data/bin/templates/public/favicon.ico +0 -0
  18. data/bin/templates/public/stylesheets/scaffold.css.template +74 -0
  19. data/core_extensions/hash.rb +9 -0
  20. data/core_extensions/module.rb +29 -0
  21. data/core_extensions/nil.rb +8 -0
  22. data/core_extensions/object.rb +9 -0
  23. data/core_extensions/string.rb +28 -0
  24. data/errors/errors.rb +79 -0
  25. data/initialize/configuration.rb +99 -0
  26. data/initialize/configure_logging.rb +24 -0
  27. data/initialize/configure_orm_support.rb +23 -0
  28. data/initialize/console.rb +13 -0
  29. data/initialize/initializer.rb +88 -0
  30. data/initialize/server/simple_server.rb +21 -0
  31. data/lib/utils/html.rb +88 -0
  32. data/lib/utils/server.rb +27 -0
  33. data/mack.rb +124 -0
  34. data/mack_tasks.rb +16 -0
  35. data/routing/route_map.rb +268 -0
  36. data/routing/urls.rb +54 -0
  37. data/sea_level/controller_base.rb +293 -0
  38. data/sea_level/cookie_jar.rb +67 -0
  39. data/sea_level/filter.rb +63 -0
  40. data/sea_level/helpers/view_helpers/html_helpers.rb +33 -0
  41. data/sea_level/helpers/view_helpers/orm_helpers.rb +72 -0
  42. data/sea_level/request.rb +83 -0
  43. data/sea_level/response.rb +6 -0
  44. data/sea_level/session.rb +33 -0
  45. data/sea_level/view_binder.rb +101 -0
  46. data/tasks/cachetastic_tasks.rake +69 -0
  47. data/tasks/log_tasks.rake +9 -0
  48. data/tasks/mack_tasks.rake +15 -0
  49. data/tasks/rake_helpers.rb +24 -0
  50. data/tasks/rake_rules.rake +19 -0
  51. data/tasks/script_tasks.rake +44 -0
  52. data/tasks/test_tasks.rake +7 -0
  53. data/test_extensions/test_assertions.rb +47 -0
  54. data/test_extensions/test_helpers.rb +84 -0
  55. metadata +173 -0
@@ -0,0 +1,99 @@
1
+ module Mack
2
+ # All configuration for the Mack subsystem happens here. Each of the default environments,
3
+ # production, development, and test have their own default configuration options. These
4
+ # get merged with overall default options.
5
+ module Configuration # :nodoc:
6
+
7
+ # use local memory and store stuff for 24 hours:
8
+ # use file for sessions and store them for 4 hours:
9
+ DEFAULTS_PRODUCTION = {
10
+ "mack::use_lint" => false,
11
+ "mack::show_exceptions" => false,
12
+ "log::level" => "info",
13
+ "log::detailed_requests" => false,
14
+ "cachetastic_default_options" => {
15
+ "debug" => false,
16
+ "adapter" => "local_memory",
17
+ "expiry_time" => 86400,
18
+ "logging" => {
19
+ "logger_1" => {
20
+ "type" => "file",
21
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
22
+ }
23
+ }
24
+ },
25
+ "cachetastic_caches_mack_session_cache_options" => {
26
+ "debug" => false,
27
+ "adapter" => "file",
28
+ "store_options" =>
29
+ {"dir" => File.join(MACK_ROOT, "tmp")},
30
+ "expiry_time" => 14400,
31
+ "logging" => {
32
+ "logger_1" => {
33
+ "type" => "file",
34
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
35
+ }
36
+ }
37
+ }
38
+ } unless self.const_defined?("DEFAULTS_PRODUCTION")
39
+
40
+ # use local memory and store stuff for 5 minutes:
41
+ DEFAULTS_DEVELOPMENT = {
42
+ "mack::cache_classes" => false,
43
+ "log::level" => "debug",
44
+ "log::console" => true,
45
+ "cachetastic_default_options" => {
46
+ "debug" => false,
47
+ "adapter" => "local_memory",
48
+ "expiry_time" => 300,
49
+ "logging" => {
50
+ "logger_1" => {
51
+ "type" => "file",
52
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
53
+ }
54
+ }
55
+ }
56
+ } unless self.const_defined?("DEFAULTS_DEVELOPMENT")
57
+
58
+ # use local memory and store stuff for 1 hour:
59
+ DEFAULTS_TEST = {
60
+ "log::level" => "error",
61
+ "cachetastic_default_options" => {
62
+ "debug" => false,
63
+ "adapter" => "local_memory",
64
+ "expiry_time" => 3600,
65
+ "logging" => {
66
+ "logger_1" => {
67
+ "type" => "file",
68
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
69
+ }
70
+ }
71
+ }
72
+ } unless self.const_defined?("DEFAULTS_TEST")
73
+
74
+ unless self.const_defined?("DEFAULTS")
75
+ DEFAULTS = {
76
+ "mack::cache_classes" => true,
77
+ "mack::use_lint" => true,
78
+ "mack::show_exceptions" => true,
79
+ "mack::session_id" => "_mack_session_id",
80
+ "mack::cookie_values" => {
81
+ "path" => "/"
82
+ },
83
+ # "mack::orm" => "activerecord",
84
+ "log::detailed_requests" => true,
85
+ "log::level" => "info",
86
+ "log::console" => false,
87
+ "log::file" => true,
88
+ "log::console_format" => "%l:\t[%d]\t%M",
89
+ "log::file_format" => "%l:\t[%d]\t%M"
90
+ }.merge(eval("DEFAULTS_#{MACK_ENV.upcase}"))
91
+ end
92
+
93
+ app_config.load_hash(DEFAULTS, "mack_defaults")
94
+ app_config.load_file(File.join(MACK_CONFIG, "app_config", "default.yml"))
95
+ app_config.load_file(File.join(MACK_CONFIG, "app_config", "#{MACK_ENV}.yml"))
96
+ # app_config.reload
97
+
98
+ end
99
+ end
@@ -0,0 +1,24 @@
1
+ #--
2
+ # Configure logging
3
+ #++
4
+ include Log4r
5
+
6
+ log_dir_loc = File.join(MACK_ROOT, "log")
7
+ FileUtils.mkdir_p(log_dir_loc)
8
+
9
+ unless Object.const_defined?("MACK_DEFAULT_LOGGER")
10
+ log = Log4r::Logger.new('')
11
+ log.level = Module.instance_eval("Log4r::#{app_config.log.level.to_s.upcase}")
12
+ # console:
13
+ if app_config.log.console
14
+ console_format = PatternFormatter.new(:pattern => app_config.log.console_format)
15
+ log.add(Log4r::StdoutOutputter.new('console', :formatter => console_format))
16
+ end
17
+ # file:
18
+ if app_config.log.file
19
+ file_format = PatternFormatter.new(:pattern => app_config.log.file_format)
20
+ log.add(FileOutputter.new('fileOutputter', :filename => File.join(log_dir_loc, "#{MACK_ENV}.log"), :trunc => false, :formatter => file_format))
21
+ end
22
+
23
+ Object::MACK_DEFAULT_LOGGER = log
24
+ end
@@ -0,0 +1,23 @@
1
+ # setup ORM:
2
+
3
+ [:activerecord, :data_mapper].each do |orm|
4
+ eval("def using_#{orm}?; false; end")
5
+ end
6
+
7
+ unless app_config.mack.orm.nil?
8
+ dbs = YAML::load(ERB.new(IO.read(File.join(MACK_CONFIG, "database.yml"))).result)
9
+ case app_config.mack.orm
10
+ when 'activerecord'
11
+ require 'activerecord'
12
+ ActiveRecord::Base.establish_connection(dbs[MACK_ENV])
13
+ eval("def using_activerecord?; true; end")
14
+ when 'data_mapper'
15
+ require 'data_mapper'
16
+ DataMapper::Database.setup(dbs[MACK_ENV])
17
+ eval("def using_data_mapper?; true; end")
18
+ else
19
+ MACK_DEFAULT_LOGGER.warn("Attempted to configure an unknown ORM: #{app_config.mack.orm}")
20
+ end
21
+ else
22
+ MACK_DEFAULT_LOGGER.warn("No ORM has been configured!")
23
+ end
@@ -0,0 +1,13 @@
1
+ # This file gets loaded when you run:
2
+ # rake console
3
+ # It loads the following classes to make using the application via the console easier:
4
+ #
5
+ # * Mack::TestHelpers
6
+ # * Mack::Routes::Urls
7
+
8
+ fl = File.join(File.dirname(__FILE__), "..")
9
+
10
+ require File.join(fl, "test_extensions", "test_helpers")
11
+
12
+ self.send(:include, Mack::TestHelpers)
13
+ self.send(:include, Mack::Routes::Urls)
@@ -0,0 +1,88 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+ require 'digest'
4
+ require 'ruby_extensions'
5
+ require 'application_configuration'
6
+ require 'cachetastic'
7
+ require 'fileutils'
8
+ require 'log4r'
9
+
10
+ # Set up Mack constants, if they haven't already been set up.
11
+ unless Object.const_defined?("MACK_ENV")
12
+ (Object::MACK_ENV = (ENV["MACK_ENV"] ||= "development")).to_sym
13
+ end
14
+ (Object::MACK_ROOT = (ENV["MACK_ROOT"] ||= FileUtils.pwd)) unless Object.const_defined?("MACK_ROOT")
15
+
16
+ Object::MACK_PUBLIC = File.join(MACK_ROOT, "public") unless Object.const_defined?("MACK_PUBLIC")
17
+ Object::MACK_APP = File.join(MACK_ROOT, "app") unless Object.const_defined?("MACK_APP")
18
+ Object::MACK_LIB = File.join(MACK_ROOT, "lib") unless Object.const_defined?("MACK_LIB")
19
+ Object::MACK_CONFIG = File.join(MACK_ROOT, "config") unless Object.const_defined?("MACK_CONFIG")
20
+ Object::MACK_VIEWS = File.join(MACK_APP, "views") unless Object.const_defined?("MACK_VIEWS")
21
+ Object::MACK_LAYOUTS = File.join(MACK_VIEWS, "layouts") unless Object.const_defined?("MACK_LAYOUTS")
22
+
23
+ unless Object.const_defined?("MACK_INITIALIZED")
24
+ puts "Starting application in #{MACK_ENV} mode."
25
+
26
+ Object::MACK_INITIALIZED = true
27
+
28
+ # Set up 'Rails' constants to allow for easier use of existing gems/plugins like application_configuration.
29
+ # I would like to take these out eventually, but for right now, it's not doing too much harm.
30
+ # Object::RAILS_ENV = MACK_ENV unless Object.const_defined?("RAILS_ENV")
31
+ # Object::RAILS_ROOT = MACK_ROOT unless Object.const_defined?("RAILS_ROOT")
32
+
33
+ require File.join(File.dirname(__FILE__), "configuration.rb")
34
+
35
+ require File.join(File.dirname(__FILE__), "configure_logging.rb")
36
+
37
+ require File.join(File.dirname(__FILE__), "configure_orm_support.rb")
38
+
39
+ fl = File.join(File.dirname(__FILE__), "..")
40
+
41
+ # Require all the necessary files to make Mack actually work!
42
+ ["errors", "core_extensions", "lib", "test_extensions", "routing", "sea_level", "tasks", "initialize/server"].each do |dir|
43
+ dir_globs = Dir.glob(File.join(fl, dir, "**/*.rb"))
44
+ dir_globs.each do |d|
45
+ require d
46
+ end
47
+ end
48
+
49
+
50
+
51
+ # ------------------------------------------------------------------------
52
+
53
+ # set up application stuff:
54
+
55
+ # set up routes:
56
+ require File.join(MACK_ROOT, "config", "routes")
57
+
58
+ # require 'app' files:
59
+ Dir.glob(File.join(MACK_APP, "**/*.rb")).each do |d|
60
+ require d
61
+ end
62
+
63
+ # require 'lib' files:
64
+ Dir.glob(File.join(MACK_LIB, "**/*.rb")).each do |d|
65
+ require d
66
+ end
67
+
68
+
69
+ # ------------------------------------------------------------------------
70
+
71
+ # Include ApplicationHelper into all controllers:
72
+ if Object.const_defined?("ApplicationHelper")
73
+ ApplicationHelper.include_safely_into(Mack::Controller::Base, Mack::ViewBinder)
74
+ end
75
+ # Find other Helpers and include them into their respective controllers.
76
+ Object.constants.collect {|c| c if c.match(/Controller$/)}.compact.each do |cont|
77
+ if Object.const_defined?("#{cont}Helper")
78
+ h = "#{cont}Helper".constantize
79
+ h.include_safely_into(cont, Mack::ViewBinder)
80
+ end
81
+ end
82
+
83
+ # Find view level Helpers and include them into the Mack::ViewBinder
84
+ Mack::ViewHelpers.constants.each do |cont|
85
+ h = "Mack::ViewHelpers::#{cont}".constantize
86
+ h.include_safely_into(Mack::ViewBinder)
87
+ end
88
+ end
@@ -0,0 +1,21 @@
1
+ module Mack
2
+ # Even though it's called, SimpleServer, this might be the only server you need to run
3
+ # a Mack application.
4
+ #
5
+ # $ ruby script/server
6
+ #
7
+ # This SimpleServer does not use Thin. But does work with anything that Rack has a handler for.
8
+ class SimpleServer
9
+
10
+ class << self
11
+
12
+ def run(options)
13
+ r = "Rack::Handler::#{options.handler.camelcase}"
14
+ puts "Starting app using: #{r} in #{options.environment} mode on port: #{options.port}"
15
+ eval(r).run(Mack::Utils::Server.build_app, :Port => options.port)
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
data/lib/utils/html.rb ADDED
@@ -0,0 +1,88 @@
1
+ module Mack
2
+ module Utils
3
+ # Useful utilities for dealing with HTML.
4
+ class Html
5
+
6
+ class << self
7
+
8
+ # Used in views to create href links. It takes link_text, url, and a Hash that gets added
9
+ # to the href as options.
10
+ #
11
+ # Examples:
12
+ # Mack::Utils::Html.href("http://www.mackframework.com") # => <a href="http://www.mackframework.com">http://www.mackframework.com</a>
13
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com") # => <a href="http://www.mackframework.com">Mack</a>
14
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :target => "_blank") # => <a href="http://www.mackframework.com" target="_blank">Mack</a>
15
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :target => "_blank", :rel => :nofollow) # => <a href="http://www.mackframework.com" target="_blank" rel="nofollow">Mack</a>
16
+ # If you pass in :method as an option it will be a JavaScript form that will post to the specified link with the
17
+ # methd specified.
18
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :method => :delete)
19
+ # If you use the :method option you can also pass in a :confirm option. The :confirm option will generate a
20
+ # javascript confirmation window. If 'OK' is selected the the form will submit. If 'cancel' is selected, then
21
+ # nothing will happen. This is extremely useful for 'delete' type of links.
22
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :method => :delete, :confirm => "Are you sure?")
23
+ def href(link_text, url = link_text, html_options = {})
24
+ if html_options[:method]
25
+ meth = nil
26
+ confirm = nil
27
+
28
+ meth = %{var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', '_method'); s.setAttribute('value', '#{html_options[:method]}'); f.appendChild(s);f.submit()}
29
+ html_options.delete(:method)
30
+
31
+ if html_options[:confirm]
32
+ confirm = %{if (confirm('#{html_options[:confirm]}'))}
33
+ html_options.delete(:confirm)
34
+ end
35
+
36
+ html_options[:onclick] = (confirm ? (confirm + " { ") : "") << meth << (confirm ? (" } ") : "") << ";return false;"
37
+ end
38
+
39
+ html = "<a href=" << '"' << url
40
+ html << '"'
41
+ html << " " << html_options.join("%s=\"%s\"", " ") unless html_options.empty?
42
+ html << ">" << link_text
43
+ html << "</a>"
44
+ html
45
+ end
46
+
47
+ alias_method :a, :href
48
+
49
+ # Wraps the content_tag method.
50
+ #
51
+ # Examples:
52
+ # Mack::Utils::Html.b("hello") # => <b>hello</b>
53
+ # Mack::Utils::Html.div("hello world!", :class => :foo)) # => <div class="foo">hello world!</div>
54
+ def method_missing(sym, *args)
55
+ ags = args.from_args
56
+
57
+ tag = sym
58
+ content = nil
59
+ options = {}
60
+
61
+ if ags.is_a?(Array)
62
+ content = ags[0] if ags[0].is_a?(String)
63
+ options = ags[1] if ags[1].is_a?(Hash)
64
+ elsif ags.is_a?(String)
65
+ content = ags
66
+ elsif ags.is_a?(Hash)
67
+ options = ags
68
+ end
69
+
70
+ content = yield if block_given?
71
+
72
+ content_tag(tag, content, options)
73
+ end
74
+
75
+ # Builds an HTML tag.
76
+ #
77
+ # Examples:
78
+ # content_tag(:b, "hello") # => <b>hello</b>
79
+ # content_tag("div", "hello world!", :class => :foo) # => <div class="foo">hello world!</div>
80
+ def content_tag(tag, content, options = {})
81
+ html = "<#{tag} #{options.join("%s=\"%s\"", " ")}>#{content}</#{tag}>"
82
+ end
83
+
84
+ end # self
85
+
86
+ end # Html
87
+ end # Utils
88
+ end # Mack
@@ -0,0 +1,27 @@
1
+ module Mack
2
+ module Utils
3
+ module Server
4
+
5
+ # This method wraps all the necessary components of the Rack system around
6
+ # Mack::Runner. This can be used build your own server around the Mack framework.
7
+ def self.build_app
8
+ # Mack framework:
9
+ app = Mack::Runner.new
10
+ # Any urls listed will go straight to the public directly and will not be served up via the app:
11
+ app = Rack::Static.new(app, :urls => ["/css", "/images", "/files", "/images", "/stylesheets", "/javascripts", "/media"], :root => "public")
12
+ app = Rack::Lint.new(app) if app_config.mack.use_lint
13
+ app = Rack::ShowStatus.new(app)
14
+ app = Rack::ShowExceptions.new(app) if app_config.mack.show_exceptions
15
+ app = Rack::Recursive.new(app)
16
+ # This will reload any edited classes if the cache_classes config setting is set to true.
17
+ app = Rack::Reloader.new(app, 1) unless app_config.mack.cache_classes
18
+ # TODO: Not sure about this logger, investigate better ones.
19
+ # TODO: Depends on MACK_DEFAULT_LOGGER already being configured.
20
+ # This makes it a drag run this 'standalone' in another Ruby program.
21
+ # app = Rack::CommonLogger.new(app, MACK_DEFAULT_LOGGER)
22
+ app
23
+ end
24
+
25
+ end # Server
26
+ end # Utils
27
+ end # Mack
data/mack.rb ADDED
@@ -0,0 +1,124 @@
1
+ require File.join(File.dirname(__FILE__), "initialize", "initializer")
2
+
3
+ module Mack
4
+ # This is the heart and soul of the Mack framework! This class interfaces with the Rack framework.
5
+ # It handles all the dispatching back and forth between the Rack framework and a Mack application.
6
+ class Runner
7
+ include Mack::Routes::Urls
8
+
9
+ attr_reader :response # :nodoc:
10
+ attr_reader :request # :nodoc:
11
+ attr_reader :cookies # :nodoc:
12
+ # This method needs to be defined as part of the Rack framework. As is noted for the Mack::Runner
13
+ # class, this is where the center of the Mack framework lies.
14
+ def call(env)
15
+ begin
16
+ setup(env) do
17
+ begin
18
+ route = Mack::Routes::RouteMap.instance.get_route_from_request(self.request)
19
+ if route[:redirect_to]
20
+ # because the route is specified to be a redirect, let's do that:
21
+ redirect_to(route)
22
+ else
23
+ # let's handle a normal request:
24
+ c = "#{route[:controller].to_s.camelcase}Controller".constantize.new(self.request, self.response, self.cookies)
25
+ self.response.write(c.run)
26
+ end
27
+ rescue Mack::Errors::ResourceNotFound, Mack::Errors::UndefinedRoute => e
28
+ return try_to_find_resource(env, self.request.path_info, e)
29
+ end
30
+ end # setup
31
+ rescue Exception => e
32
+ MACK_DEFAULT_LOGGER.error(e)
33
+ raise e
34
+ end
35
+ end
36
+
37
+ private
38
+ def log_request
39
+ s_time = Time.now
40
+ x = yield
41
+ e_time = Time.now
42
+ p_time = e_time - s_time
43
+ if app_config.log.detailed_requests
44
+ msg = "\n\t[#{@request.request_method.upcase}] '#{@request.path_info}'\n"
45
+ msg << "\tSession ID: #{@request.session.id}\n"
46
+ msg << "\tParameters: #{@request.all_params.inspect}\n"
47
+ msg << "\tCompleted in #{p_time} (#{(1 / p_time).round} reqs/sec) | #{@response.status} [#{@request.full_host}]"
48
+ else
49
+ msg = "[#{@request.request_method.upcase}] '#{@request.path_info}' (#{p_time})"
50
+ end
51
+ MACK_DEFAULT_LOGGER.info(msg)
52
+ x
53
+ end
54
+
55
+ # Setup the request, response, cookies, session, etc...
56
+ # yield up, and then clean things up afterwards.
57
+ def setup(env)
58
+ log_request do
59
+ @request = Mack::Request.new(env)
60
+ @response = Mack::Response.new
61
+ @cookies = Mack::CookieJar.new(self.request, self.response)
62
+ session do
63
+ yield
64
+ end
65
+ self.response.finish
66
+ end
67
+ end
68
+
69
+ def session
70
+ sess_id = self.cookies[app_config.mack.session_id]
71
+ unless sess_id
72
+ sess_id = create_new_session
73
+ else
74
+ sess = Cachetastic::Caches::MackSessionCache.get(sess_id)
75
+ if sess
76
+ self.request.session = sess
77
+ else
78
+ # we couldn't find it in the store, so we need to create it:
79
+ sess_id = create_new_session
80
+ end
81
+ end
82
+
83
+ yield
84
+
85
+ Cachetastic::Caches::MackSessionCache.set(sess_id, self.request.session)
86
+ end
87
+
88
+ def create_new_session
89
+ id = String.randomize(40).downcase
90
+ self.cookies[app_config.mack.session_id] = {:value => id, :expires => nil}
91
+ sess = Mack::Session.new(id)
92
+ self.request.session = sess
93
+ Cachetastic::Caches::MackSessionCache.set(id, sess)
94
+ end
95
+
96
+ def try_to_find_resource(env, path_info, exception)
97
+ # we can't find a route for this, so let's try and see if it's in the public directory:
98
+ if File.extname(path_info).blank?
99
+ path_info << ".html"
100
+ end
101
+ if File.exists?(File.join(MACK_PUBLIC, path_info))
102
+ return Rack::File.new(File.join(MACK_PUBLIC)).call(env)
103
+ else
104
+ raise exception
105
+ end
106
+ end
107
+
108
+ # This will redirect the request to the specified url. A default status of
109
+ # 302, Moved Temporarily, is set if no status is specified. A simple HTML
110
+ # page is rendered in case the redirect does not occur.
111
+ def redirect_to(route)
112
+ status = route[:status] || 302
113
+ url = route[:redirect_to]
114
+ options = self.request.all_params
115
+ options.merge!(route)
116
+ options - [:controller, :action, :redirect_to, :method, :status]
117
+ url = url_for_pattern(url, options)
118
+ self.response.status = status
119
+ self.response[:location] = url
120
+ self.response.write(redirect_html(self.request.path_info, url, status))
121
+ end
122
+
123
+ end
124
+ end