aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/dispatcher.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2005-11-02 01:20:36 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2005-11-02 01:20:36 +0000
commit1cfd25a7743b2a6f1e2e67a77c9ee3d949b9edb7 (patch)
treeb11d15e0433c901fe5d36e26d03a44394180767e /railties/lib/dispatcher.rb
parentb4b47e560eb8627190fc6bcf3b54fd2faa62c5e2 (diff)
downloadrails-1cfd25a7743b2a6f1e2e67a77c9ee3d949b9edb7.tar.gz
rails-1cfd25a7743b2a6f1e2e67a77c9ee3d949b9edb7.tar.bz2
rails-1cfd25a7743b2a6f1e2e67a77c9ee3d949b9edb7.zip
Failsafe response handler for dispatcher.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2841 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/lib/dispatcher.rb')
-rw-r--r--railties/lib/dispatcher.rb36
1 files changed, 29 insertions, 7 deletions
diff --git a/railties/lib/dispatcher.rb b/railties/lib/dispatcher.rb
index 73bedf5ecf..a2fc6e8553 100644
--- a/railties/lib/dispatcher.rb
+++ b/railties/lib/dispatcher.rb
@@ -29,15 +29,20 @@ class Dispatcher
# Dispatch the given CGI request, using the given session options, and
# emitting the output via the given output. If you dispatch with your
- # own CGI object, be sure to handle the exceptions it raises.
+ # own CGI object be sure to handle the exceptions it raises on multipart
+ # requests (EOFError and ArgumentError).
def dispatch(cgi = nil, session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout)
- cgi ||= CGI.new
- request, response = ActionController::CgiRequest.new(cgi, session_options), ActionController::CgiResponse.new(cgi)
- prepare_application
- ActionController::Routing::Routes.recognize!(request).process(request, response).out(output)
+ if cgi ||= new_cgi(output)
+ request, response = ActionController::CgiRequest.new(cgi, session_options), ActionController::CgiResponse.new(cgi)
+ prepare_application
+ ActionController::Routing::Routes.recognize!(request).process(request, response).out(output)
+ end
rescue Object => exception
- ActionController::Base.process_with_exception(request, response, exception).out(output)
+ failsafe_response(output, '500 Internal Server Error') do
+ ActionController::Base.process_with_exception(request, response, exception).out(output)
+ end
ensure
+ # Do not give a failsafe response here.
reset_after_dispatch
end
@@ -51,8 +56,15 @@ class Dispatcher
Dependencies.remove_subclasses_for(ActiveRecord::Base, ActiveRecord::Observer, ActionController::Base)
Dependencies.remove_subclasses_for(ActionMailer::Base) if defined?(ActionMailer::Base)
end
-
+
private
+ # CGI.new plus exception handling. CGI#read_multipart raises EOFError
+ # if body.empty? or body.size != Content-Length and raises ArgumentError
+ # if Content-Length is non-integer.
+ def new_cgi(output)
+ failsafe_response(output, '400 Bad Request') { CGI.new }
+ end
+
def prepare_application
ActionController::Routing::Routes.reload if Dependencies.load?
prepare_breakpoint
@@ -72,5 +84,15 @@ class Dispatcher
rescue
nil
end
+
+ # If the block raises, send status code as a last-ditch response.
+ def failsafe_response(output, status)
+ yield
+ rescue Object
+ begin
+ output.write "Status: #{status}\r\n"
+ rescue Object
+ end
+ end
end
end