Class: Vintage::Handler

Inherits:
Object
  • Object
show all
Defined in:
lib/vintage/handler.rb

Overview

The Mongrel HTTP Handler. Handles all operations with requests.

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Handler

Returns a new instance of Handler.



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/vintage/handler.rb', line 15

def initialize(options)
  # Make our configuration options avialable to the handler
  @options = options
  
  # Setup a DirHandler for sending static files securely
  @static_handler = Rack::File.new(@options[:static_path])
  
  # Inject our helpers in the RequestContext class to make them
  # available on each request.
  include_helpers
end

Instance Method Details

#call(env) ⇒ Object

Main request handler for Mongrel.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/vintage/handler.rb', line 28

def call(env)
  # Setup up the request's context (response and request information)
  request = Rack::Request.new(env)
  context = RequestContext.new(request)

  # Setup our request's path
  @request_path = request.path_info

  # Initialize the buffered log entry
  log_entry = ""
  log_entry << "*** request for [#{request.url}] from [#{env['REMOTE_ADDR']}]\n"

  # If it's a root request, we want to render the template we configured
  @request_path = @options[:root] if @request_path == '/'
  
  # If it's a static file we don't need to append a file extension
  filename = (@request_path =~ /\.(.*)$/) ? "#{@options[:static_path]}/#{@request_path}" : "#{@options[:path]}/#{@request_path}.#{@options[:templates]}"
  
  # Does the file exist...?
  if File.exists?(filename)
    # It's found!  Let's add to our log entry...
    log_entry << "    response: [200]\n"
    log_entry << "    rendering [#{@request_path}]\n"

    # Is it a static file?
    if (@request_path =~ /\.(.*)$/)
      # Yes?  Let our static handler take it away!
      @static_handler.call(env)
    else
      # No!  Render a template...
      content = Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@request_path}.#{@options[:templates]}", "r").read, context)
    
      # Set the content type if we're responding with a render
      context.response.headers["Content-Type"] = "text/html" if context.response.code == 200
      response = Rack::Response.new(content, context.response.code, {}.merge!(context.response.headers))
    
      # Render (if response is 200) or redirect 
      # Set cookies        
      if context.response.cookies != {}
        context.response.cookies.each do |key, value|
          response.set_cookie(key, value)
        end
      end
      
      response.finish
    end
  else
    # Page not found
    # Log the 404
    log_entry << "    response: [404]\n"
    log_entry << "    rendering 'page not found'\n"
    
    # Send back the default or a custom template
    content = @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)
    [context.response.code, {}.merge!(context.response.headers), content]
  end
rescue StandardError => err
  # OOPS!  Something broke.
  context.response.code = 500

  # Log it and send an error page...
  log_entry << "\t!!! [500] #{err}\n"
  content = @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)
  [context.response.code, {}.merge!(context.response.headers), content]
ensure
  # After every request push the buffered log entry out to the logger
  Log.enter log_entry.to_s + "\n"
end

#include_helpersObject

Inject the default helpers and helpers from the helpers/ directory (if available) into the RequestContext class.



100
101
102
# File 'lib/vintage/handler.rb', line 100

def include_helpers
  RequestContext.send(:include, Vintage::Helpers)
end