aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/middleware
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware')
-rw-r--r--actionpack/lib/action_dispatch/middleware/closed_error.rb7
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb10
-rw-r--r--actionpack/lib/action_dispatch/middleware/debug_exceptions.rb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/flash.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/public_exceptions.rb30
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb65
7 files changed, 65 insertions, 60 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/closed_error.rb b/actionpack/lib/action_dispatch/middleware/closed_error.rb
deleted file mode 100644
index 0a4db47f4b..0000000000
--- a/actionpack/lib/action_dispatch/middleware/closed_error.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module ActionDispatch
- class ClosedError < StandardError #:nodoc:
- def initialize(kind)
- super "Cannot modify #{kind} because it was closed. This means it was already streamed back to the client or converted to HTTP headers."
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 51cec41a34..39ff58a447 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -121,10 +121,6 @@ module ActionDispatch
@cookies = {}
end
- attr_reader :closed
- alias :closed? :closed
- def close!; @closed = true end
-
def each(&block)
@cookies.each(&block)
end
@@ -165,7 +161,6 @@ module ActionDispatch
# Sets the cookie named +name+. The second argument may be the very cookie
# value, or a hash of options as documented above.
def []=(key, options)
- raise ClosedError, :cookies if closed?
if options.is_a?(Hash)
options.symbolize_keys!
value = options[:value]
@@ -259,7 +254,6 @@ module ActionDispatch
end
def []=(key, options)
- raise ClosedError, :cookies if closed?
if options.is_a?(Hash)
options.symbolize_keys!
else
@@ -298,7 +292,6 @@ module ActionDispatch
end
def []=(key, options)
- raise ClosedError, :cookies if closed?
if options.is_a?(Hash)
options.symbolize_keys!
options[:value] = @verifier.generate(options[:value])
@@ -352,9 +345,6 @@ module ActionDispatch
end
[status, headers, body]
- ensure
- cookie_jar = ActionDispatch::Request.new(env).cookie_jar unless cookie_jar
- cookie_jar.close!
end
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
index cd4af82c6e..dabbabb1e6 100644
--- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
@@ -15,8 +15,9 @@ module ActionDispatch
begin
response = @app.call(env)
- # TODO: Maybe this should be in the router itself
if response[1]['X-Cascade'] == 'pass'
+ body = response[2]
+ body.close if body.respond_to?(:close)
raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
end
rescue Exception => exception
diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb
index e59404ef68..bc5b163931 100644
--- a/actionpack/lib/action_dispatch/middleware/flash.rb
+++ b/actionpack/lib/action_dispatch/middleware/flash.rb
@@ -93,7 +93,6 @@ module ActionDispatch
end
def []=(k, v) #:nodoc:
- raise ClosedError, :flash if closed?
keep(k)
@flashes[k] = v
end
@@ -159,10 +158,6 @@ module ActionDispatch
@now ||= FlashNow.new(self)
end
- attr_reader :closed
- alias :closed? :closed
- def close!; @closed = true; end
-
# Keeps either the entire current flash or a specific flash entry available for the next action:
#
# flash.keep # keeps the entire flash
@@ -258,7 +253,6 @@ module ActionDispatch
end
env[KEY] = new_hash
- new_hash.close!
end
if session.key?('flash') && session['flash'].empty?
diff --git a/actionpack/lib/action_dispatch/middleware/public_exceptions.rb b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
new file mode 100644
index 0000000000..85b8d178bf
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
@@ -0,0 +1,30 @@
+module ActionDispatch
+ # A simple Rack application that renders exceptions in the given public path.
+ class PublicExceptions
+ attr_accessor :public_path
+
+ def initialize(public_path)
+ @public_path = public_path
+ end
+
+ def call(env)
+ status = env["PATH_INFO"][1..-1]
+ locale_path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale
+ path = "#{public_path}/#{status}.html"
+
+ if locale_path && File.exist?(locale_path)
+ render(status, File.read(locale_path))
+ elsif File.exist?(path)
+ render(status, File.read(path))
+ else
+ [404, { "X-Cascade" => "pass" }, []]
+ end
+ end
+
+ private
+
+ def render(status, body)
+ [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index 6bcf099d2c..f75b4d4d04 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -74,10 +74,6 @@ module ActionDispatch
class AbstractStore < Rack::Session::Abstract::ID
include Compatibility
include StaleSessionCheck
-
- def destroy_session(env, sid, options)
- raise '#destroy_session needs to be implemented.'
- end
end
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
index 0c95248611..5eceeece1f 100644
--- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -4,10 +4,18 @@ require 'active_support/deprecation'
module ActionDispatch
# This middleware rescues any exception returned by the application
- # and wraps them in a format for the end user.
+ # and calls an exceptions app that will wrap it in a format for the end user.
+ #
+ # The exceptions app should be passed as parameter on initialization
+ # of ShowExceptions. Everytime there is an exception, ShowExceptions will
+ # store the exception in env["action_dispatch.exception"], rewrite the
+ # PATH_INFO to the exception status code and call the rack app.
+ #
+ # If the application returns a "X-Cascade" pass response, this middleware
+ # will send an empty response as result with the correct status code.
+ # If any exception happens inside the exceptions app, this middleware
+ # catches the exceptions and returns a FAILSAFE_RESPONSE.
class ShowExceptions
- RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
-
FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'},
["<html><body><h1>500 Internal Server Error</h1>" <<
"If you are the administrator of this website, then please read this web " <<
@@ -28,9 +36,19 @@ module ActionDispatch
end
end
- def initialize(app, consider_all_requests_local = nil)
- ActiveSupport::Deprecation.warn "Passing consider_all_requests_local option to ActionDispatch::ShowExceptions middleware no longer works" unless consider_all_requests_local.nil?
+ def initialize(app, exceptions_app = nil)
+ if [true, false].include?(exceptions_app)
+ ActiveSupport::Deprecation.warn "Passing consider_all_requests_local option to ActionDispatch::ShowExceptions middleware no longer works"
+ exceptions_app = nil
+ end
+
+ if exceptions_app.nil?
+ raise ArgumentError, "You need to pass an exceptions_app when initializing ActionDispatch::ShowExceptions. " \
+ "In case you want to render pages from a public path, you can use ActionDispatch::PublicExceptions.new('path/to/public')"
+ end
+
@app = app
+ @exceptions_app = exceptions_app
end
def call(env)
@@ -40,7 +58,7 @@ module ActionDispatch
raise exception if env['action_dispatch.show_exceptions'] == false
end
- response || render_exception_with_failsafe(env, exception)
+ response || render_exception(env, exception)
end
private
@@ -50,37 +68,20 @@ module ActionDispatch
def status_code(*)
end
- def render_exception_with_failsafe(env, exception)
- render_exception(env, exception)
+ def render_exception(env, exception)
+ wrapper = ExceptionWrapper.new(env, exception)
+ status = wrapper.status_code
+ env["action_dispatch.exception"] = wrapper.exception
+ env["PATH_INFO"] = "/#{status}"
+ response = @exceptions_app.call(env)
+ response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response
rescue Exception => failsafe_error
$stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"
FAILSAFE_RESPONSE
end
- def render_exception(env, exception)
- wrapper = ExceptionWrapper.new(env, exception)
-
- status = wrapper.status_code
- locale_path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale
- path = "#{public_path}/#{status}.html"
-
- if locale_path && File.exist?(locale_path)
- render(status, File.read(locale_path))
- elsif File.exist?(path)
- render(status, File.read(path))
- else
- render(status, '')
- end
- end
-
- def render(status, body)
- [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
- end
-
- # TODO: Make this a middleware initialization parameter once
- # we removed the second option (which is deprecated)
- def public_path
- defined?(Rails.public_path) ? Rails.public_path : 'public_path'
+ def pass_response(status)
+ [status, {"Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0"}, []]
end
end
end