about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--Rakefile2
-rw-r--r--doc/site/src/news.page2
-rw-r--r--ext/http11/http11.c2
-rw-r--r--lib/mongrel.rb23
4 files changed, 18 insertions, 11 deletions
diff --git a/Rakefile b/Rakefile
index a0eafea..e814a70 100644
--- a/Rakefile
+++ b/Rakefile
@@ -53,7 +53,7 @@ task :site => [:site_webgen, :site_rdoc, :site_coverage, :site_projects_rdoc]
 setup_extension("http11", "http11")
 
 name="mongrel"
-version="0.3.13.1"
+version="0.3.13.2"
 
 setup_gem(name, version) do |spec|
   spec.summary = "A small fast HTTP library and server that runs Rails, Camping, and Nitro apps."
diff --git a/doc/site/src/news.page b/doc/site/src/news.page
index f9ca15d..8feb00a 100644
--- a/doc/site/src/news.page
+++ b/doc/site/src/news.page
@@ -7,7 +7,7 @@ ordering: 2
 
 h1. Latest News
 
-h2. Jun 20: Mongrel 0.3.13.1 -- Small Fixes
+h2. Jun 20: Mongrel 0.3.13.2 -- Small Fixes
 
 This is a small release that fixes a little bug, some of the documentation,
 and adds the new RedirectHandler code and a @redirect@ call for the mongrel.conf
diff --git a/ext/http11/http11.c b/ext/http11/http11.c
index 88e8e98..3d43b82 100644
--- a/ext/http11/http11.c
+++ b/ext/http11/http11.c
@@ -554,7 +554,7 @@ void Init_http11()
   DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
   DEF_GLOBAL(server_protocol_value, "HTTP/1.1");
   DEF_GLOBAL(http_host, "HTTP_HOST");
-  DEF_GLOBAL(mongrel_version, "Mongrel 0.3.13.1");
+  DEF_GLOBAL(mongrel_version, "Mongrel 0.3.13.2");
   DEF_GLOBAL(server_software, "SERVER_SOFTWARE");
   DEF_GLOBAL(port_80, "80");
 
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 4921c25..d1d669f 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -28,8 +28,7 @@ require 'mongrel/tcphack'
 require 'yaml'
 require 'time'
 require 'rubygems'
-require 'etc'
-
+require 'etc'
 
 begin
   require 'sendfile'
@@ -62,8 +61,10 @@ module Mongrel
 
 
   # Used to stop the HttpServer via Thread.raise.
-  class StopServer < Exception
-  end
+  class StopServer < Exception; end
+
+  # Thrown at a thread when it is timed out.
+  class TimeoutError < Exception; end
 
 
   # Every standard HTTP code mapped to the appropriate message.  These are
@@ -131,7 +132,7 @@ module Mongrel
     # The original URI requested by the client.  Passed to URIClassifier to build PATH_INFO and SCRIPT_NAME.
     REQUEST_URI='REQUEST_URI'.freeze
 
-    MONGREL_VERSION="0.3.13.1".freeze
+    MONGREL_VERSION="0.3.13.2".freeze
 
     # TODO: this use of a base for tempfiles needs to be looked at for security problems
     MONGREL_TMP_BASE="mongrel".freeze
@@ -580,6 +581,8 @@ module Mongrel
         # ignored
       rescue HttpParserError
         STDERR.puts "#{Time.now}: BAD CLIENT (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #$!"
+      rescue Errno::EMFILE
+        reap_dead_workers('too many files')
       rescue Object
         STDERR.puts "#{Time.now}: ERROR: #$!"
       ensure
@@ -601,7 +604,7 @@ module Mongrel
 
           if mark - w[:started_on] > @death_time + @timeout
             STDERR.puts "Thread #{w.inspect} is too old, killing."
-            w.raise(StopServer.new("Timed out thread."))
+            w.raise(TimeoutError.new("Timed out thread."))
           end
         end
       end
@@ -751,8 +754,6 @@ module Mongrel
       @needs_restart = false
       @pid_file = defaults[:pid_file]
 
-      change_privilege(@defaults[:user], @defaults[:group])
-      
       if blk
         cloaker(&blk).bind(self).call
       end
@@ -817,6 +818,8 @@ module Mongrel
     # * :port => Port to bind.
     # * :num_processors => The maximum number of concurrent threads allowed.  (950 default)
     # * :timeout => 1/100th of a second timeout between requests. (10 is 1/10th, 0 is timeout)
+    # * :user => User to change to, must have :group as well.
+    # * :group => Group to change to, must have :user as well.
     #
     def listener(options={},&blk)
       raise "Cannot call listener inside another listener block." if (@listener or @listener_name)
@@ -828,6 +831,10 @@ module Mongrel
       @listener_name = "#{ops[:host]}:#{ops[:port]}"
       @listeners[@listener_name] = @listener
 
+      if ops[:user] and ops[:group]
+        change_privilege(ops[:user], ops[:group])
+      end
+
       # Does the actual cloaking operation to give the new implicit self.
       if blk
         cloaker(&blk).bind(self).call