aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb39
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb3
-rw-r--r--actionpack/lib/action_dispatch/journey/router/utils.rb4
-rw-r--r--actionpack/lib/action_dispatch/journey/visitors.rb45
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb13
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb20
6 files changed, 66 insertions, 58 deletions
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index e9031f3fac..ab14a61b97 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -71,6 +71,26 @@ module ActionController
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.h(location)}\">redirected</a>.</body></html>"
end
+ def _compute_redirect_to_location(options) #:nodoc:
+ case options
+ # The scheme name consist of a letter followed by any combination of
+ # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
+ # characters; and is terminated by a colon (":").
+ # See http://tools.ietf.org/html/rfc3986#section-3.1
+ # The protocol relative scheme starts with a double slash "//".
+ when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
+ options
+ when String
+ request.protocol + request.host_with_port + options
+ when :back
+ request.headers["Referer"] or raise RedirectBackError
+ when Proc
+ _compute_redirect_to_location options.call
+ else
+ url_for(options)
+ end.delete("\0\r\n")
+ end
+
private
def _extract_redirect_to_status(options, response_status)
if options.is_a?(Hash) && options.key?(:status)
@@ -81,24 +101,5 @@ module ActionController
302
end
end
-
- def _compute_redirect_to_location(options)
- case options
- # The scheme name consist of a letter followed by any combination of
- # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
- # characters; and is terminated by a colon (":").
- # The protocol relative scheme starts with a double slash "//"
- when %r{\A(\w[\w+.-]*:|//).*}
- options
- when String
- request.protocol + request.host_with_port + options
- when :back
- request.headers["Referer"] or raise RedirectBackError
- when Proc
- _compute_redirect_to_location options.call
- else
- url_for(options)
- end.delete("\0\r\n")
- end
end
end
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 573c739da4..bd64b1f812 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -124,6 +124,9 @@ module ActionController #:nodoc:
@loaded = true
end
+ # no-op
+ def destroy; end
+
def exists?
true
end
diff --git a/actionpack/lib/action_dispatch/journey/router/utils.rb b/actionpack/lib/action_dispatch/journey/router/utils.rb
index 80011597aa..1edf86cd88 100644
--- a/actionpack/lib/action_dispatch/journey/router/utils.rb
+++ b/actionpack/lib/action_dispatch/journey/router/utils.rb
@@ -7,11 +7,13 @@ module ActionDispatch
# Normalizes URI path.
#
# Strips off trailing slash and ensures there is a leading slash.
+ # Also converts downcase url encoded string to uppercase.
#
# normalize_path("/foo") # => "/foo"
# normalize_path("/foo/") # => "/foo"
# normalize_path("foo") # => "/foo"
# normalize_path("") # => "/"
+ # normalize_path("/%ab") # => "/%AB"
def self.normalize_path(path)
path = "/#{path}"
path.squeeze!('/')
@@ -36,7 +38,7 @@ module ActionDispatch
UNSAFE_FRAGMENT = Regexp.new("[^#{safe_fragment}]", false).freeze
end
- Parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
+ Parser = URI::Parser.new
def self.escape_path(path)
Parser.escape(path.to_s, UriEscape::UNSAFE_SEGMENT)
diff --git a/actionpack/lib/action_dispatch/journey/visitors.rb b/actionpack/lib/action_dispatch/journey/visitors.rb
index 0a8cb1b4d4..a5b4679fae 100644
--- a/actionpack/lib/action_dispatch/journey/visitors.rb
+++ b/actionpack/lib/action_dispatch/journey/visitors.rb
@@ -84,44 +84,43 @@ module ActionDispatch
# Used for formatting urls (url_for)
class Formatter < Visitor # :nodoc:
- attr_reader :options, :consumed
+ attr_reader :options
def initialize(options)
@options = options
- @consumed = {}
end
private
- def visit_GROUP(node)
- if consumed == options
- nil
- else
- route = visit(node.left)
- route.include?("\0") ? nil : route
+ def visit(node, optional = false)
+ case node.type
+ when :LITERAL, :SLASH, :DOT
+ node.left
+ when :STAR
+ visit(node.left)
+ when :GROUP
+ visit(node.left, true)
+ when :CAT
+ visit_CAT(node, optional)
+ when :SYMBOL
+ visit_SYMBOL(node)
end
end
- def terminal(node)
- node.left
- end
-
- def binary(node)
- [visit(node.left), visit(node.right)].join
- end
+ def visit_CAT(node, optional)
+ left = visit(node.left, optional)
+ right = visit(node.right, optional)
- def nary(node)
- node.children.map { |c| visit(c) }.join
+ if optional && !(right && left)
+ ""
+ else
+ [left, right].join
+ end
end
def visit_SYMBOL(node)
- key = node.to_sym
-
- if value = options[key]
- consumed[key] = value
+ if value = options[node.to_sym]
Router::Utils.escape_path(value)
- else
- "\0"
end
end
end
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index 6d3f8da932..2fb03f2712 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -74,6 +74,19 @@ module ActionDispatch
# * <tt>:routing_type</tt> - Allowed values are <tt>:path</tt> or <tt>:url</tt>.
# Default is <tt>:url</tt>.
#
+ # Also includes all the options from <tt>url_for</tt>. These include such
+ # things as <tt>:anchor</tt> or <tt>:trailing_slash</tt>. Example usage
+ # is given below:
+ #
+ # polymorphic_url([blog, post], anchor: 'my_anchor')
+ # # => "http://example.com/blogs/1/posts/1#my_anchor"
+ # polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
+ # # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
+ #
+ # For all of these options, see the documentation for <tt>url_for</tt>.
+ #
+ # ==== Functionality
+ #
# # an Article record
# polymorphic_url(record) # same as article_url(record)
#
diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb
index 44ed0ac1f3..93f9fab9c2 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/response.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -67,21 +67,11 @@ module ActionDispatch
end
def normalize_argument_to_redirection(fragment)
- normalized = case fragment
- when Regexp
- fragment
- when %r{^\w[A-Za-z\d+.-]*:.*}
- fragment
- when String
- @request.protocol + @request.host_with_port + fragment
- when :back
- raise RedirectBackError unless refer = @request.headers["Referer"]
- refer
- else
- @controller.url_for(fragment)
- end
-
- normalized.respond_to?(:delete) ? normalized.delete("\0\r\n") : normalized
+ if Regexp === fragment
+ fragment
+ else
+ @controller._compute_redirect_to_location(fragment)
+ end
end
end
end