vintage 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-01-01
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jeremy McAnally
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,33 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/vintage
7
+ config/hoe.rb
8
+ config/requirements.rb
9
+ lib/vintage.rb
10
+ lib/vintage/version.rb
11
+ lib/vintage/errors.rb
12
+ lib/vintage/handler.rb
13
+ lib/vintage/helpers.rb
14
+ lib/vintage/log.rb
15
+ lib/vintage/renderer.rb
16
+ lib/vintage/request_context.rb
17
+ lib/vintage/server.rb
18
+ log/debug.log
19
+ script/destroy
20
+ script/generate
21
+ setup.rb
22
+ tasks/deployment.rake
23
+ tasks/environment.rake
24
+ tasks/website.rake
25
+ test/test_helper.rb
26
+ test/test_vintage.rb
27
+ app_generators/vintage_application/USAGE
28
+ app_generators/vintage_application/vintage_application_generator.rb
29
+ app_generators/vintage_application/templates/configuration.yml
30
+ app_generators/vintage_application/templates/index.erb
31
+ app_generators/vintage_application/templates/README
32
+ app_generators/vintage_application/templates/style.css
33
+ app_generators/vintage_application/templates/vintage.png
data/README.txt ADDED
@@ -0,0 +1,40 @@
1
+ = Vintage - The super slim, microwebframework of doom!
2
+
3
+ Vintage is a very small web framework based on the original idea of Merb: Mongrel serving up
4
+ ERb (Embedded Ruby) templates. The idea has been expanded and now Vintage helps you serve up
5
+ ERb, HAML, Textile, Markdown, and Markaby templates.
6
+
7
+ == Basic Usage
8
+
9
+ To use Vintage, you have two options. You can use it in standard mode or application mode. In
10
+ standard mode, there is no configuration and Vintage will serve up templates and static files
11
+ from the current folder. To get this mode, then simply type <tt>vintage start</tt> in any folder.
12
+
13
+ $ vintage start
14
+ - vintage version 0.0.1
15
+ starting server on port 5000
16
+
17
+ Now navigating to a URL will look in the current folder for the file or template. For example, going
18
+ to <tt>http://localhost:5000/my_template</tt> will look for <tt>my_template.erb</tt> (or whatever template
19
+ engine you are using) in the current folder and render it if available. If a static file is requested, then
20
+ it is served up. If you request <tt>http://localhost:5000/my_folder/my_template</tt>, then the application
21
+ will look in <tt>my_folder</tt> for the <tt>my_template</tt> template.
22
+
23
+ === Vintage as an application server
24
+
25
+ Vintage can also be configured to be used as an application server. To do so, you can either generate an
26
+ application or hand create a <tt>configuration.yml</tt> file (see one from a generated project for an example).
27
+ To generate an application, simple run +vintage+ with a project name as the argument.
28
+
29
+ vintage my_project
30
+
31
+ This command will generate a number of files. Chief among these is <tt>configuration.yml</tt> which tells
32
+ Vintage how you'd like to run it. Other files include a sample template and the proper folder structure
33
+ for the generated configuration to work properly. This setup allows you to more easily segment your code
34
+ for easier maintenance.
35
+
36
+ == Helpers
37
+
38
+ Vintage comes with a few helpers that live in Vintage::Helpers. You can add your own helpers by creating a
39
+ <tt>helpers</tt> folder and stashing modules in there. As of right now, helpers must live in the Vintage::Helpers
40
+ module, but this will hopefully be changing very soon.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -0,0 +1,6 @@
1
+ Vintage - The super slim web framework for men and women
2
+ ========================================================
3
+
4
+ Vintage is a very small web framework based on the original idea of Merb: Mongrel serving up
5
+ ERb (Embedded Ruby) templates. The idea has been expanded and now Vintage helps you serve up
6
+ ERb, HAML, Textile, Markdown, and Markaby templates.
@@ -0,0 +1,17 @@
1
+ ---
2
+ # Path for static files
3
+ :static_path: static/
4
+ # Path for application templates
5
+ :path: app/
6
+ # Templating engine to use
7
+ :templates: erb
8
+ # Port to launch server on
9
+ :port: 5000
10
+ # Relative URL to mount application on
11
+ :mount: /
12
+ # Default template to render on root
13
+ :root: index
14
+ # You can also define error templates
15
+ # :errors:
16
+ # :not_found: not_found
17
+ # :internal_error: internal_error
@@ -0,0 +1,29 @@
1
+ <html>
2
+ <head>
3
+ <title>
4
+ Welcome to Vintage
5
+ </title>
6
+ <link rel="stylesheet" href="style.css" />
7
+ </head>
8
+ <body>
9
+ <img src="vintage.png" />
10
+ <h1>Welcome to Vintage</h1>
11
+ <p>
12
+ Come on in and relax. Actually, don't relax. Build something.
13
+ </p>
14
+ <div>
15
+ <h2>Request Information</h2>
16
+ <ul>
17
+ <li>Remote IP: <%= request.remote_ip %></li>
18
+ <li>Referer: <%= request.referer %></li>
19
+ <li>Requested URI: <%= request.uri %></li>
20
+ <li>Request method: <%= request.method %></li>
21
+ <li>User agent: <%= request.user_agent %></li>
22
+ <li>Query string: <%= request.query_string %></li>
23
+ <li>Parameters: <%= request.params == {} ? "None" : request.params.to_a.map{|k,v| "#{k} = #{v}"}.join(", ") %></li>
24
+ </ul>
25
+ </div>
26
+ <br />
27
+ <%= link_to "Vintage homepage", "http://vintage.rubyforge.org" %>
28
+ </body>
29
+ </html>
@@ -0,0 +1,8 @@
1
+ BODY { background: #3E2B09; text-align: center; font-family: sans-serif; }
2
+ h1 { color: white; }
3
+ p { color: #ccd69f; }
4
+ div { background: #ccd69f; color: black; width: 450px; padding: 10px; margin: auto; border: 2px solid #aab47d;}
5
+ div h2 { font-size: 14pt; color: #33400a; margin: 0px; }
6
+ div ul { list-style-type: none; }
7
+ div ul li { padding: 0px; margin: 8px 0px; text-align: left; }
8
+ A { color: white; }
@@ -0,0 +1,71 @@
1
+ class VintageApplicationGenerator < RubiGen::Base
2
+
3
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
4
+ Config::CONFIG['ruby_install_name'])
5
+
6
+ default_options :author => nil
7
+
8
+ attr_reader :name
9
+
10
+ def initialize(runtime_args, runtime_options = {})
11
+ super
12
+ usage if args.empty?
13
+ @destination_root = File.expand_path(args.shift)
14
+ @name = base_name
15
+ extract_options
16
+ end
17
+
18
+ def manifest
19
+ record do |m|
20
+ # Ensure appropriate folder(s) exists
21
+ m.directory ''
22
+ BASEDIRS.each { |path| m.directory path }
23
+
24
+ m.file "configuration.yml", "configuration.yml"
25
+ m.file "README", "README"
26
+ m.file "index.erb", "app/index.erb"
27
+ m.file "vintage.png", "static/vintage.png"
28
+ m.file "style.css", "static/style.css"
29
+
30
+ # m.dependency "install_rubigen_scripts", [destination_root, 'vintage_application'],
31
+ # :shebang => options[:shebang], :collision => :force
32
+ end
33
+ end
34
+
35
+ protected
36
+ def banner
37
+ <<-EOS
38
+ Creates a ...
39
+
40
+ USAGE: #{spec.name} name"
41
+ EOS
42
+ end
43
+
44
+ def add_options!(opts)
45
+ opts.separator ''
46
+ opts.separator 'Options:'
47
+ # For each option below, place the default
48
+ # at the top of the file next to "default_options"
49
+ # opts.on("-a", "--author=\"Your Name\"", String,
50
+ # "Some comment about this option",
51
+ # "Default: none") { |options[:author]| }
52
+ opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
53
+ end
54
+
55
+ def extract_options
56
+ # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
57
+ # Templates can access these value via the attr_reader-generated methods, but not the
58
+ # raw instance variable value.
59
+ # @author = options[:author]
60
+ end
61
+
62
+ # Installation skeleton. Intermediate directories are automatically
63
+ # created so don't sweat their absence here.
64
+ BASEDIRS = %w(
65
+ app
66
+ static
67
+ helpers
68
+ test
69
+ tmp
70
+ )
71
+ end
data/bin/vintage ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Jeremy McAnally on 2008-1-1.
4
+ # Copyright (c) 2008. All rights reserved.
5
+
6
+ $:.unshift File.dirname(__FILE__)
7
+ require File.dirname(__FILE__) + '/../lib/vintage'
8
+
9
+ require 'rubygems'
10
+ require 'optparse'
11
+ require 'rubigen'
12
+
13
+ # NOTE: the option -p/--path= is given as an example, and should probably be replaced in your application.
14
+
15
+ OPTIONS = {
16
+ :path => Dir.pwd,
17
+ :static_path => Dir.pwd,
18
+ :port => 5000,
19
+ :config => 'configuration.yml',
20
+ :templates => 'erb',
21
+ :mount => '/',
22
+ :root => 'index'
23
+ }
24
+ MANDATORY_OPTIONS = %w( )
25
+
26
+ parser = OptionParser.new do |opts|
27
+ opts.banner = <<BANNER
28
+
29
+ Vintage - v.#{Vintage::VERSION::STRING}
30
+ =================
31
+ The super-micro web framework. If a project name is provided,
32
+ a new project is generated. Otherwise, Vintage will start serving
33
+ given the defaults and/or any provided options.
34
+
35
+ Usage: #{File.basename($0)} [options]
36
+ #{File.basename($0)} [project name]
37
+
38
+ Options are:
39
+ BANNER
40
+ opts.separator ""
41
+ opts.on("-p", "--path=PATH", String,
42
+ "The root path for selecting files",
43
+ "Default: ~") { |OPTIONS[:path]| }
44
+ opts.on("-P", "--port=PORT", Integer,
45
+ "The port to serve up your Vintage application on",
46
+ "Default: 5000") { |OPTIONS[:port]| }
47
+ opts.on("-c", "--config=FILE", String,
48
+ "The configuration file to use when launching this Vintage application",
49
+ "Default: configuration.rb") { |OPTIONS[:config]| }
50
+ opts.on("-t", "--template=TYPE", String,
51
+ "The parser used for templates (can be erb, haml, mab, markdown, or textile)",
52
+ "Default: erb") { |OPTIONS[:templates]| }
53
+ opts.on("-m", "--mount-at=url", String,
54
+ "The relative URL to mount this application at (e.g., vintage -m myapp will mount at http://localhost/myapp)",
55
+ "Default: none (mounted at /)") { |OPTIONS[:mount]| }
56
+ opts.on("-r", "--root=template", String,
57
+ "The template to render at the root URL",
58
+ "Default: index") { |OPTIONS[:root]| }
59
+ opts.on("-h", "--help",
60
+ "Show this help message.") { puts opts; exit }
61
+ opts.parse!(ARGV)
62
+ end
63
+
64
+ if ARGV.empty?
65
+ puts parser
66
+ puts
67
+ elsif ARGV[0] == "start"
68
+ OPTIONS.merge!(YAML::load_file(OPTIONS[:config])) if File.exists?(OPTIONS[:config])
69
+ Vintage::Server.run(OPTIONS)
70
+ else
71
+ require 'rubigen/scripts/generate'
72
+ source = RubiGen::PathSource.new(:application, File.join(File.dirname(__FILE__), "../app_generators"))
73
+ RubiGen::Base.reset_sources
74
+ RubiGen::Base.append_sources source
75
+ RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'vintage_application')
76
+ end
data/config/hoe.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'vintage/version'
2
+
3
+ AUTHOR = 'Jeremy McAnally' # can also be an array of Authors
4
+ EMAIL = "jeremymcanally@gmail.com"
5
+ DESCRIPTION = "A super simple web framework"
6
+ GEM_NAME = 'vintage' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'vintage' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+
11
+ @config_file = "~/.rubyforge/user-config.yml"
12
+ @config = nil
13
+ RUBYFORGE_USERNAME = "unknown"
14
+ def rubyforge_username
15
+ unless @config
16
+ begin
17
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
18
+ rescue
19
+ puts <<-EOS
20
+ ERROR: No rubyforge config file found: #{@config_file}
21
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
22
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
23
+ EOS
24
+ exit
25
+ end
26
+ end
27
+ RUBYFORGE_USERNAME.replace @config["username"]
28
+ end
29
+
30
+
31
+ REV = nil
32
+ # UNCOMMENT IF REQUIRED:
33
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
34
+ VERS = Vintage::VERSION::STRING + (REV ? ".#{REV}" : "")
35
+ VERSION = VERS
36
+ RDOC_OPTS = ['--quiet', '--title', 'vintage documentation',
37
+ "--opname", "index.html",
38
+ "--line-numbers",
39
+ "--main", "README",
40
+ "--inline-source"]
41
+
42
+ class Hoe
43
+ def extra_deps
44
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
45
+ @extra_deps
46
+ end
47
+ end
48
+
49
+ # Generate all the Rake tasks
50
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
51
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
52
+ p.author = AUTHOR
53
+ p.description = DESCRIPTION
54
+ p.email = EMAIL
55
+ p.summary = DESCRIPTION
56
+ p.url = HOMEPATH
57
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
58
+ p.test_globs = ["test/**/test_*.rb"]
59
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
60
+
61
+ # == Optional
62
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
63
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
64
+
65
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
66
+
67
+ end
68
+
69
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
70
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
71
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
72
+ hoe.rsync_args = '-av --delete --ignore-errors'
@@ -0,0 +1,17 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
16
+
17
+ require 'vintage'
@@ -0,0 +1,76 @@
1
+ module Vintage
2
+ # A class to render the default error pages. These will
3
+ # not render if error pages are specified in the configuration.
4
+ class ErrorReporter
5
+ # Standard template to render for a <tt>500 Internal Server Error</tt>
6
+ def self.internal_error(error, params)
7
+ """
8
+ <html>
9
+ <head>
10
+ <title>Vintage Error: 500 Internal Server Error</title>
11
+ <style>
12
+ body { margin: 0px; padding: 0px; font-family: sans-serif; }
13
+ h1 { background: #3E2B09; padding: 45px 10px 10px 10px; color: #6F5E3C; border: 0px; border-bottom: 2px solid #1C0907; margin: 0px; }
14
+ h1 span.error { text-shadow: 0.1em 0.1em #333; color: white; }
15
+ h2 { margin: 0px; padding: 5px 5px 10px 10px; font-size: 14pt !important; }
16
+ h2 span.where { color: #999; }
17
+ h3 { margin: 0px; padding: 10px 10px; color: #999;}
18
+ ul { margin: 0px; }
19
+ li { margin: 0px; padding: 0px 30px; }
20
+ pre { padding: 0 30px; margin: 0px; }
21
+ </style>
22
+ </head>
23
+
24
+ <body>
25
+ <h1><span class='error'>#{error.class}</span> 500 Internal Server Error</h1>
26
+ <h2>#{error.message} <span class='where'>at #{error.backtrace[0]}</span></h2>
27
+ <div>
28
+ <h3>Parameters</h3>
29
+ <ul>
30
+ #{params == {} ? "None" : params.to_a.map{|key, val| "<li><b>" + key.to_s + "<b> = " + val.to_s + "</li>"}.join("\n") }
31
+ </ul>
32
+ <br />
33
+ <h3>Backtrace</h3>
34
+ <pre>#{error.backtrace.join("\n")}</pre>
35
+ </div>
36
+ </body>
37
+ </html>
38
+
39
+ """
40
+ end
41
+
42
+ # Standard template to render for a <tt>404 Page Not Found</tt> error
43
+ def self.not_found(url, remote_ip, params)
44
+ """
45
+ <html>
46
+ <head>
47
+ <title>Vintage Error: 404 Page Not Found</title>
48
+ <style>
49
+ body { margin: 0px; padding: 0px; font-family: sans-serif; }
50
+ h1 { background: #3E2B09; padding: 45px 10px 10px 10px; color: #6F5E3C; border: 0px; border-bottom: 2px solid #1C0907; margin: 0px; }
51
+ h1 span.error { text-shadow: 0.1em 0.1em #333; color: white; }
52
+ h2 { margin: 0px; padding: 5px 5px 10px 10px; font-size: 14pt !important; }
53
+ h2 span.where { color: #999; }
54
+ h3 { margin: 0px; padding: 10px 10px; color: #999;}
55
+ ul { margin: 0px; }
56
+ li { margin: 0px; padding: 0px 30px; }
57
+ pre { padding: 0 30px; margin: 0px; }
58
+ </style>
59
+ </head>
60
+
61
+ <body>
62
+ <h1><span class='error'>Page Not Found</span> 404 Not Found</h1>
63
+ <h2>Request for #{url} <span class='where'>from #{remote_ip}</span></h2>
64
+ <div>
65
+ <h3>Parameters</h3>
66
+ <ul>
67
+ #{params == {} ? "None" : params.to_a.map{|key, val| "<li><b>" + key.to_s + "<b> = " + val.to_s + "</li>"}.join("\n") }
68
+ </ul>
69
+ </div>
70
+ </body>
71
+ </html>
72
+
73
+ """
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,121 @@
1
+ require 'rubygems'
2
+ require 'mongrel'
3
+ require 'erubis'
4
+ require 'erb'
5
+ require 'mime/types'
6
+
7
+ require 'vintage/renderer'
8
+ require 'vintage/request_context'
9
+ require 'vintage/errors'
10
+
11
+ module Vintage
12
+ # The Mongrel HTTP Handler. Handles all operations with requests.
13
+ class Handler < Mongrel::HttpHandler
14
+ def initialize(options)
15
+ # Make our configuration options avialable to the handler
16
+ @options = options
17
+
18
+ # Setup a DirHandler for sending static files securely
19
+ @static_handler = Mongrel::DirHandler.new(@options[:static_path], false, nil)
20
+
21
+ # Inject our helpers in the RequestContext class to make them
22
+ # available on each request.
23
+ include_helpers
24
+ end
25
+
26
+ # Main request handler for Mongrel.
27
+ def process(request, response)
28
+ # Parse params into a nice Hash
29
+ handle_params(request.params["QUERY_STRING"])
30
+
31
+ # Setup our request's path
32
+ @request_path = request.params["PATH_INFO"]
33
+
34
+ # Setup up the request's context (response and request information)
35
+ context = RequestContext.new(request, @params, {})
36
+
37
+ # Initialize the buffered log entry
38
+ log_entry = ""
39
+ log_entry << "*** request for [#{request.params['REQUEST_URI']}] from [#{request.params['REMOTE_ADDR']}]\n"
40
+
41
+ # If it's a root request, we want to render the template we configured
42
+ @request_path = @options[:root] if @request_path == '/'
43
+
44
+ # If it's a static file we don't need to append a file extension
45
+ filename = (@request_path =~ /\.(.*)$/) ? "#{@options[:static_path]}/#{@request_path}" : "#{@options[:path]}/#{@request_path}.#{@options[:templates]}"
46
+
47
+ # Does the file exist...?
48
+ if File.exists?(filename)
49
+ # It's found! Let's add to our log entry...
50
+ log_entry << " response: [200]\n"
51
+ log_entry << " rendering [#{@request_path}]\n"
52
+
53
+ # Is it a static file?
54
+ if (@request_path =~ /\.(.*)$/)
55
+ # Yes? Let our static handler take it away!
56
+ @static_handler.process(request, response)
57
+ else
58
+ # No! Render a template...
59
+ content = Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@request_path}.#{@options[:templates]}", "r").read, context)
60
+ end
61
+
62
+ # Render (if response is 200) or redirect
63
+ response.start(context.response.code) do |head, out|
64
+ # Add any custom headers (e.g., from redirect_to)
65
+ context.response.headers.each do |k,v|
66
+ head[k] = v
67
+ end
68
+
69
+ # Set the content type if we're responding with a render
70
+ head["Content-Type"] = "text/html" if context.response.code == 200
71
+
72
+ # Write out to the response
73
+ out.write content
74
+ end
75
+ else
76
+ # Page not found
77
+ response.start(404) do |head, out|
78
+ # Log the 404
79
+ log_entry << " response: [404]\n"
80
+ log_entry << " rendering 'page not found'\n"
81
+
82
+ # Send back the default or a custom template
83
+ head["Content-Type"] = "text/html"
84
+ out.write @options[:errors] && @options[:errors][:not_found] ? Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@options[:errors][:not_found]}.#{@options[:templates]}", "r").read, context) : ErrorReporter.not_found(@request_path, request.params['REMOTE_ADDR'], @params)
85
+ end
86
+ end
87
+ rescue StandardError => err
88
+ # OOPS! Something broke.
89
+ response.start(500) do |head, out|
90
+ # Log it and send an error page...
91
+ log_entry << "\t!!! [500] #{err}\n"
92
+ head["Content-Type"] = "text/html"
93
+ out.write @options[:errors] && @options[:errors][:internal_error] ? Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@options[:errors][:internal_error]}.#{@options[:templates]}", "r").read, context) : ErrorReporter.internal_error(err, @params)
94
+ end
95
+ ensure
96
+ # After every request push the buffered log entry out to the logger
97
+ Log.enter log_entry.to_s + "\n"
98
+ end
99
+
100
+ # Parse HTTP params into a +Hash+.
101
+ def handle_params(params)
102
+ @params = {}
103
+
104
+ unless params == nil || params == ''
105
+ # Split the query string and hack it up
106
+ params.split('&').each do |param|
107
+ key, val = param.split('=')
108
+
109
+ @params[key.to_sym] = val
110
+ end
111
+ end
112
+ end
113
+
114
+ # Inject the default helpers and helpers from the
115
+ # +helpers/+ directory (if available) into the
116
+ # RequestContext class.
117
+ def include_helpers
118
+ RequestContext.send(:include, Vintage::Helpers)
119
+ end
120
+ end
121
+ end