From d2dcbb98ae7c3963c0c658c196644095ccaec1ca Mon Sep 17 00:00:00 2001 From: Ian Ownbey Date: Mon, 1 Dec 2008 03:45:02 -0500 Subject: Got rid of handlers and test_conditional, now people just use rack --- lib/mongrel/handlers.rb | 236 ------------------------------------------------ 1 file changed, 236 deletions(-) (limited to 'lib/mongrel') diff --git a/lib/mongrel/handlers.rb b/lib/mongrel/handlers.rb index e643025..ce24628 100644 --- a/lib/mongrel/handlers.rb +++ b/lib/mongrel/handlers.rb @@ -88,198 +88,6 @@ module Mongrel end - # - # Serves the contents of a directory. You give it the path to the root - # where the files are located, and it tries to find the files based on - # the PATH_INFO inside the directory. If the requested path is a - # directory then it returns a simple directory listing. - # - # It does a simple protection against going outside it's root path by - # converting all paths to an absolute expanded path, and then making - # sure that the final expanded path includes the root path. If it doesn't - # than it simply gives a 404. - # - # If you pass nil as the root path, it will not check any locations or - # expand any paths. This lets you serve files from multiple drives - # on win32. It should probably not be used in a public-facing way - # without additional checks. - # - # The default content type is "text/plain; charset=ISO-8859-1" but you - # can change it anything you want using the DirHandler.default_content_type - # attribute. - # - class DirHandler < HttpHandler - attr_accessor :default_content_type - attr_reader :path - - MIME_TYPES_FILE = "mime_types.yml" - MIME_TYPES = YAML.load_file(File.join(File.dirname(__FILE__), MIME_TYPES_FILE)) - - ONLY_HEAD_GET="Only HEAD and GET allowed.".freeze - - # You give it the path to the directory root and and optional listing_allowed and index_html - def initialize(path, listing_allowed=true, index_html="index.html") - @path = File.expand_path(path) if path - @listing_allowed = listing_allowed - @index_html = index_html - @default_content_type = "application/octet-stream".freeze - end - - # Checks if the given path can be served and returns the full path (or nil if not). - def can_serve(path_info) - - req_path = HttpRequest.unescape(path_info) - # Add the drive letter or root path - req_path = File.join(@path, req_path) if @path - req_path = File.expand_path req_path - - if File.exist? req_path and (!@path or req_path.index(@path) == 0) - # It exists and it's in the right location - if File.directory? req_path - # The request is for a directory - index = File.join(req_path, @index_html) - if File.exist? index - # Serve the index - return index - elsif @listing_allowed - # Serve the directory - return req_path - else - # Do not serve anything - return nil - end - else - # It's a file and it's there - return req_path - end - else - # does not exist or isn't in the right spot - return nil - end - end - - - # Returns a simplistic directory listing if they're enabled, otherwise a 403. - # Base is the base URI from the REQUEST_URI, dir is the directory to serve - # on the file system (comes from can_serve()), and response is the HttpResponse - # object to send the results on. - def send_dir_listing(base, dir, response) - # take off any trailing / so the links come out right - base = HttpRequest.unescape(base) - base.chop! if base[-1] == "/"[-1] - - if @listing_allowed - response.start(200) do |head,out| - head[Const::CONTENT_TYPE] = "text/html" - out << "Directory Listing" - Dir.entries(dir).each do |child| - next if child == "." - out << "" - out << (child == ".." ? "Up to parent.." : child) - out << "
" - end - out << "" - end - else - response.start(403) do |head,out| - out.write("Directory listings not allowed") - end - end - end - - - # Sends the contents of a file back to the user. Not terribly efficient since it's - # opening and closing the file for each read. - def send_file(req_path, request, response, header_only=false) - - stat = File.stat(req_path) - - # Set the last modified times as well and etag for all files - mtime = stat.mtime - # Calculated the same as apache, not sure how well the works on win32 - etag = Const::ETAG_FORMAT % [mtime.to_i, stat.size, stat.ino] - - modified_since = request.params[Const::HTTP_IF_MODIFIED_SINCE] - none_match = request.params[Const::HTTP_IF_NONE_MATCH] - - # test to see if this is a conditional request, and test if - # the response would be identical to the last response - same_response = case - when modified_since && !last_response_time = Time.httpdate(modified_since) rescue nil : false - when modified_since && last_response_time > Time.now : false - when modified_since && mtime > last_response_time : false - when none_match && none_match == '*' : false - when none_match && !none_match.strip.split(/\s*,\s*/).include?(etag) : false - else modified_since || none_match # validation successful if we get this far and at least one of the header exists - end - - header = response.header - header[Const::ETAG] = etag - - if same_response - response.start(304) {} - else - - # First we setup the headers and status then we do a very fast send on the socket directly - - # Support custom responses except 404, which is the default. A little awkward. - response.status = 200 if response.status == 404 - header[Const::LAST_MODIFIED] = mtime.httpdate - - # Set the mime type from our map based on the ending - dot_at = req_path.rindex('.') - if dot_at - header[Const::CONTENT_TYPE] = MIME_TYPES[req_path[dot_at .. -1]] || @default_content_type - else - header[Const::CONTENT_TYPE] = @default_content_type - end - - # send a status with out content length - response.send_status(stat.size) - response.send_header - - if not header_only - response.send_file(req_path, stat.size < Const::CHUNK_SIZE * 2) - end - end - end - - # Process the request to either serve a file or a directory listing - # if allowed (based on the listing_allowed parameter to the constructor). - def process(request, response) - req_method = request.params[Const::REQUEST_METHOD] || Const::GET - req_path = can_serve request.params[Const::PATH_INFO] - if not req_path - # not found, return a 404 - response.start(404) do |head,out| - out << "File not found" - end - else - begin - if File.directory? req_path - send_dir_listing(request.params[Const::REQUEST_URI], req_path, response) - elsif req_method == Const::HEAD - send_file(req_path, request, response, true) - elsif req_method == Const::GET - send_file(req_path, request, response, false) - else - response.start(403) {|head,out| out.write(ONLY_HEAD_GET) } - end - rescue => details - STDERR.puts "Error sending file #{req_path}: #{details}" - end - end - end - - # There is a small number of default mime types for extensions, but - # this lets you add any others you'll need when serving content. - def DirHandler::add_mime_type(extension, type) - MIME_TYPES[extension] = type - end - - end - - # When added to a config script (-S in mongrel_rails) it will # look at the client's allowed response types and then gzip # compress anything that is going out. @@ -421,48 +229,4 @@ module Mongrel end end end - - # This handler allows you to redirect one url to another. - # You can use it like String#gsub, where the string is the REQUEST_URI. - # REQUEST_URI is the full path with GET parameters. - # - # Eg. /test/something?help=true&disclaimer=false - # - # == Examples - # - # h = Mongrel::HttpServer.new('0.0.0.0') - # h.register '/test', Mongrel::RedirectHandler.new('/to/there') # simple - # h.register '/to', Mongrel::RedirectHandler.new(/t/, 'w') # regexp - # # and with a block - # h.register '/hey', Mongrel::RedirectHandler.new(/(\w+)/) { |match| ... } - # - class RedirectHandler < Mongrel::HttpHandler - # You set the rewrite rules when building the object. - # - # pattern => What to look for or replacement if used alone - # - # replacement, block => One of them is used to replace the found text - - def initialize(pattern, replacement = nil, &block) - unless replacement or block - @pattern, @replacement = nil, pattern - else - @pattern, @replacement, @block = pattern, replacement, block - end - end - - # Process the request and return a redirect response - def process(request, response) - unless @pattern - response.socket.write(Mongrel::Const::REDIRECT % @replacement) - else - if @block - new_path = request.params['REQUEST_URI'].gsub(@pattern, &@block) - else - new_path = request.params['REQUEST_URI'].gsub(@pattern, @replacement) - end - response.socket.write(Mongrel::Const::REDIRECT % new_path) - end - end - end end -- cgit v1.2.3-24-ge0c7