aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb24
-rw-r--r--actionpack/lib/action_dispatch/middleware/string_coercion.rb29
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb19
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb113
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb9
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/selector.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb1
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'