From fbf042877dd1690b0202d38cba29c6e7f9f0a0d6 Mon Sep 17 00:00:00 2001 From: zedshaw Date: Mon, 5 Jun 2006 08:54:06 +0000 Subject: [PATCH] Late night hackery. Moving code for checking users and groups to common place, letting people who set allow_concurrency shoot themselves in the foot. git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@225 19e92222-5c0b-0410-8929-a290d50e31e9 --- bin/mongrel_rails | 27 +++----------- doc/site/src/docs/apache.page | 2 +- lib/mongrel/command.rb | 66 +++++++++++++++++++++++------------ lib/mongrel/rails.rb | 9 ++--- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/bin/mongrel_rails b/bin/mongrel_rails index 4886e6eb..38ec96c2 100644 --- a/bin/mongrel_rails +++ b/bin/mongrel_rails @@ -56,31 +56,14 @@ class Start < GemPlugin::Plugin "/commands" valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate valid_user? @user if @user valid_group? @group if @group - + + if ActionController::Base.allow_concurrency + STDERR.puts "[RAILS] allow_concurrency is true. Wow, you're very brave." + end + return @valid end - def valid_user?(user) - valid?(Process.uid == 0, "You must be root to change the user.") - valid?(@group, "You must also specify a group.") - begin - Etc.getpwnam(user) - rescue - failure "User does not exist: #{user}" - @valid = false - end - end - - def valid_group?(group) - valid?(Process.uid == 0, "You must be root to change the group.") - valid?(@user, "You must also specify a user.") - begin - Etc.getgrnam(group) - rescue - failure "Group does not exist: #{group}" - @valid = false - end - end def run diff --git a/doc/site/src/docs/apache.page b/doc/site/src/docs/apache.page index 89466e8b..f397a459 100644 --- a/doc/site/src/docs/apache.page +++ b/doc/site/src/docs/apache.page @@ -6,4 +6,4 @@ directoryName: Apache h1. Apache Best Practice Deployment -Coming soon... + diff --git a/lib/mongrel/command.rb b/lib/mongrel/command.rb index 3e596164..ba9c2f62 100644 --- a/lib/mongrel/command.rb +++ b/lib/mongrel/command.rb @@ -29,12 +29,12 @@ module Mongrel module Command BANNER = "Usage: mongrel_rails [options]" - + # A Command pattern implementation used to create the set of command available to the user # from Mongrel. The script uses objects which implement this interface to do the # user's bidding. module Base - + attr_reader :valid, :done_validating, :original_args # Called by the implemented command to set the options for that command. @@ -68,7 +68,7 @@ module Mongrel @done_validating = true puts @opt end - + # I need to add my own -v definition to prevent the -v from exiting by default as well. @opt.on_tail("--version", "Show version") do @done_validating = true @@ -76,7 +76,7 @@ module Mongrel puts "Version #{Mongrel::Const::MONGREL_VERSION}" end end - + @opt.parse! argv end @@ -88,19 +88,19 @@ module Mongrel def validate return @valid end - + # Returns a help message. Defaults to OptionParser#help which should be good. def help @opt.help end - + # Runs the command doing it's job. You should implement this otherwise it will # throw a NotImplementedError as a reminder. def run raise NotImplementedError end - - + + # Validates the given expression is true and prints the message if not, exiting. def valid?(exp, message) if not @done_validating and (not exp) @@ -114,29 +114,51 @@ module Mongrel def valid_exists?(file, message) valid?(file != nil && File.exist?(file), message) end - - + + # Validates that the file is a file and not a directory or something else. def valid_file?(file, message) valid?(file != nil && File.file?(file), message) end - + # Validates that the given directory exists def valid_dir?(file, message) valid?(file != nil && File.directory?(file), message) end + def valid_user?(user) + valid?(Process.uid == 0, "You must be root to change the user.") + valid?(@group, "You must also specify a group.") + begin + Etc.getpwnam(user) + rescue + failure "User does not exist: #{user}" + @valid = false + end + end + + def valid_group?(group) + valid?(Process.uid == 0, "You must be root to change the group.") + valid?(@user, "You must also specify a user.") + begin + Etc.getgrnam(group) + rescue + failure "Group does not exist: #{group}" + @valid = false + end + end + # Just a simple method to display failure until something better is developed. def failure(message) STDERR.puts "!!! #{message}" end end - + # A Singleton class that manages all of the available commands # and handles running them. class Registry include Singleton - + # Builds a list of possible commands from the Command derivates list def commands pmgr = GemPlugin::Manager.instance @@ -147,27 +169,27 @@ module Mongrel # Prints a list of available commands. def print_command_list puts "#{Mongrel::Command::BANNER}\nAvailable commands are:\n\n" - + self.commands.each do |name| puts " - #{name[1 .. -1]}\n" end - + puts "\nEach command takes -h as an option to get help." - + end - - + + # Runs the args against the first argument as the command name. # If it has any errors it returns a false, otherwise it return true. def run(args) # find the command cmd_name = args.shift - + if !cmd_name or cmd_name == "?" or cmd_name == "help" print_command_list return true end - + # command exists, set it up and validate it begin command = GemPlugin::Manager.instance.create("/commands/#{cmd_name}", :argv => args) @@ -176,7 +198,7 @@ module Mongrel print_command_list return end - + # Normally the command is NOT valid right after being created # but sometimes (like with -h or -v) there's no further processing # needed so the command is already valid so we can skip it. @@ -190,7 +212,7 @@ module Mongrel end return true end - + end end end diff --git a/lib/mongrel/rails.rb b/lib/mongrel/rails.rb index 8ebd76d4..f108236a 100644 --- a/lib/mongrel/rails.rb +++ b/lib/mongrel/rails.rb @@ -77,10 +77,9 @@ module Mongrel cgi = Mongrel::CGIWrapper.new(request, response) cgi.handler = self - @guard.synchronize do - # Rails is not thread safe so must be run entirely within synchronize - Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body) - end + @guard.lock unless ActionController::Base.allow_concurrency + # Rails is not thread safe so must be run entirely within synchronize + Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body) # This finalizes the output using the proper HttpResponse way cgi.out {""} @@ -89,6 +88,8 @@ module Mongrel rescue Object => rails_error STDERR.puts "Error calling Dispatcher.dispatch #{rails_error.inspect}" STDERR.puts rails_error.backtrace.join("\n") + ensure + @guard.unlock end end end