about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-03-26 23:57:11 +0000
committerzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-03-26 23:57:11 +0000
commit4d9966ee00b597cff3b58c851aef65c3801d9077 (patch)
treef845b065e891869fe6df47fd6ec286146f953d8d
parentf2b53a3a4b1ddacac4fc18ccbe2b016194a50777 (diff)
downloadunicorn-4d9966ee00b597cff3b58c851aef65c3801d9077.tar.gz
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@123 19e92222-5c0b-0410-8929-a290d50e31e9
-rw-r--r--bin/mongrel_rails9
-rw-r--r--examples/mongrel.conf9
-rw-r--r--lib/mongrel.rb63
-rw-r--r--projects/mongrel_config/lib/mongrel_config/app.rb1
-rw-r--r--test/test_configurator.rb18
-rw-r--r--test/test_response.rb3
6 files changed, 73 insertions, 30 deletions
diff --git a/bin/mongrel_rails b/bin/mongrel_rails
index 23121d8..74d56be 100644
--- a/bin/mongrel_rails
+++ b/bin/mongrel_rails
@@ -22,6 +22,7 @@ class Start < GemPlugin::Plugin "/commands"
       ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
       ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
       ['-B', '--debug', "Enable debugging mode", :@debug, false],
+      ['-C', '--config PATH', "Use a config file", :@config_file, nil]
     ]
   end
   
@@ -36,18 +37,24 @@ class Start < GemPlugin::Plugin "/commands"
     valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
     valid_dir? @docroot, "Path to docroot not valid: #@docroot"
     valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
-
+    valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
     return @valid
   end
 
   def run
 
+    # command line setting override config file settings
     settings = { :host => @address,  :port => @port, :cwd => @cwd,
       :log_file => @log_file, :pid_file => @pid_file, :environment => @environment,
       :docroot => @docroot, :mime_map => @mime_map, :daemon => @daemon,
       :debug => @debug, :includes => ["mongrel"]
     }
 
+    if @config_file
+      STDERR.puts "** Loading settings from #{@config_file} (command line options override)."
+      conf = YAML.load_file(@config_file)
+      settings = conf.merge(settings)
+    end
     
     config = Mongrel::Rails::RailsConfigurator.new(settings) do
       log "Starting Mongrel in #{settings[:environment]} mode at #{settings[:host]}:#{settings[:port]}"
diff --git a/examples/mongrel.conf b/examples/mongrel.conf
new file mode 100644
index 0000000..5c77707
--- /dev/null
+++ b/examples/mongrel.conf
@@ -0,0 +1,9 @@
+---
+:environment: production
+:daemon: "true"
+:host: 0.0.0.0
+:log_file: log/mongrel.log
+:docroot: public
+:debug: "false"
+:port: 3000
+:pid_file: log/mongrel.pid
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 9c7a804..59402cc 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -5,7 +5,6 @@ require 'stringio'
 require 'mongrel/cgi'
 require 'mongrel/handlers'
 require 'mongrel/command'
-require 'timeout'
 require 'mongrel/tcphack'
 require 'yaml'
 
@@ -256,11 +255,15 @@ module Mongrel
     # Receives a block passing it the header and body for you to work with.
     # When the block is finished it writes everything you've done to
     # the socket in the proper order.  This lets you intermix header and
-    # body content as needed.
-    def start(status=200)
+    # body content as needed.  Handlers are able to modify pretty much
+    # any part of the request in the chain, and can stop further processing
+    # by simple passing "finalize=true" to the start method.  By default
+    # all handlers run and then mongrel finalizes the request when they're
+    # all done.
+    def start(status=200, finalize=false)
       @status = status.to_i
       yield @header, @body
-      finished
+      finished if finalize
     end
 
     # Primarily used in exception handling to reset the response output in order to write
@@ -268,7 +271,7 @@ module Mongrel
     # sent the header or the body.  This is pretty catastrophic actually.
     def reset
       if @body_sent
-        raise "You ahve already sent the request body."
+        raise "You have already sent the request body."
       elsif @header_sent
         raise "You have already sent the request headers."
       else
@@ -278,23 +281,29 @@ module Mongrel
     end
 
     def send_status
-      status = "HTTP/1.1 #{@status} #{HTTP_STATUS_CODES[@status]}\r\nContent-Length: #{@body.length}\r\nConnection: close\r\n"
-      @socket.write(status)
-      @status_sent = true
+      if not @status_sent
+        status = "HTTP/1.1 #{@status} #{HTTP_STATUS_CODES[@status]}\r\nContent-Length: #{@body.length}\r\nConnection: close\r\n"
+        @socket.write(status)
+        @status_sent = true
+      end
     end
 
     def send_header
-      @header.out.rewind
-      @socket.write(@header.out.read)
-      @socket.write("\r\n")
-      @header_sent = true
+      if not @header_sent
+        @header.out.rewind
+        @socket.write(@header.out.read)
+        @socket.write("\r\n")
+        @header_sent = true
+      end
     end
 
     def send_body
-      @body.rewind
-      # connection: close is also added to ensure that the client does not pipeline.
-      @socket.write(@body.read)
-      @body_sent = true
+      if not @body_sent
+        @body.rewind
+        # connection: close is also added to ensure that the client does not pipeline.
+        @socket.write(@body.read)
+        @body_sent = true
+      end
     end
 
     # This takes whatever has been done to header and body and then writes it in the
@@ -306,7 +315,7 @@ module Mongrel
     end
 
     def done
