about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-06-18 04:57:26 +0000
committerzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-06-18 04:57:26 +0000
commit364270615b8e6f1bd5cc8611267137f1a83b8124 (patch)
treeaff4bf91f421237f8fb39e666c9e7f4666fbe356 /lib
parente5c6b9ad70d844f4d656efa2306c2f7973cb2fee (diff)
downloadunicorn-364270615b8e6f1bd5cc8611267137f1a83b8124.tar.gz
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@245 19e92222-5c0b-0410-8929-a290d50e31e9
Diffstat (limited to 'lib')
-rw-r--r--lib/mongrel.rb33
-rw-r--r--lib/mongrel/handlers.rb59
2 files changed, 86 insertions, 6 deletions
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 6090708..4432a2e 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -171,6 +171,7 @@ module Mongrel
     HTTP_X_FORWARDED_FOR="HTTP_X_FORWARDED_FOR".freeze
     HTTP_IF_UNMODIFIED_SINCE="HTTP_IF_UNMODIFIED_SINCE".freeze
     HTTP_IF_NONE_MATCH="HTTP_IF_NONE_MATCH".freeze
+    REDIRECT = "HTTP/1.1 302 Found\r\nLocation: %s\r\nConnection: close\r\n\r\n".freeze
   end
 
 
@@ -534,9 +535,15 @@ module Mongrel
               params[Const::PATH_INFO] = path_info
               params[Const::SCRIPT_NAME] = script_name
               params[Const::REMOTE_ADDR] = params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last
+              data = data[nparsed ... data.length] || ""
+
+              if handlers[0].request_notify
+                # this first handler wants to be notified when the process starts
+                handlers[0].request_begins(params)
+              end
 
               # TODO: Find a faster/better way to carve out the range, preferably without copying.
-              request = HttpRequest.new(params, data[nparsed ... data.length] || "", client)
+              request = HttpRequest.new(params, data, client)
 
               # in the case of large file uploads the user could close the socket, so skip those requests
               break if request.body == nil  # nil signals from HttpRequest::initialize that the request was aborted
@@ -926,6 +933,16 @@ module Mongrel
       GemPlugin::Manager.instance.create(name, ops)
     end
 
+    # Let's you do redirects easily as described in Mongrel::RedirectHandler.
+    # You use it inside the configurator like this:
+    #
+    #   redirect("/test", "/to/there") # simple
+    #   redirect("/to", /t/, 'w') # regexp
+    #   redirect("/hey", /(w+)/) {|match| ...}  # block
+    #
+    def redirect(from, pattern, replacement = nil, &block)
+      uri from, :handler => Mongrel::RedirectHandler.new(pattern, replacement, &block)
+    end
 
     # Works like a meta run method which goes through all the
     # configured listeners.  Use the Configurator.join method
@@ -968,13 +985,21 @@ module Mongrel
     # found in Rails applications that are either slow or become unresponsive
     # after a little while.
     #
-    # TODO: Document the optional selections from the what parameter
+    # You can pass an extra parameter *what* to indicate what you want to
+    # debug.  For example, if you just want to dump rails stuff then do:
+    #
+    #   debug "/", what = [:rails]
+    #
+    # And it will only produce the log/mongrel_debug/rails.log file.
+    # Available options are:  :object, :railes, :files, :threads, :params
+    #
+    # NOTE: Use [:files] to get acccesses dumped to stderr like with WEBrick.
     def debug(location, what = [:object, :rails, :files, :threads, :params])
       require 'mongrel/debug'
       handlers = {
-        :object => "/handlers/requestlog::access",
+        :files => "/handlers/requestlog::access",
         :rails => "/handlers/requestlog::files",
-        :files => "/handlers/requestlog::objects",
+        :object => "/handlers/requestlog::objects",
         :threads => "/handlers/requestlog::threads",
         :params => "/handlers/requestlog::params"
       }
diff --git a/lib/mongrel/handlers.rb b/lib/mongrel/handlers.rb
index d20ca17..509d3e9 100644
--- a/lib/mongrel/handlers.rb
+++ b/lib/mongrel/handlers.rb
@@ -31,11 +31,19 @@ module Mongrel
   # should be implemented using the HttpHandlerPlugin mixin.
   #
   class HttpHandler
-    attr_reader :header_only
+    attr_reader :request_notify
     attr_accessor :listener
 
+    # This will be called by Mongrel on the *first* (index 0) handler *if* it has
+    # HttpHandler.request_notify set to *true*.  You only get the parameters
+    # for the request, with the idea that you'd "bound" the beginning of the
+    # request processing and the first call to process.
+    def request_begins(params)
+    end
+
     def process(request, response)
     end
+
   end
 
 
@@ -45,9 +53,12 @@ module Mongrel
   # the process method later.
   module HttpHandlerPlugin
     attr_reader :options
-    attr_reader :header_only
+    attr_reader :request_notify
     attr_accessor :listener
 
+    def request_begins(params)
+    end
+
     def initialize(options={})
       @options = options
       @header_only = false
@@ -398,4 +409,48 @@ 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
+        @replacement = 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