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.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/debug_exceptions.rb10
-rw-r--r--actionpack/lib/action_dispatch/middleware/debug_view.rb10
-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/stack.rb15
-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/_request_and_response.html.erb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb75
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb11
15 files changed, 185 insertions, 17 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 b69bcab05c..dac60a13c6 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -287,8 +287,8 @@ module ActionDispatch
DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
def self.build(req, cookies)
- new(req).tap do |hash|
- hash.update(cookies)
+ new(req).tap do |jar|
+ jar.update(cookies)
end
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..148662a48b 100644
--- a/actionpack/lib/action_dispatch/middleware/debug_view.rb
+++ b/actionpack/lib/action_dispatch/middleware/debug_view.rb
@@ -52,5 +52,15 @@ module ActionDispatch
super
end
end
+
+ def protect_against_forgery?
+ false
+ end
+
+ def params_valid?
+ @request.parameters
+ rescue ActionController::BadRequest
+ 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/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index f0c869fba0..57e4adb457 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -34,7 +34,11 @@ module ActionDispatch
end
def build(app)
- InstrumentationProxy.new(klass.new(app, *args, &block), inspect)
+ klass.new(app, *args, &block)
+ end
+
+ def build_instrumented(app)
+ InstrumentationProxy.new(build(app), inspect)
end
end
@@ -119,7 +123,14 @@ module ActionDispatch
end
def build(app = nil, &block)
- middlewares.freeze.reverse.inject(app || block) { |a, e| e.build(a) }
+ instrumenting = ActiveSupport::Notifications.notifier.listening?(InstrumentationProxy::EVENT_NAME)
+ middlewares.freeze.reverse.inject(app || block) do |a, e|
+ if instrumenting
+ e.build_instrumented(a)
+ else
+ e.build(a)
+ end
+ end
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/_request_and_response.html.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
index 49b1e83551..04271d8e8a 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
@@ -6,7 +6,9 @@
<% end %>
<h2 style="margin-top: 30px">Request</h2>
-<p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
+<% if params_valid? %>
+ <p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
+<% end %>
<div class="details">
<div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb
index 396768ecee..ca42a6fa8b 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb
@@ -1,5 +1,5 @@
<%
- clean_params = @request.filtered_parameters.clone
+ clean_params = params_valid? ? @request.filtered_parameters.clone : {}
clean_params.delete("action")
clean_params.delete("controller")
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..57cdcf9aaf 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
@@ -1,14 +1,18 @@
<header>
<h1>
<%= @exception.class.to_s %>
- <% if @request.parameters['controller'] %>
+ <% if params_valid? && @request.parameters['controller'] %>
in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
<% end %>
</h1>
</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/diagnostics.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb
index 603de54b8b..d3265563a8 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb
@@ -1,5 +1,5 @@
<%= @exception.class.to_s %><%
- if @request.parameters['controller']
+ if params_valid? && @request.parameters['controller']
%> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
<% end %>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb
index 39ea25bdfc..f535822ccf 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb
@@ -2,11 +2,14 @@
<html lang="en">
<head>
<meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Action Controller: Exception caught</title>
<style>
body {
background-color: #FAFAFA;
color: #333;
+ color-scheme: light dark;
+ supported-color-schemes: light dark;
margin: 0px;
}
@@ -35,6 +38,7 @@
}
h1 {
+ overflow-wrap: break-word;
margin: 0.2em 0;
line-height: 1.1em;
font-size: 2em;
@@ -50,7 +54,7 @@
border-radius: 4px;
margin: 1em 0px;
display: block;
- width: 978px;
+ max-width: 978px;
}
.summary {
@@ -78,7 +82,7 @@
.source {
border: 1px solid #D9D9D9;
background: #ECECEC;
- width: 978px;
+ max-width: 978px;
}
.source pre {
@@ -114,7 +118,13 @@
}
.line.active {
- background-color: #FFCCCC;
+ background-color: #FCC;
+ }
+
+ .button_to {
+ display: inline-block;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
}
.hidden {
@@ -123,10 +133,67 @@
a { color: #980905; }
a:visited { color: #666; }
- a.trace-frames { color: #666; }
+ a.trace-frames {
+ color: #666;
+ overflow-wrap: break-word;
+ }
a:hover { color: #C52F24; }
a.trace-frames.selected { color: #C52F24 }
+ @media (prefers-color-scheme: dark) {
+ body {
+ background-color: #222;
+ color: #ECECEC;
+ }
+
+ .details {
+ border-color: #666;
+ }
+
+ .summary {
+ border-color: #666;
+ }
+
+ .source {
+ border-color: #555;
+ background-color: #333;
+ }
+
+ .source .data {
+ background: #444;
+ }
+
+ .source .data .line_numbers {
+ background: #333;
+ border-color: #222;
+ }
+
+ .line:hover {
+ background: #666;
+ }
+
+ .line.active {
+ background-color: #977;
+ }
+
+ input[type="submit"] {
+ color: #EEE;
+ background-color: #535353;
+ border: none;
+ border-radius: 3px;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0,0,0,0.15), 0 1px 1px rgba(0,0,0,0.15);
+ padding: 2px 7px;
+ }
+ input[type="submit"]:active {
+ background-color: #777;
+ }
+
+ a { color: #C52F24; }
+ a.trace-frames { color: #999; }
+ a:hover { color: #E9382B; }
+ a.trace-frames.selected { color: #E9382B; }
+ }
+
<%= yield :style %>
</style>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
index 0242b706b2..2fb4650398 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
@@ -49,6 +49,17 @@
width: 80%;
font-size: inherit;
}
+
+ @media (prefers-color-scheme: dark) {
+ #route_table tbody tr:nth-child(odd) {
+ background: #333;
+ }
+
+ #route_table tbody.exact_matches,
+ #route_table tbody.fuzzy_matches {
+ color: #333;
+ }
+ }
<% end %>
<table id='route_table' class='route_table'>