diff options
Diffstat (limited to 'actionpack/lib/action_dispatch')
8 files changed, 113 insertions, 86 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index f27f22c7e7..04a101dbb2 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -179,7 +179,7 @@ module ActionDispatch 'cookie containing the session data. Use ' + 'config.action_controller.session = { :key => ' + '"_myapp_session", :secret => "some secret phrase" } in ' + - 'config/environment.rb' + 'config/application.rb' end end diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 4ebc8a2ab9..10f04dcdf6 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -1,7 +1,24 @@ require 'active_support/core_ext/exception' +require 'active_support/notifications' require 'action_dispatch/http/request' module ActionDispatch + # This middleware rescues any exception returned by the application and renders + # nice exception pages if it's being rescued locally. + # + # Every time an exception is caught, a notification is published, becoming a good API + # to deal with exceptions. So, if you want send an e-mail through ActionMailer + # everytime this notification is published, you just need to do the following: + # + # ActiveSupport::Notifications.subscribe "action_dispatch.show_exception" do |name, start, end, instrumentation_id, payload| + # ExceptionNotifier.deliver_exception(start, payload) + # end + # + # The payload is a hash which has two pairs: + # + # * :env - Contains the rack env for the given request; + # * :exception - The exception raised; + # class ShowExceptions LOCALHOST = '127.0.0.1'.freeze @@ -44,8 +61,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) + ActiveSupport::Notifications.instrument 'action_dispatch.show_exception', + :env => env, :exception => exception do + raise exception if env['action_dispatch.show_exceptions'] == false + render_exception(env, exception) + end end private diff --git a/actionpack/lib/action_dispatch/middleware/string_coercion.rb b/actionpack/lib/action_dispatch/middleware/string_coercion.rb deleted file mode 100644 index 232e947835..0000000000 --- a/actionpack/lib/action_dispatch/middleware/string_coercion.rb +++ /dev/null @@ -1,29 +0,0 @@ -module ActionDispatch - class StringCoercion - class UglyBody < ActiveSupport::BasicObject - def initialize(body) - @body = body - end - - def each - @body.each do |part| - yield part.to_s - end - end - - private - def method_missing(*args, &block) - @body.__send__(*args, &block) - end - end - - def initialize(app) - @app = app - end - - def call(env) - status, headers, body = @app.call(env) - [status, headers, UglyBody.new(body)] - end - end -end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 8f33346a4f..3e577c7f99 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -200,13 +200,22 @@ module ActionDispatch path = args.shift || block path_proc = path.is_a?(Proc) ? path : proc { |params| path % params } status = options[:status] || 301 + body = 'Moved Permanently' lambda do |env| - req = Rack::Request.new(env) - params = path_proc.call(env["action_dispatch.request.path_parameters"]) - url = req.scheme + '://' + req.host + params + req = Request.new(env) - [ status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently'] ] + uri = URI.parse(path_proc.call(req.params.symbolize_keys)) + uri.scheme ||= req.scheme + uri.host ||= req.host + uri.port ||= req.port unless req.port == 80 + + headers = { + 'Location' => uri.to_s, + 'Content-Type' => 'text/html', + 'Content-Length' => body.length.to_s + } + [ status, headers, [body] ] end end @@ -283,7 +292,7 @@ module ActionDispatch end def namespace(path) - scope("/#{path}") { yield } + scope("/#{path}", :name_prefix => path.to_s) { yield } end def constraints(constraints = {}) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index bd397432ce..90893aa0e6 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -74,9 +74,8 @@ module ActionDispatch @routes = {} @helpers = [] - @module ||= Module.new - @module.instance_methods.each do |selector| - @module.class_eval { remove_method selector } + @module ||= Module.new do + instance_methods.each { |selector| remove_method(selector) } end end @@ -138,67 +137,87 @@ module ActionDispatch end end - def named_helper_module_eval(code, *args) - @module.module_eval(code, *args) - end - def define_hash_access(route, name, kind, options) selector = hash_access_name(name, kind) - named_helper_module_eval <<-end_eval # We use module_eval to avoid leaks + + # We use module_eval to avoid leaks + @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 def #{selector}(options = nil) # def hash_for_users_url(options = nil) options ? #{options.inspect}.merge(options) : #{options.inspect} # options ? {:only_path=>false}.merge(options) : {:only_path=>false} end # end protected :#{selector} # protected :hash_for_users_url - end_eval + END_EVAL helpers << selector end + # Create a url helper allowing ordered parameters to be associated + # with corresponding dynamic segments, so you can do: + # + # foo_url(bar, baz, bang) + # + # Instead of: + # + # foo_url(:bar => bar, :baz => baz, :bang => bang) + # + # Also allow options hash, so you can do: + # + # foo_url(bar, baz, bang, :sort_by => 'baz') + # def define_url_helper(route, name, kind, options) selector = url_helper_name(name, kind) - # The segment keys used for positional parameters - hash_access_method = hash_access_name(name, kind) - # allow ordered parameters to be associated with corresponding - # dynamic segments, so you can do - # - # foo_url(bar, baz, bang) - # - # instead of + # We use module_eval to avoid leaks. # - # foo_url(:bar => bar, :baz => baz, :bang => bang) + # def users_url(*args) + # if args.empty? || Hash === args.first + # options = hash_for_users_url(args.first || {}) + # else + # options = hash_for_users_url(args.extract_options!) + # default = default_url_options(options) if self.respond_to?(:default_url_options, true) + # options = (default ||= {}).merge(options) # - # Also allow options hash, so you can do + # keys = [] + # keys -= options.keys if args.size < keys.size - 1 # - # foo_url(bar, baz, bang, :sort_by => 'baz') + # args = args.zip(keys).inject({}) do |h, (v, k)| + # h[k] = v + # h + # end # - named_helper_module_eval <<-end_eval # We use module_eval to avoid leaks - def #{selector}(*args) # def users_url(*args) - # - opts = if args.empty? || Hash === args.first # opts = if args.empty? || Hash === args.first - args.first || {} # args.first || {} - else # else - options = args.extract_options! # options = args.extract_options! - args = args.zip(#{route.segment_keys.inspect}).inject({}) do |h, (v, k)| # args = args.zip([]).inject({}) do |h, (v, k)| - h[k] = v # h[k] = v - h # h - end # end - options.merge(args) # options.merge(args) - end # end - # - url_for(#{hash_access_method}(opts)) # url_for(hash_for_users_url(opts)) - # - end # end - #Add an alias to support the now deprecated formatted_* URL. # #Add an alias to support the now deprecated formatted_* URL. - def formatted_#{selector}(*args) # def formatted_users_url(*args) - ActiveSupport::Deprecation.warn( # ActiveSupport::Deprecation.warn( - "formatted_#{selector}() has been deprecated. " + # "formatted_users_url() has been deprecated. " + - "Please pass format to the standard " + # "Please pass format to the standard " + - "#{selector} method instead.", caller) # "users_url method instead.", caller) - #{selector}(*args) # users_url(*args) - end # end - protected :#{selector} # protected :users_url - end_eval + # # Tell url_for to skip default_url_options + # options[:use_defaults] = false + # options.merge!(args) + # end + # + # url_for(options) + # end + @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 + def #{selector}(*args) + if args.empty? || Hash === args.first + options = #{hash_access_method}(args.first || {}) + else + options = #{hash_access_method}(args.extract_options!) + default = default_url_options(options) if self.respond_to?(:default_url_options, true) + options = (default ||= {}).merge(options) + + keys = #{route.segment_keys.inspect} + keys -= options.keys if args.size < keys.size - 1 # take format into account + + args = args.zip(keys).inject({}) do |h, (v, k)| + h[k] = v + h + end + + # Tell url_for to skip default_url_options + options[:use_defaults] = false + options.merge!(args) + end + + url_for(options) + end + protected :#{selector} + END_EVAL helpers << selector end end diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index 5686bbdbde..c2486d3730 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -2,6 +2,15 @@ module ActionDispatch module Assertions # A small suite of assertions that test responses from Rails applications. module ResponseAssertions + extend ActiveSupport::Concern + + included do + # TODO: Need to pull in AV::Template monkey patches that track which + # templates are rendered. assert_template should probably be part + # of AV instead of AD. + require 'action_view/test_case' + end + # Asserts that the response is one of the following types: # # * <tt>:success</tt> - Status code was 200 diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index c2dc591ff7..a6b1126e2b 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -524,7 +524,7 @@ module ActionDispatch fix_content = lambda do |node| # Gets around a bug in the Rails 1.1 HTML parser. - node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { CGI.escapeHTML($1) } + node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { Rack::Utils.escapeHTML($1) } end selected = elements.map do |element| diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 2a5f5dcd5c..4ec47d146c 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -1,6 +1,5 @@ require 'stringio' require 'uri' -require 'active_support/test_case' require 'active_support/core_ext/object/metaclass' require 'rack/test' |