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/actionable_exceptions.rb39
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/debug_exceptions.rb10
-rw-r--r--actionpack/lib/action_dispatch/middleware/debug_view.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/exception_wrapper.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/public_exceptions.rb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb7
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb27
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb13
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb0
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb4
14 files changed, 114 insertions, 12 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/actionable_exceptions.rb b/actionpack/lib/action_dispatch/middleware/actionable_exceptions.rb
new file mode 100644
index 0000000000..e94cc46603
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/actionable_exceptions.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require "erb"
+require "action_dispatch/http/request"
+require "active_support/actionable_error"
+
+module ActionDispatch
+ class ActionableExceptions # :nodoc:
+ cattr_accessor :endpoint, default: "/rails/actions"
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ request = ActionDispatch::Request.new(env)
+ return @app.call(env) unless actionable_request?(request)
+
+ ActiveSupport::ActionableError.dispatch(request.params[:error].to_s.safe_constantize, request.params[:action])
+
+ redirect_to request.params[:location]
+ end
+
+ private
+ def actionable_request?(request)
+ request.show_exceptions? && request.post? && request.path == endpoint
+ end
+
+ def redirect_to(location)
+ body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(location)}\">redirected</a>.</body></html>"
+
+ [302, {
+ "Content-Type" => "text/html; charset=#{Response.default_charset}",
+ "Content-Length" => body.bytesize.to_s,
+ "Location" => location,
+ }, [body]]
+ end
+ end
+end
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 1611a8b3dd..b69bcab05c 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -338,7 +338,7 @@ module ActionDispatch
def update_cookies_from_jar
request_jar = @request.cookie_jar.instance_variable_get(:@cookies)
- set_cookies = request_jar.reject { |k, _| @delete_cookies.key?(k) }
+ set_cookies = request_jar.reject { |k, _| @delete_cookies.key?(k) || @set_cookies.key?(k) }
@cookies.update set_cookies if set_cookies
end
diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
index 61773d97a2..0b15c94122 100644
--- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
@@ -4,6 +4,8 @@ require "action_dispatch/http/request"
require "action_dispatch/middleware/exception_wrapper"
require "action_dispatch/routing/inspector"
+require "active_support/actionable_error"
+
require "action_view"
require "action_view/base"
@@ -60,7 +62,11 @@ module ActionDispatch
log_error(request, wrapper)
if request.get_header("action_dispatch.show_detailed_exceptions")
- content_type = request.formats.first
+ begin
+ content_type = request.formats.first
+ rescue Mime::Type::InvalidMimeType
+ render_for_api_request(Mime[:text], wrapper)
+ end
if api_request?(content_type)
render_for_api_request(content_type, wrapper)
@@ -142,7 +148,7 @@ module ActionDispatch
message = []
message << " "
message << "#{exception.class} (#{exception.message}):"
- message.concat(exception.annoted_source_code) if exception.respond_to?(:annoted_source_code)
+ message.concat(exception.annotated_source_code) if exception.respond_to?(:annotated_source_code)
message << " "
message.concat(trace)
diff --git a/actionpack/lib/action_dispatch/middleware/debug_view.rb b/actionpack/lib/action_dispatch/middleware/debug_view.rb
index 43c0a84504..a03650254e 100644
--- a/actionpack/lib/action_dispatch/middleware/debug_view.rb
+++ b/actionpack/lib/action_dispatch/middleware/debug_view.rb
@@ -52,5 +52,9 @@ module ActionDispatch
super
end
end
+
+ def protect_against_forgery?
+ false
+ end
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
index 1fb3e9db00..0cc56f5013 100644
--- a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
+++ b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
@@ -12,6 +12,7 @@ module ActionDispatch
"ActionController::UnknownHttpMethod" => :method_not_allowed,
"ActionController::NotImplemented" => :not_implemented,
"ActionController::UnknownFormat" => :not_acceptable,
+ "Mime::Type::InvalidMimeType" => :not_acceptable,
"ActionController::MissingExactTemplate" => :not_acceptable,
"ActionController::InvalidAuthenticityToken" => :unprocessable_entity,
"ActionController::InvalidCrossOriginRequest" => :unprocessable_entity,
diff --git a/actionpack/lib/action_dispatch/middleware/public_exceptions.rb b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
index 3feb3a19f3..a88ad40f21 100644
--- a/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
@@ -21,8 +21,12 @@ module ActionDispatch
def call(env)
request = ActionDispatch::Request.new(env)
status = request.path_info[1..-1].to_i
- content_type = request.formats.first
- body = { status: status, error: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500]) }
+ begin
+ content_type = request.formats.first
+ rescue Mime::Type::InvalidMimeType
+ content_type = Mime[:text]
+ end
+ body = { status: status, error: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500]) }
render(status, content_type, body)
end
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 02ccfbc81a..7c43c781c7 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -24,9 +24,10 @@ module ActionDispatch
#
# Rails.application.config.session_store :cookie_store, key: '_your_app_session'
#
- # By default, your secret key base is derived from your application name in
- # the test and development environments. In all other environments, it is stored
- # encrypted in the <tt>config/credentials.yml.enc</tt> file.
+ # In the development and test environments your application's secret key base is
+ # generated by Rails and stored in a temporary file in <tt>tmp/development_secret.txt</tt>.
+ # In all other environments, it is stored encrypted in the
+ # <tt>config/credentials.yml.enc</tt> file.
#
# If your application was not updated to Rails 5.2 defaults, the secret_key_base
# will be found in the old <tt>config/secrets.yml</tt> file.
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index b82f8aa3a3..f0c869fba0 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -34,7 +34,28 @@ module ActionDispatch
end
def build(app)
- klass.new(app, *args, &block)
+ InstrumentationProxy.new(klass.new(app, *args, &block), inspect)
+ end
+ end
+
+ # This class is used to instrument the execution of a single middleware.
+ # It proxies the `call` method transparently and instruments the method
+ # call.
+ class InstrumentationProxy
+ EVENT_NAME = "process_middleware.action_dispatch"
+
+ def initialize(middleware, class_name)
+ @middleware = middleware
+
+ @payload = {
+ middleware: class_name,
+ }
+ end
+
+ def call(env)
+ ActiveSupport::Notifications.instrument(EVENT_NAME, @payload) do
+ @middleware.call(env)
+ end
end
end
@@ -97,8 +118,8 @@ module ActionDispatch
middlewares.push(build_middleware(klass, args, block))
end
- def build(app = Proc.new)
- middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) }
+ def build(app = nil, &block)
+ middlewares.freeze.reverse.inject(app || block) { |a, e| e.build(a) }
end
private
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb
new file mode 100644
index 0000000000..b6c6d2f50d
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb
@@ -0,0 +1,13 @@
+<% actions = ActiveSupport::ActionableError.actions(exception) %>
+
+<% if actions.any? %>
+ <div class="actions">
+ <% actions.each do |action, _| %>
+ <%= button_to action, ActionDispatch::ActionableExceptions.endpoint, params: {
+ error: exception.class.name,
+ action: action,
+ location: request.path
+ } %>
+ <% end %>
+ </div>
+<% end %>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
index bde26f46c2..999e84e4d6 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
@@ -8,7 +8,11 @@
</header>
<div id="container">
- <h2><%= h @exception.message %></h2>
+ <h2>
+ <%= h @exception.message %>
+
+ <%= render "rescues/actions", exception: @exception, request: @request %>
+ </h2>
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx, error_index: 0 %>
<%= render "rescues/trace", traces: @traces, trace_to_show: @trace_to_show, error_index: 0 %>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb
index d144fc1cd2..77cfdd20c8 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb
@@ -13,6 +13,9 @@
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
<br />To resolve this issue run: rails active_storage:install
<% end %>
+ <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
+ <br />To resolve this issue run: rails action_mailbox:install
+ <% end %>
</h2>
<%= render "rescues/source", source_extracts: @source_extracts, show_source_idx: @show_source_idx %>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb
index 55aaf58713..16c3ecc331 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb
@@ -6,6 +6,8 @@
<%= @exception.message %>
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
To resolve this issue run: rails active_storage:install
+<% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
+To resolve this issue run: rails action_mailbox:install
<% end %>
<%= render template: "rescues/_source" %>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb
index 39ea25bdfc..0f78e23b7f 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb
@@ -117,6 +117,10 @@
background-color: #FFCCCC;
}
+ .button_to {
+ display: inline-block;
+ }
+
.hidden {
display: none;
}