diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware')
24 files changed, 127 insertions, 53 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb index 852f1cf6f5..baf9d5779e 100644 --- a/actionpack/lib/action_dispatch/middleware/callbacks.rb +++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb @@ -8,14 +8,14 @@ module ActionDispatch class << self delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader" - end - def self.before(*args, &block) - set_callback(:call, :before, *args, &block) - end + def before(*args, &block) + set_callback(:call, :before, *args, &block) + end - def self.after(*args, &block) - set_callback(:call, :after, *args, &block) + def after(*args, &block) + set_callback(:call, :after, *args, &block) + end end def initialize(app) diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 5b914f293d..fe110d7938 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -30,7 +30,7 @@ module ActionDispatch # cookies[:login] = { value: "XJ-122", expires: 1.hour.from_now } # # # Sets a signed cookie, which prevents users from tampering with its value. - # # The cookie is signed by your app's <tt>config.secret_key_base</tt> value. + # # The cookie is signed by your app's <tt>secrets.secret_key_base</tt> value. # # It can be read using the signed method <tt>cookies.signed[:name]</tt> # cookies.signed[:user_id] = current_user.id # @@ -77,7 +77,7 @@ module ActionDispatch # domain and subdomains. # # * <tt>:expires</tt> - The time at which this cookie expires, as a \Time object. - # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers. + # * <tt>:secure</tt> - Whether this cookie is only transmitted to HTTPS servers. # Default is +false+. # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or # only HTTP. Defaults to +false+. @@ -117,10 +117,10 @@ module ActionDispatch # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed # cookie was tampered with by the user (or a 3rd party), nil will be returned. # - # If +config.secret_key_base+ and +config.secret_token+ (deprecated) are both set, + # If +secrets.secret_key_base+ and +config.secret_token+ (deprecated) are both set, # legacy cookies signed with the old key generator will be transparently upgraded. # - # This jar requires that you set a suitable secret for the verification on your app's +config.secret_key_base+. + # This jar requires that you set a suitable secret for the verification on your app's +secrets.secret_key_base+. # # Example: # @@ -140,10 +140,10 @@ module ActionDispatch # Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read. # If the cookie was tampered with by the user (or a 3rd party), nil will be returned. # - # If +config.secret_key_base+ and +config.secret_token+ (deprecated) are both set, + # If +secrets.secret_key_base+ and +config.secret_token+ (deprecated) are both set, # legacy cookies signed with the old key generator will be transparently upgraded. # - # This jar requires that you set a suitable secret for the verification on your app's +config.secret_key_base+. + # This jar requires that you set a suitable secret for the verification on your app's +secrets.secret_key_base+. # # Example: # @@ -160,7 +160,7 @@ module ActionDispatch end end - # Returns the +signed+ or +encrypted jar, preferring +encrypted+ if +secret_key_base+ is set. + # Returns the +signed+ or +encrypted+ jar, preferring +encrypted+ if +secret_key_base+ is set. # Used by ActionDispatch::Session::CookieStore to avoid the need to introduce new cookie stores. def signed_or_encrypted @signed_or_encrypted ||= @@ -409,7 +409,7 @@ module ActionDispatch end # UpgradeLegacySignedCookieJar is used instead of SignedCookieJar if - # config.secret_token and config.secret_key_base are both set. It reads + # config.secret_token and secrets.secret_key_base are both set. It reads # legacy cookies signed with the old dummy key generator and re-saves # them using the new key generator to provide a smooth upgrade path. class UpgradeLegacySignedCookieJar < SignedCookieJar #:nodoc: @@ -427,7 +427,7 @@ module ActionDispatch def initialize(parent_jar, key_generator, options = {}) if ActiveSupport::LegacyKeyGenerator === key_generator - raise "You didn't set config.secret_key_base, which is required for this cookie jar. " + + raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " + "Read the upgrade documentation to learn more about this new config option." end @@ -465,7 +465,7 @@ module ActionDispatch end # UpgradeLegacyEncryptedCookieJar is used by ActionDispatch::Session::CookieStore - # instead of EncryptedCookieJar if config.secret_token and config.secret_key_base + # instead of EncryptedCookieJar if config.secret_token and secrets.secret_key_base # are both set. It reads legacy cookies signed with the old dummy key generator and # encrypts and re-saves them using the new key generator to provide a smooth upgrade path. class UpgradeLegacyEncryptedCookieJar < EncryptedCookieJar #:nodoc: diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb index 64230ff1ae..0ca1a87645 100644 --- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -34,27 +34,35 @@ module ActionDispatch log_error(env, wrapper) if env['action_dispatch.show_detailed_exceptions'] + request = Request.new(env) template = ActionView::Base.new([RESCUES_TEMPLATE_PATH], - :request => Request.new(env), - :exception => wrapper.exception, - :application_trace => wrapper.application_trace, - :framework_trace => wrapper.framework_trace, - :full_trace => wrapper.full_trace, - :routes_inspector => routes_inspector(exception), - :source_extract => wrapper.source_extract, - :line_number => wrapper.line_number, - :file => wrapper.file + request: request, + exception: wrapper.exception, + application_trace: wrapper.application_trace, + framework_trace: wrapper.framework_trace, + full_trace: wrapper.full_trace, + routes_inspector: routes_inspector(exception), + source_extract: wrapper.source_extract, + line_number: wrapper.line_number, + file: wrapper.file ) file = "rescues/#{wrapper.rescue_template}" - body = template.render(:template => file, :layout => 'rescues/layout') - render(wrapper.status_code, body) + + if request.xhr? + body = template.render(template: file, layout: false, formats: [:text]) + format = "text/plain" + else + body = template.render(template: file, layout: 'rescues/layout') + format = "text/html" + end + render(wrapper.status_code, body, format) else raise exception end end - def render(status, body) - [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]] + def render(status, body, format) + [status, {'Content-Type' => "#{format}; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]] end def log_error(env, wrapper) diff --git a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb index 1de3d14530..377f05c982 100644 --- a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb +++ b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb @@ -1,5 +1,5 @@ require 'action_controller/metal/exceptions' -require 'active_support/core_ext/class/attribute_accessors' +require 'active_support/core_ext/module/attribute_accessors' module ActionDispatch class ExceptionWrapper @@ -96,7 +96,7 @@ module ActionDispatch def source_fragment(path, line) return unless Rails.respond_to?(:root) && Rails.root full_path = Rails.root.join(path) - if File.exists?(full_path) + if File.exist?(full_path) File.open(full_path, "r") do |file| start = [line - 3, 0].max lines = file.each_line.drop(start).take(6) diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 0fa1e9b859..b426183488 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -41,9 +41,9 @@ module ActionDispatch when Proc strategy.call(request.raw_post) when :json - data = ActiveSupport::JSON.decode(request.body) + data = ActiveSupport::JSON.decode(request.raw_post) data = {:_json => data} unless data.is_a?(Hash) - request.deep_munge(data).with_indifferent_access + Request::Utils.deep_munge(data).with_indifferent_access else false end diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 8879291dbd..57bc6d5cd0 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -143,7 +143,7 @@ module ActionDispatch # proxies with incompatible IP header conventions, and there is no way # for us to determine which header is the right one after the fact. # Since we have no idea, we give up and explode. - should_check_ip = @check_ip && client_ips.last + should_check_ip = @check_ip && client_ips.last && forwarded_ips.last if should_check_ip && !forwarded_ips.include?(client_ips.last) # We don't know which came from the proxy, and which from the user raise IpSpoofAttackError, "IP spoofing attack?! " + diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index b9eb8036e9..1ebc189c28 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -15,8 +15,8 @@ module ActionDispatch # best possible option given your application's configuration. # # If you only have secret_token set, your cookies will be signed, but - # not encrypted. This means a user cannot alter his +user_id+ without - # knowing your app's secret key, but can easily read his +user_id+. This + # not encrypted. This means a user cannot alter their +user_id+ without + # knowing your app's secret key, but can easily read their +user_id+. This # was the default for Rails 3 apps. # # If you have secret_key_base set, your cookies will be encrypted. This @@ -31,9 +31,10 @@ module ActionDispatch # # Myapp::Application.config.session_store :cookie_store, key: '_your_app_session' # - # Configure your secret key in config/initializers/secret_token.rb: + # Configure your secret key in config/secrets.yml: # - # Myapp::Application.config.secret_key_base 'secret key' + # development: + # secret_key_base: 'secret key' # # To generate a secret key for an existing application, run `rake secret`. # diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index fcc5bc12c4..1d4f0f89a6 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -29,8 +29,11 @@ module ActionDispatch def call(env) @app.call(env) rescue Exception => exception - raise exception if env['action_dispatch.show_exceptions'] == false - render_exception(env, exception) + if env['action_dispatch.show_exceptions'] == false + raise exception + else + render_exception(env, exception) + end end private diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb index 9e03cbf2b7..999c022535 100644 --- a/actionpack/lib/action_dispatch/middleware/ssl.rb +++ b/actionpack/lib/action_dispatch/middleware/ssl.rb @@ -36,8 +36,7 @@ module ActionDispatch url.scheme = "https" url.host = @host if @host url.port = @port if @port - headers = hsts_headers.merge('Content-Type' => 'text/html', - 'Location' => url.to_s) + headers = { 'Content-Type' => 'text/html', 'Location' => url.to_s } [301, headers, []] end @@ -58,7 +57,7 @@ module ActionDispatch cookies = cookies.split("\n") headers['Set-Cookie'] = cookies.map { |cookie| - if cookie !~ /;\s+secure(;|$)/ + if cookie !~ /;\s*secure\s*(;|$)/i "#{cookie}; secure" else cookie diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index c6a7d9c415..2764584fe9 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -11,9 +11,10 @@ module ActionDispatch end def match?(path) - path = path.dup + path = unescape_path(path) + return false unless path.valid_encoding? - full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(unescape_path(path))) + full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(path)) paths = "#{full_path}#{ext}" matches = Dir[paths] @@ -40,7 +41,6 @@ module ActionDispatch end def escape_glob_chars(path) - path.force_encoding('binary') if path.respond_to? :force_encoding path.gsub(/[*?{}\[\]]/, "\\\\\\&") end end diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb index db219c8fa9..db219c8fa9 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb 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 new file mode 100644 index 0000000000..396768ecee --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb @@ -0,0 +1,23 @@ +<% + clean_params = @request.filtered_parameters.clone + clean_params.delete("action") + clean_params.delete("controller") + + request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n") + + def debug_hash(object) + object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n") + end unless self.class.method_defined?(:debug_hash) +%> + +Request parameters +<%= request_dump %> + +Session dump +<%= debug_hash @request.session %> + +Env dump +<%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %> + +Response headers +<%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb index b181909bff..b181909bff 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb new file mode 100644 index 0000000000..d4af5c9b06 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb @@ -0,0 +1,15 @@ +<% + traces = { "Application Trace" => @application_trace, + "Framework Trace" => @framework_trace, + "Full Trace" => @full_trace } +%> + +Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %> + +<% traces.each do |name, trace| %> +<% if trace.any? %> +<%= name %> +<%= trace.join("\n") %> + +<% end %> +<% end %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb index 57a2940802..f154021ae6 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb @@ -8,7 +8,7 @@ </header> <div id="container"> - <h2><%= @exception.message %></h2> + <h2><%= h @exception.message %></h2> <%= render template: "rescues/_source" %> <%= render template: "rescues/_trace" %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb index ca14215946..5c016e544e 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb @@ -3,5 +3,5 @@ </header> <div id="container"> - <h2><%= @exception.message %></h2> + <h2><%= h @exception.message %></h2> </div> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb new file mode 100644 index 0000000000..ae62d9eb02 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb @@ -0,0 +1,3 @@ +Template is missing + +<%= @exception.message %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb index cd3daff065..7e9cedb95e 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb @@ -2,7 +2,7 @@ <h1>Routing Error</h1> </header> <div id="container"> - <h2><%= @exception.message %></h2> + <h2><%= h @exception.message %></h2> <% unless @exception.failures.empty? %> <p> <h2>Failure reasons:</h2> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb new file mode 100644 index 0000000000..f6e4dac1f3 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb @@ -0,0 +1,11 @@ +Routing Error + +<%= @exception.message %> +<% unless @exception.failures.empty? %> +Failure reasons: +<% @exception.failures.each do |route, reason| %> + - <%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %> +<% end %> +<% end %> + +<%= render template: "rescues/_trace", format: :text %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb index 31f46ee340..027a0f5b3e 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb @@ -10,7 +10,7 @@ <p> Showing <i><%= @exception.file_name %></i> where line <b>#<%= @exception.line_number %></b> raised: </p> - <pre><code><%= @exception.message %></code></pre> + <pre><code><%= h @exception.message %></code></pre> <div class="source"> <div class="info"> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb new file mode 100644 index 0000000000..5da21d9784 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb @@ -0,0 +1,8 @@ +<% @source_extract = @exception.source_extract(0, :html) %> +<%= @exception.original_exception.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %> + +Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised: +<%= @exception.message %> +<%= @exception.sub_template_message %> +<%= render template: "rescues/_trace", format: :text %> +<%= render template: "rescues/_request_and_response", format: :text %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb index c1fbf67eed..259fb2bb3b 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb @@ -2,5 +2,5 @@ <h1>Unknown action</h1> </header> <div id="container"> - <h2><%= @exception.message %></h2> + <h2><%= h @exception.message %></h2> </div> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb new file mode 100644 index 0000000000..83973addcb --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb @@ -0,0 +1,3 @@ +Unknown action + +<%= @exception.message %> 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 95461fa693..323873ba4b 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb @@ -89,8 +89,8 @@ } // takes an array of elements with a data-regexp attribute and - // passes their their parent <tr> into the callback function - // if the regexp matchs a given path + // passes their parent <tr> into the callback function + // if the regexp matches a given path function eachElemsForPath(elems, path, func) { each(elems, function(e){ var reg = e.getAttribute("data-regexp"); |