Changeset 2
- Timestamp:
- 01/05/08 13:34:30 (7 months ago)
- Files:
-
- bin/vintage (modified) (2 diffs)
- lib/vintage/handler.rb (modified) (5 diffs)
- lib/vintage/request_context.rb (modified) (1 diff)
- lib/vintage/server.rb (modified) (2 diffs)
- requests.log (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
bin/vintage
r1 r2 20 20 :templates => 'erb', 21 21 :mount => '/', 22 :root => 'index' 22 :root => 'index', 23 :server => 'mongrel' 23 24 } 24 25 MANDATORY_OPTIONS = %w( ) … … 57 58 "The template to render at the root URL", 58 59 "Default: index") { |OPTIONS[:root]| } 60 opts.on("-s", "--server=server", String, 61 "The server daemon to use (can be mongrel, webrick, cgi, or fastcgi)", 62 "Default: mongrel") { |OPTIONS[:server]| } 59 63 opts.on("-h", "--help", 60 64 "Show this help message.") { puts opts; exit } lib/vintage/handler.rb
r1 r2 3 3 require 'erubis' 4 4 require 'erb' 5 5 6 require 'mime/types' 6 7 … … 11 12 module Vintage 12 13 # The Mongrel HTTP Handler. Handles all operations with requests. 13 class Handler < Mongrel::HttpHandler14 class Handler 14 15 def initialize(options) 15 16 # Make our configuration options avialable to the handler … … 17 18 18 19 # Setup a DirHandler for sending static files securely 19 @static_handler = Mongrel::DirHandler.new(@options[:static_path], false, nil)20 @static_handler = Rack::File.new(@options[:static_path]) 20 21 21 22 # Inject our helpers in the RequestContext class to make them … … 25 26 26 27 # 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 28 def call(env) 29 # Setup up the request's context (response and request information) 30 request = Rack::Request.new(env) 31 context = RequestContext.new(request) 32 31 33 # 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 34 @request_path = request.path_info 35 37 36 # Initialize the buffered log entry 38 37 log_entry = "" 39 log_entry << "*** request for [#{request. params['REQUEST_URI']}] from [#{request.params['REMOTE_ADDR']}]\n"38 log_entry << "*** request for [#{request.url}] from [#{env['REMOTE_ADDR']}]\n" 40 39 41 40 # If it's a root request, we want to render the template we configured … … 54 53 if (@request_path =~ /\.(.*)$/) 55 54 # Yes? Let our static handler take it away! 56 @static_handler. process(request, response)55 @static_handler.call(env) 57 56 else 58 57 # No! Render a template... 59 58 content = Renderer.send(@options[:templates].to_sym, File.open("#{@options[:path]}#{@request_path}.#{@options[:templates]}", "r").read, context) 60 end61 59 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 60 # Render (if response is 200) or redirect 69 61 # 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 62 context.response.headers["Content-Type"] = "text/html" if context.response.code == 200 63 [context.response.code, {}.merge!(context.response.headers), content] 74 64 end 75 65 else 76 66 # 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 67 # Log the 404 68 log_entry << " response: [404]\n" 69 log_entry << " rendering 'page not found'\n" 70 71 # Send back the default or a custom template 72 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) 73 [context.response.code, {}.merge!(context.response.headers), content] 86 74 end 87 75 rescue StandardError => err 88 76 # 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 end77 context.response.code = 500 78 79 # Log it and send an error page... 80 log_entry << "\t!!! [500] #{err}\n" 81 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) 82 [context.response.code, {}.merge!(context.response.headers), content] 95 83 ensure 96 84 # After every request push the buffered log entry out to the logger 97 85 Log.enter log_entry.to_s + "\n" 98 end99 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 up106 params.split('&').each do |param|107 key, val = param.split('=')108 109 @params[key.to_sym] = val110 end111 end112 86 end 113 87 lib/vintage/request_context.rb
r1 r2 1 # Class that encapsulates information about the request. 2 class Request 3 attr_accessor :remote_ip, :method, :params, :query_string, :uri, :referer, :user_agent 1 require 'rack' 2 require 'rack/file' 3 4 module Vintage 5 # Class that encapsulates the response's headers and 6 # response code. 7 class Response 8 attr_accessor :headers, :code 4 9 5 def initialize(request, param_hash) 6 self.remote_ip = request.params['REMOTE_ADDR'] 7 self.referer = request.params['HTTP_REFERER'] 8 self.uri = request.params['REQUEST_URI'] 9 self.method = request.params['REQUEST_METHOD'] 10 self.user_agent = request.params['HTTP_USER_AGENT'] 11 self.query_string = request.params['QUERY_STRING'] 12 self.params = param_hash 10 def initialize 11 self.headers = {} 12 self.code = 200 13 end 14 end 15 16 # A class that creates a context for template 17 # rendering. Helpers are mixed in here to give 18 # templates access to them. 19 class RequestContext 20 attr_accessor :request, :response 21 22 def initialize(incoming_request) 23 self.request = incoming_request 24 self.response = Vintage::Response.new 25 end 13 26 end 14 27 end 15 28 16 # Class that encapsulates the response's headers and 17 # response code. 18 class Response 19 attr_accessor :headers, :code 20 21 def initialize(headers) 22 self.headers = headers 23 self.code = 200 29 module Rack 30 class Request 31 def remote_ip 32 @env['REMOTE_ADDR'] 33 end 34 35 def user_agent 36 @env['HTTP_USER_AGENT'] 37 end 24 38 end 25 39 end 26 27 # A class that creates a context for template28 # rendering. Helpers are mixed in here to give29 # templates access to them.30 class RequestContext31 attr_accessor :request, :response32 33 def initialize(incoming_request, params, headers)34 self.request = Request.new(incoming_request, params)35 self.response = Response.new(headers)36 end37 endlib/vintage/server.rb
r1 r2 7 7 require 'vintage/log' 8 8 require 'vintage/helpers' 9 10 require 'rack' 11 require 'rack/file' 9 12 10 13 begin … … 23 26 Log.enter "\t starting server on port #{options[:port]}" 24 27 Log.enter 28 29 application = Handler.new(options) 30 31 server = Rack::Handler::Mongrel 25 32 26 h = Mongrel::HttpServer.new("0.0.0.0", options[:port]) 27 h.register(options[:mount], Handler.new(options)) 28 h.run.join 33 case options[:server] 34 when "mongrel" 35 server = Rack::Handler::Mongrel 36 when "webrick" 37 server = Rack::Handler::WEBrick 38 when "cgi" 39 server = Rack::Handler::CGI 40 when "fastcgi" 41 server = Rack::Handler::FastCGI 42 end 43 44 server.run application, {:Port => options[:port], :Host => "0.0.0.0", :AccessLog => []} 29 45 rescue Interrupt 30 46 Log.enter requests.log
r1 r2 7 7 shutting server down 8 8 9 - vintage version 0.0.1 10 starting server on port 5000 11 12 13 - interrupt signal caught 14 shutting server down 15