-      @status_sent && @header_sent && @body_sent
+      (@status_sent and @header_sent and @body_sent)
     end
   end
   
@@ -332,6 +341,7 @@ module Mongrel
   class HttpServer
     attr_reader :acceptor
     attr_reader :workers
+    attr_reader :classifier
 
     # Creates a working server on host:port (strange things happen if port isn't a Number).
     # Use HttpServer::run to start the server and HttpServer.acceptor.join to
@@ -387,6 +397,10 @@ module Mongrel
                 break if response.done
               end
 
+              if not response.done
+                response.finished
+              end
+
             else
               client.write(Const::ERROR_404_RESPONSE)
             end
@@ -482,11 +496,14 @@ module Mongrel
     def register(uri, handler)
       script_name, path_info, handlers = @classifier.resolve(uri)
 
-      if not handlers or (path_info and path_info != "/" and path_info.length == 0)
-        # new uri that is just longer
+      if not handlers
         @classifier.register(uri, [handler])
       else
-        handlers << handler
+        if path_info.length == 0 or (script_name == "/" and path_info == "/")
+          handlers << handler
+        else
+          @classifier.register(uri, [handler])
+        end
       end
     end
 
@@ -745,9 +762,9 @@ module Mongrel
       MongrelDbg.begin_trace :rails
       MongrelDbg.begin_trace :files
       
-      uri "/", :handler => plugin("/handlers/requestlog::files")
-      uri "/", :handler => plugin("/handlers/requestlog::objects")
-      uri "/", :handler => plugin("/handlers/requestlog::params")
+      uri location, :handler => plugin("/handlers/requestlog::files")
+      uri location, :handler => plugin("/handlers/requestlog::objects")
+      uri location, :handler => plugin("/handlers/requestlog::params")
     end
 
 
diff --git a/projects/mongrel_config/lib/mongrel_config/app.rb b/projects/mongrel_config/lib/mongrel_config/app.rb
index 5517d22..f723456 100644
--- a/projects/mongrel_config/lib/mongrel_config/app.rb
+++ b/projects/mongrel_config/lib/mongrel_config/app.rb
@@ -89,7 +89,6 @@ module Configure::Views
         p { span { "Port:" }; input :name => "port", :value => "4000" }
         p { span { "Environment:" }; input :name => "env", :value => "development" }
         p { span { "Address:" }; input :name => "address", :value => "0.0.0.0" }
-        p { span { "Number Processors:" }; input :name => "num_procs", :value => "20" }
         input :type => "submit", :value => "START"
       end
     end
diff --git a/test/test_configurator.rb b/test/test_configurator.rb
index 2fb9f85..fdc7511 100644
--- a/test/test_configurator.rb
+++ b/test/test_configurator.rb
@@ -21,7 +21,7 @@ class Sentinel < GemPlugin::Plugin "/handlers"
 end
 
 
-class MongrelDbgTest < Test::Unit::TestCase
+class ConfiguratorTest < Test::Unit::TestCase
 
   def test_base_handler_config
     config = Mongrel::Configurator.new :host => "localhost" do
@@ -30,24 +30,32 @@ class MongrelDbgTest < Test::Unit::TestCase
         uri "/", :handler => plugin("/handlers/testplugin")
         uri "/", :handler => plugin("/handlers/testplugin")
         uri "/", :handler => Mongrel::DirHandler.new(".", load_mime_map("examples/mime.yaml"))
-        uri "/", :handler => plugin("/handlers/sentinel")
+        uri "/", :handler => plugin("/handlers/testplugin")
 
         uri "/test", :handler => plugin("/handlers/testplugin")
         uri "/test", :handler => plugin("/handlers/testplugin")
         uri "/test", :handler => Mongrel::DirHandler.new(".", load_mime_map("examples/mime.yaml"))
-        uri "/test", :handler => plugin("/handlers/sentinel")
+        uri "/test", :handler => plugin("/handlers/testplugin")
         run
       end
     end
 
+
+    config.listeners.each do |host,listener|
+      puts "Registered URIs: #{listener.classifier.uris.inspect}"
+      assert listener.classifier.uris.length == 2, "Wrong number of registered URIs"
+      assert listener.classifier.uris.include?("/"),  "/ not registered"
+      assert listener.classifier.uris.include?("/test"), "/test not registered"
+    end
+
     res = Net::HTTP.get(URI.parse('http://localhost:3111/test'))
     assert res != nil, "Didn't get a response"
-    assert $test_plugin_fired == 2, "Test filter plugin didn't run twice."
+    assert $test_plugin_fired == 3, "Test filter plugin didn't run 3 times."
 
 
     res = Net::HTTP.get(URI.parse('http://localhost:3111/'))
     assert res != nil, "Didn't get a response"
-    assert $test_plugin_fired == 4, "Test filter plugin didn't run 4 times."
+    assert $test_plugin_fired == 6, "Test filter plugin didn't run 6 times."
 
     config.stop
     
diff --git a/test/test_response.rb b/test/test_response.rb
index e905e01..36a29fb 100644
--- a/test/test_response.rb
+++ b/test/test_response.rb
@@ -26,6 +26,8 @@ class ResponseTest < Test::Unit::TestCase
       out.write("tested")
       out.write("hello!")
     end
+
+    resp.finished
     assert io.length > 0, "output didn't have data"
   end
 
@@ -38,6 +40,7 @@ class ResponseTest < Test::Unit::TestCase
       out.write("NOT FOUND")
     end
 
+    resp.finished
     assert io.length > 0, "output didn't have data"
   end