diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2005-06-22 12:59:36 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2005-06-22 12:59:36 +0000 |
commit | 4e0ffab8b05f5cc35996ac4866ee61cefb432af6 (patch) | |
tree | 897aea07971f463340d944efadefe9d4dc678bfe /railties/lib | |
parent | ce44079818c9307ed20a2f11b2bf7933803f78f7 (diff) | |
download | rails-4e0ffab8b05f5cc35996ac4866ee61cefb432af6.tar.gz rails-4e0ffab8b05f5cc35996ac4866ee61cefb432af6.tar.bz2 rails-4e0ffab8b05f5cc35996ac4866ee61cefb432af6.zip |
Removed the mutex from the WEBrick adapter under the production environment so concurrent requests can be served
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1482 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/lib')
-rw-r--r-- | railties/lib/dispatcher.rb | 6 | ||||
-rw-r--r-- | railties/lib/webrick_server.rb | 96 |
2 files changed, 68 insertions, 34 deletions
diff --git a/railties/lib/dispatcher.rb b/railties/lib/dispatcher.rb index 140d8e84a3..b2f9650e65 100644 --- a/railties/lib/dispatcher.rb +++ b/railties/lib/dispatcher.rb @@ -25,13 +25,13 @@ require 'breakpoint' class Dispatcher class << self - def dispatch(cgi = CGI.new, session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS) + def dispatch(cgi = CGI.new, session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) begin request, response = ActionController::CgiRequest.new(cgi, session_options), ActionController::CgiResponse.new(cgi) prepare_application - ActionController::Routing::Routes.recognize!(request).process(request, response).out + ActionController::Routing::Routes.recognize!(request).process(request, response).out(output) rescue Object => exception - ActionController::Base.process_with_exception(request, response, exception).out + ActionController::Base.process_with_exception(request, response, exception).out(output) ensure reset_application end diff --git a/railties/lib/webrick_server.rb b/railties/lib/webrick_server.rb index bd8c287c9b..46451e2e52 100644 --- a/railties/lib/webrick_server.rb +++ b/railties/lib/webrick_server.rb @@ -8,6 +8,24 @@ include WEBrick ABSOLUTE_RAILS_ROOT = File.expand_path(RAILS_ROOT) +class CGI + def stdinput + @stdin || $stdin + end + + def stdinput=(input) + @stdin = input + end + + def env_table + @env_table || ENV + end + + def env_table=(table) + @env_table = table + end +end + class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet REQUEST_MUTEX = Mutex.new @@ -18,6 +36,10 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet server.mount('/', DispatchServlet, options) trap("INT") { server.shutdown } + + require File.join(@server_options[:server_root], "..", "config", "environment") unless defined?(RAILS_ROOT) + require "dispatcher" + server.start end @@ -31,20 +53,21 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet def service(req, res) begin unless handle_file(req, res) - REQUEST_MUTEX.lock + REQUEST_MUTEX.lock unless RAILS_ENV == 'production' unless handle_dispatch(req, res) raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." end end ensure - REQUEST_MUTEX.unlock if REQUEST_MUTEX.locked? + unless RAILS_ENV == 'production' + REQUEST_MUTEX.unlock if REQUEST_MUTEX.locked? + end end end def handle_file(req, res) begin req = req.dup - path = req.path.dup # Add .html if the last path piece has no . in it @@ -63,35 +86,13 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet end end - def handle_dispatch(req, res, origin = nil) - env = req.meta_vars.clone - env.delete "SCRIPT_NAME" - env["QUERY_STRING"] = req.request_uri.query - env["REQUEST_URI"] = origin if origin - - data = nil - $old_stdin, $old_stdout = $stdin, $stdout - $stdin, $stdout = StringIO.new(req.body || ""), StringIO.new - - begin - require 'cgi' - CGI.send(:define_method, :env_table) { env } - - load File.join(@server_options[:server_root], "dispatch.rb") - - $stdout.rewind - data = $stdout.read - ensure - $stdin, $stdout = $old_stdin, $old_stdout - end + def handle_dispatch(req, res, origin = nil) + data = StringIO.new + Dispatcher.dispatch(create_cgi(req, origin), ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, data) - raw_header, body = *data.split(/^[\xd\xa]+/on, 2) - header = WEBrick::HTTPUtils::parse_header(raw_header) - if /^(\d+)/ =~ header['status'][0] - res.status = $1.to_i - header.delete('status') - end - res.cookies.concat header.delete('set-cookie') + header, body = extract_header_and_body(data) + assign_status(res, header) + res.cookies.concat(header.delete('set-cookie')) header.each { |key, val| res[key] = val.join(", ") } res.body = body @@ -100,4 +101,37 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet p err, err.backtrace return false end + + private + def create_cgi(req, origin) + cgi = CGI.new + cgi.env_table = create_env_table(req, origin) + cgi.stdinput = req.body || "" + return cgi + end + + def create_env_table(req, origin) + env = req.meta_vars.clone + env.delete "SCRIPT_NAME" + env["QUERY_STRING"] = req.request_uri.query + env["REQUEST_URI"] = origin if origin + return env + end + + def extract_header_and_body(data) + data.rewind + data = data.read + + raw_header, body = *data.split(/^[\xd\xa]+/on, 2) + header = WEBrick::HTTPUtils::parse_header(raw_header) + + return header, body + end + + def assign_status(res, header) + if /^(\d+)/ =~ header['status'][0] + res.status = $1.to_i + header.delete('status') + end + end end |