aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-06-22 12:59:36 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-06-22 12:59:36 +0000
commit4e0ffab8b05f5cc35996ac4866ee61cefb432af6 (patch)
tree897aea07971f463340d944efadefe9d4dc678bfe /railties/lib
parentce44079818c9307ed20a2f11b2bf7933803f78f7 (diff)
downloadrails-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.rb6
-rw-r--r--railties/lib/webrick_server.rb96
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