From e67f001e7c1b3d24750e9dd81006d2ad84bbf50e Mon Sep 17 00:00:00 2001 From: Agis- Date: Fri, 11 Jul 2014 13:24:49 +0300 Subject: Use `#bytesize` instead of `#size` when checking for cookie overflow Although the cookie values happens to be ASCII strings because they are Base64 encoded, it is semantically incorrect to check for the number of the characters in the cookie, when we actually want to check for the number of the bytes it consists of. Furthermore it is unecessary coupling with the current implementation that uses Base64 for encoding the values. --- actionpack/lib/action_dispatch/middleware/cookies.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index e069840b8e..ac9e5effe2 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -468,7 +468,7 @@ module ActionDispatch options = { :value => @verifier.generate(serialize(name, options)) } end - raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE + raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE @parent_jar[name] = options end @@ -526,7 +526,7 @@ module ActionDispatch options[:value] = @encryptor.encrypt_and_sign(serialize(name, options[:value])) - raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE + raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE @parent_jar[name] = options end -- cgit v1.2.3 From f49d20ef36c2d339e7a988fdc52981cdb95af22f Mon Sep 17 00:00:00 2001 From: Grey Baker Date: Sun, 13 Jul 2014 17:58:20 +0100 Subject: Stash original path in `ShowExceptions` middleware `ActionDispatch::ShowExceptions` overwrites `PATH_INFO` with the status code for the exception defined in `ExceptionWrapper`, so the path the user was visiting when an exception occurred was not previously available to any custom exceptions_app. The original `PATH_INFO` is now stashed in `env["action_dispatch.original_path"]`. --- actionpack/lib/action_dispatch/middleware/show_exceptions.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 1d4f0f89a6..f0779279c1 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -42,6 +42,7 @@ module ActionDispatch wrapper = ExceptionWrapper.new(env, exception) status = wrapper.status_code env["action_dispatch.exception"] = wrapper.exception + env["action_dispatch.original_path"] = env["PATH_INFO"] env["PATH_INFO"] = "/#{status}" response = @exceptions_app.call(env) response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response -- cgit v1.2.3 From 0777b17dafd54442409c02237be8b5562025ed3f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 1 Jul 2014 15:33:30 -0700 Subject: RouteSet should be in charge of constructing the dispather Now we can override how requests are dispatched in the routeset object --- actionpack/lib/action_dispatch/routing/mapper.rb | 17 +++++++++-------- actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++++ 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 235a840682..cf8826eec6 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -66,7 +66,7 @@ module ActionDispatch attr_reader :requirements, :conditions, :defaults attr_reader :to, :default_controller, :default_action, :as, :anchor - def self.build(scope, path, options) + def self.build(scope, set, path, options) options = scope[:options].merge(options) if scope[:options] options.delete :only @@ -77,12 +77,13 @@ module ActionDispatch defaults = (scope[:defaults] || {}).merge options.delete(:defaults) || {} - new scope, path, defaults, options + new scope, set, path, defaults, options end - def initialize(scope, path, defaults, options) + def initialize(scope, set, path, defaults, options) @requirements, @conditions = {}, {} @defaults = defaults + @set = set @to = options.delete :to @default_controller = options.delete(:controller) || scope[:controller] @@ -249,9 +250,9 @@ module ActionDispatch Constraints.new(to, blocks, false) else if blocks.any? - Constraints.new(dispatcher, blocks, true) + Constraints.new(dispatcher(defaults), blocks, true) else - dispatcher + dispatcher(defaults) end end end @@ -348,8 +349,8 @@ module ActionDispatch parser.parse path end - def dispatcher - Routing::RouteSet::Dispatcher.new(defaults) + def dispatcher(defaults) + @set.dispatcher defaults end end @@ -1551,7 +1552,7 @@ module ActionDispatch options[:as] = name_for_action(options[:as], action) end - mapping = Mapping.build(@scope, URI.parser.escape(path), options) + mapping = Mapping.build(@scope, @set, URI.parser.escape(path), options) app, conditions, requirements, defaults, as, anchor = mapping.to_route @set.add_route(app, conditions, requirements, defaults, as, anchor) end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 69535faabd..1ee74e6810 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -334,6 +334,10 @@ module ActionDispatch @prepend.each { |blk| eval_block(blk) } end + def dispatcher(defaults) + Routing::RouteSet::Dispatcher.new(defaults) + end + module MountedHelpers #:nodoc: extend ActiveSupport::Concern include UrlFor -- cgit v1.2.3 From 8e105a55383a3c94dfe3507c37b79a5e4fe85276 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 15 Jul 2014 15:31:31 -0700 Subject: rack 1.6 encodes the filenames in posts correctly now --- actionpack/lib/action_dispatch/http/upload.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb index 45bf751d09..538bcfdcd7 100644 --- a/actionpack/lib/action_dispatch/http/upload.rb +++ b/actionpack/lib/action_dispatch/http/upload.rb @@ -27,7 +27,7 @@ module ActionDispatch @tempfile = hash[:tempfile] raise(ArgumentError, ':tempfile is required') unless @tempfile - @original_filename = encode_filename(hash[:filename]) + @original_filename = hash[:filename] @content_type = hash[:type] @headers = hash[:head] end @@ -66,13 +66,6 @@ module ActionDispatch def eof? @tempfile.eof? end - - private - - def encode_filename(filename) - # Encode the filename in the utf8 encoding, unless it is nil - filename.force_encoding(Encoding::UTF_8).encode! if filename - end end end end -- cgit v1.2.3 From 1ae9f056c5ea5c588ebdf8adce03d35efd049139 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 15 Jul 2014 18:19:11 -0700 Subject: routed applications will respond to these methods --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- actionpack/lib/action_dispatch/testing/integration.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index cf8826eec6..6419c17be9 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -616,7 +616,7 @@ module ActionDispatch end def define_generate_prefix(app, name) - return unless app.respond_to?(:routes) && app.routes.respond_to?(:define_mounted_helper) + return unless app.respond_to?(:routes) _route = @set.named_routes.routes[name.to_sym] _routes = @set diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 08d4eee7fb..cb2cb10870 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -200,7 +200,7 @@ module ActionDispatch @url_options ||= default_url_options.dup.tap do |url_options| url_options.reverse_merge!(controller.url_options) if controller - if @app.respond_to?(:routes) && @app.routes.respond_to?(:default_url_options) + if @app.respond_to?(:routes) url_options.reverse_merge!(@app.routes.default_url_options) end -- cgit v1.2.3 From 90f0cdc906fcec77937363c87cba45f3802ac858 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 11:35:27 -0700 Subject: always transcode the file to utf-8 people may be passing filenames to the constructor that are not utf-8, but they will assome that calling `original_filename` returns utf-8 (because that's what it used to do). --- actionpack/lib/action_dispatch/http/upload.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb index 538bcfdcd7..540e11a4a0 100644 --- a/actionpack/lib/action_dispatch/http/upload.rb +++ b/actionpack/lib/action_dispatch/http/upload.rb @@ -28,6 +28,7 @@ module ActionDispatch raise(ArgumentError, ':tempfile is required') unless @tempfile @original_filename = hash[:filename] + @original_filename &&= @original_filename.encode "UTF-8" @content_type = hash[:type] @headers = hash[:head] end -- cgit v1.2.3 From f636652dd52ed36f7438c0436679c987cdfefb82 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 11:54:53 -0700 Subject: extract inner options before delegating to the helper If we extract the options from the user facing method call ASAP, then we can simplify internal logic. --- actionpack/lib/action_dispatch/routing/route_set.rb | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 1ee74e6810..d24751d28d 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -155,8 +155,8 @@ module ActionDispatch @arg_size = @required_parts.size end - def call(t, args) - if args.size == arg_size && !args.last.is_a?(Hash) && optimize_routes_generation?(t) + def call(t, args, inner_options) + if args.size == arg_size && !inner_options && optimize_routes_generation?(t) options = t.url_options.merge @options options[:path] = optimized_helper(args) ActionDispatch::Http::URL.url_for(options) @@ -207,15 +207,19 @@ module ActionDispatch @route = route end - def call(t, args) + def call(t, args, inner_options) controller_options = t.url_options options = controller_options.merge @options - hash = handle_positional_args(controller_options, args, options, @segment_keys) + hash = handle_positional_args(controller_options, + inner_options || {}, + args, + options, + @segment_keys) + t._routes.url_for(hash) end - def handle_positional_args(controller_options, args, result, path_params) - inner_options = args.extract_options! + def handle_positional_args(controller_options, inner_options, args, result, path_params) if args.size > 0 if args.size < path_params.size - 1 # take format into account @@ -251,7 +255,9 @@ module ActionDispatch @module.remove_possible_method name @module.module_eval do define_method(name) do |*args| - helper.call self, args + options = nil + options = args.pop if args.last.is_a? Hash + helper.call self, args, options end end -- cgit v1.2.3 From 832d2c40df31db7dd6b679b85644089518810638 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 14:47:45 -0700 Subject: we should be checking if the app is a class Hopefully `object.class` always returns something that is_a?(Class), so the previous logic didn't really make sense. --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 6419c17be9..e77f6286ea 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -610,7 +610,7 @@ module ActionDispatch if app.respond_to?(:railtie_name) app.railtie_name else - class_name = app.class.is_a?(Class) ? app.name : app.class.name + class_name = app.is_a?(Class) ? app.name : app.class.name ActiveSupport::Inflector.underscore(class_name).tr("/", "_") end end -- cgit v1.2.3 From d66536d7d478c47d3b47f4a9aee892e2881c7d64 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 15:08:55 -0700 Subject: app should always be a class (I suppose) --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index e77f6286ea..1fe5cce6a8 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -610,7 +610,7 @@ module ActionDispatch if app.respond_to?(:railtie_name) app.railtie_name else - class_name = app.is_a?(Class) ? app.name : app.class.name + class_name = app.name ActiveSupport::Inflector.underscore(class_name).tr("/", "_") end end -- cgit v1.2.3 From 4a7b95985f54ef1847f50eff294f7361d900539f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 15:41:47 -0700 Subject: Rails-ish apps should descend from Rails::Railtie Use an is_a check to ensure it's a Railsish app so we can avoid respond_to calls everywhere. --- actionpack/lib/action_dispatch/routing/mapper.rb | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 1fe5cce6a8..c16b04520e 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -605,18 +605,13 @@ module ActionDispatch private def app_name(app) - return unless app.respond_to?(:routes) + return unless app.is_a?(Class) && app < Rails::Railtie - if app.respond_to?(:railtie_name) - app.railtie_name - else - class_name = app.name - ActiveSupport::Inflector.underscore(class_name).tr("/", "_") - end + app.railtie_name end def define_generate_prefix(app, name) - return unless app.respond_to?(:routes) + return unless app.is_a?(Class) && app < Rails::Railtie _route = @set.named_routes.routes[name.to_sym] _routes = @set -- cgit v1.2.3 From 9b15828b5c347395b42066a588c88e5eb4e72279 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 16:13:08 -0700 Subject: push rails app testing up this way we only have to test for whether it is a rails app once. --- actionpack/lib/action_dispatch/routing/mapper.rb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index c16b04520e..32d963ba76 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -577,13 +577,21 @@ module ActionDispatch raise "A rack application must be specified" unless path - options[:as] ||= app_name(app) + rails_app = rails_app? app + + if rails_app + options[:as] ||= app.railtie_name + else + # non rails apps can't have an :as + options[:as] = nil + end + target_as = name_for_action(options[:as], path) options[:via] ||= :all match(path, options.merge(:to => app, :anchor => false, :format => false)) - define_generate_prefix(app, target_as) + define_generate_prefix(app, target_as) if rails_app self end @@ -604,15 +612,11 @@ module ActionDispatch end private - def app_name(app) - return unless app.is_a?(Class) && app < Rails::Railtie - - app.railtie_name + def rails_app?(app) + app.is_a?(Class) && app < Rails::Railtie end def define_generate_prefix(app, name) - return unless app.is_a?(Class) && app < Rails::Railtie - _route = @set.named_routes.routes[name.to_sym] _routes = @set app.routes.define_mounted_helper(name) @@ -1541,7 +1545,7 @@ module ActionDispatch action = nil end - if !options.fetch(:as, true) + if !options.fetch(:as, true) # if it's set to nil or false options.delete(:as) else options[:as] = name_for_action(options[:as], action) -- cgit v1.2.3 From 1e930e7a488c91beaebfa9682394877e9ad70183 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 16:31:07 -0700 Subject: we do not need to dup the options hash, it is private and a new object each call --- actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index d24751d28d..4fb32a76eb 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -249,8 +249,8 @@ module ActionDispatch # # foo_url(bar, baz, bang, sort_by: 'baz') # - def define_url_helper(route, name, options) - helper = UrlHelper.create(route, options.dup) + def define_url_helper(route, name, opts) + helper = UrlHelper.create(route, opts) @module.remove_possible_method name @module.module_eval do -- cgit v1.2.3 From f875331e3282228d2019392b1653fb8ea39fd711 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 17:27:03 -0700 Subject: only extract :params from the options hash once --- actionpack/lib/action_dispatch/http/url.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 6ba2820d09..f5e71f5a3d 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -48,9 +48,8 @@ module ActionDispatch end if options.key? :params - params = options[:params].is_a?(Hash) ? - options[:params] : - { params: options[:params] } + param = options[:params] + params = param.is_a?(Hash) ? param : { params: param } params.reject! { |_,v| v.to_param.nil? } result << "?#{params.to_query}" unless params.empty? -- cgit v1.2.3 From 69799eda94c41461cf4a8157f457f0be4a012611 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 18:13:22 -0700 Subject: break out path building logic to methods --- actionpack/lib/action_dispatch/http/url.rb | 36 ++++++++++++++++++------------ 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index f5e71f5a3d..fc1d0e6663 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -34,19 +34,26 @@ module ActionDispatch raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true' end - path = options[:script_name].to_s.chomp("/") - path << options[:path].to_s + result = options[:script_name].to_s.chomp("/") + result << options[:path].to_s - path = add_trailing_slash(path) if options[:trailing_slash] + result = add_trailing_slash(result) if options[:trailing_slash] - result = if options[:only_path] - path - else - protocol = options[:protocol] - port = options[:port] - build_host_url(host, port, protocol, options).concat path - end + result = add_params options, result + result = add_anchor options, result + if options[:only_path] + result + else + protocol = options[:protocol] + port = options[:port] + build_host_url(host, port, protocol, options, result) + end + end + + private + + def add_params(options, result) if options.key? :params param = options[:params] params = param.is_a?(Hash) ? param : { params: param } @@ -54,13 +61,14 @@ module ActionDispatch params.reject! { |_,v| v.to_param.nil? } result << "?#{params.to_query}" unless params.empty? end + result + end + def add_anchor(options, result) result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor] result end - private - def extract_domain_from(host, tld_length) host.split('.').last(1 + tld_length).join('.') end @@ -82,7 +90,7 @@ module ActionDispatch path end - def build_host_url(host, port, protocol, options) + def build_host_url(host, port, protocol, options, path) if match = host.match(HOST_REGEXP) protocol ||= match[1] unless protocol == false host = match[2] @@ -103,7 +111,7 @@ module ActionDispatch result << ":#{normalized_port}" } - result + result.concat path end def named_host?(host) -- cgit v1.2.3 From 0e26271456a772de5ce4c4c78cce3a275bcb89a8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jul 2014 18:15:15 -0700 Subject: extract path building to a method --- actionpack/lib/action_dispatch/http/url.rb | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index fc1d0e6663..5decab3d8f 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -34,21 +34,23 @@ module ActionDispatch raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true' end + if options[:only_path] + path_for options + else + protocol = options[:protocol] + port = options[:port] + build_host_url(host, port, protocol, options, path_for(options)) + end + end + + def path_for(options) result = options[:script_name].to_s.chomp("/") result << options[:path].to_s result = add_trailing_slash(result) if options[:trailing_slash] result = add_params options, result - result = add_anchor options, result - - if options[:only_path] - result - else - protocol = options[:protocol] - port = options[:port] - build_host_url(host, port, protocol, options, result) - end + add_anchor options, result end private -- cgit v1.2.3 From 2888f8653e2e0a6394e41cb4e8db2e2d81313eb7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 17 Jul 2014 10:47:58 -0700 Subject: use a strategy object for generating urls in named helpers since we know that the route should be a path or fully qualified, we can pass a strategy object that handles generation. This allows us to eliminate an "if only_path" branch when generating urls. --- actionpack/lib/action_dispatch/http/url.rb | 21 +++++++----- .../lib/action_dispatch/routing/route_set.rb | 37 ++++++++++++++-------- 2 files changed, 37 insertions(+), 21 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 5decab3d8f..473f692b05 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -29,20 +29,25 @@ module ActionDispatch end def url_for(options) - host = options[:host] - unless host || options[:only_path] - raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true' - end - if options[:only_path] path_for options else - protocol = options[:protocol] - port = options[:port] - build_host_url(host, port, protocol, options, path_for(options)) + full_url_for options end end + def full_url_for(options) + host = options[:host] + protocol = options[:protocol] + port = options[:port] + + unless host + raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true' + end + + build_host_url(host, port, protocol, options, path_for(options)) + end + def path_for(options) result = options[:script_name].to_s.chomp("/") result << options[:path].to_s diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 4fb32a76eb..3ecf6a76f1 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -134,11 +134,11 @@ module ActionDispatch end class UrlHelper # :nodoc: - def self.create(route, options) + def self.create(route, options, url_strategy) if optimize_helper?(route) - OptimizedUrlHelper.new(route, options) + OptimizedUrlHelper.new(route, options, url_strategy) else - new route, options + new route, options, url_strategy end end @@ -146,10 +146,12 @@ module ActionDispatch !route.glob? && route.path.requirements.empty? end + attr_reader :url_strategy + class OptimizedUrlHelper < UrlHelper # :nodoc: attr_reader :arg_size - def initialize(route, options) + def initialize(route, options, url_strategy) super @required_parts = @route.required_parts @arg_size = @required_parts.size @@ -159,7 +161,7 @@ module ActionDispatch if args.size == arg_size && !inner_options && optimize_routes_generation?(t) options = t.url_options.merge @options options[:path] = optimized_helper(args) - ActionDispatch::Http::URL.url_for(options) + url_strategy.call options else super end @@ -201,10 +203,11 @@ module ActionDispatch end end - def initialize(route, options) + def initialize(route, options, url_strategy) @options = options @segment_keys = route.segment_keys.uniq @route = route + @url_strategy = url_strategy end def call(t, args, inner_options) @@ -216,7 +219,7 @@ module ActionDispatch options, @segment_keys) - t._routes.url_for(hash) + t._routes.url_for(hash, url_strategy) end def handle_positional_args(controller_options, inner_options, args, result, path_params) @@ -249,8 +252,8 @@ module ActionDispatch # # foo_url(bar, baz, bang, sort_by: 'baz') # - def define_url_helper(route, name, opts) - helper = UrlHelper.create(route, opts) + def define_url_helper(route, name, opts, url_strategy) + helper = UrlHelper.create(route, opts, url_strategy) @module.remove_possible_method name @module.module_eval do @@ -266,12 +269,20 @@ module ActionDispatch def define_named_route_methods(name, route) define_url_helper route, :"#{name}_path", - route.defaults.merge(:use_route => name, :only_path => true) + route.defaults.merge(:use_route => name), PATH + define_url_helper route, :"#{name}_url", - route.defaults.merge(:use_route => name, :only_path => false) + route.defaults.merge(:use_route => name), FULL end end + # :stopdoc: + # strategy for building urls to send to the client + PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) } + FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) } + UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) } + # :startdoc: + attr_accessor :formatter, :set, :named_routes, :default_scope, :router attr_accessor :disable_clear_and_finalize, :resources_path_names attr_accessor :default_url_options, :request_class @@ -643,7 +654,7 @@ module ActionDispatch end # The +options+ argument must be a hash whose keys are *symbols*. - def url_for(options) + def url_for(options, url_strategy = UNKNOWN) options = default_url_options.merge options user = password = nil @@ -677,7 +688,7 @@ module ActionDispatch options[:user] = user options[:password] = password - ActionDispatch::Http::URL.url_for(options) + url_strategy.call options end def call(env) -- cgit v1.2.3 From 212057b912627b9c4056f911a43c83b18ae3ab34 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 17 Jul 2014 11:21:06 -0700 Subject: pass the route name to define_url_helper this allows us to avoid 2 hash allocations per named helper definition, also we can avoid a `merge` and `delete`. --- .../lib/action_dispatch/routing/route_set.rb | 42 +++++++++++----------- actionpack/lib/action_dispatch/routing/url_for.rb | 4 ++- 2 files changed, 24 insertions(+), 22 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 3ecf6a76f1..80c705608d 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -134,11 +134,11 @@ module ActionDispatch end class UrlHelper # :nodoc: - def self.create(route, options, url_strategy) + def self.create(route, options, route_name, url_strategy) if optimize_helper?(route) - OptimizedUrlHelper.new(route, options, url_strategy) + OptimizedUrlHelper.new(route, options, route_name, url_strategy) else - new route, options, url_strategy + new route, options, route_name, url_strategy end end @@ -146,12 +146,12 @@ module ActionDispatch !route.glob? && route.path.requirements.empty? end - attr_reader :url_strategy + attr_reader :url_strategy, :route_name class OptimizedUrlHelper < UrlHelper # :nodoc: attr_reader :arg_size - def initialize(route, options, url_strategy) + def initialize(route, options, route_name, url_strategy) super @required_parts = @route.required_parts @arg_size = @required_parts.size @@ -203,11 +203,12 @@ module ActionDispatch end end - def initialize(route, options, url_strategy) + def initialize(route, options, route_name, url_strategy) @options = options @segment_keys = route.segment_keys.uniq @route = route @url_strategy = url_strategy + @route_name = route_name end def call(t, args, inner_options) @@ -219,7 +220,7 @@ module ActionDispatch options, @segment_keys) - t._routes.url_for(hash, url_strategy) + t._routes.url_for(hash, route_name, url_strategy) end def handle_positional_args(controller_options, inner_options, args, result, path_params) @@ -252,8 +253,8 @@ module ActionDispatch # # foo_url(bar, baz, bang, sort_by: 'baz') # - def define_url_helper(route, name, opts, url_strategy) - helper = UrlHelper.create(route, opts, url_strategy) + def define_url_helper(route, name, opts, route_key, url_strategy) + helper = UrlHelper.create(route, opts, route_key, url_strategy) @module.remove_possible_method name @module.module_eval do @@ -268,11 +269,8 @@ module ActionDispatch end def define_named_route_methods(name, route) - define_url_helper route, :"#{name}_path", - route.defaults.merge(:use_route => name), PATH - - define_url_helper route, :"#{name}_url", - route.defaults.merge(:use_route => name), FULL + define_url_helper route, :"#{name}_path", route.defaults, name, PATH + define_url_helper route, :"#{name}_url", route.defaults, name, FULL end end @@ -512,8 +510,8 @@ module ActionDispatch attr_reader :options, :recall, :set, :named_route - def initialize(options, recall, set) - @named_route = options.delete(:use_route) + def initialize(named_route, options, recall, set) + @named_route = named_route @options = options.dup @recall = recall.dup @set = set @@ -629,13 +627,15 @@ module ActionDispatch end def generate_extras(options, recall={}) - path, params = generate(options, recall) + route_key = options.delete :use_route + path, params = generate(route_key, options, recall) return path, params.keys end - def generate(options, recall = {}) - Generator.new(options, recall, self).generate + def generate(route_key, options, recall = {}) + Generator.new(route_key, options, recall, self).generate end + private :generate RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length, :trailing_slash, :anchor, :params, :only_path, :script_name, @@ -654,7 +654,7 @@ module ActionDispatch end # The +options+ argument must be a hash whose keys are *symbols*. - def url_for(options, url_strategy = UNKNOWN) + def url_for(options, route_name = nil, url_strategy = UNKNOWN) options = default_url_options.merge options user = password = nil @@ -676,7 +676,7 @@ module ActionDispatch path_options = options.dup RESERVED_OPTIONS.each { |ro| path_options.delete ro } - path, params = generate(path_options, recall) + path, params = generate(route_name, path_options, recall) if options.key? :params params.merge! options[:params] diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index e624fe3c4a..e1c73f8f07 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -152,7 +152,9 @@ module ActionDispatch when nil _routes.url_for(url_options.symbolize_keys) when Hash - _routes.url_for(options.symbolize_keys.reverse_merge!(url_options)) + route_name = options.delete :use_route + _routes.url_for(options.symbolize_keys.reverse_merge!(url_options), + route_name) when String options when Symbol -- cgit v1.2.3 From 932386be8a9c0f60c7bb078261c5433aeccb3284 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 17 Jul 2014 11:26:59 -0700 Subject: `recall` should be `path_parameters`, also make it required "recall" is a terrible name. This variable contains the parameters that we got from the path (e.g. for "/posts/1" it has :controller => "posts", :id => "1"). Since it contains the parameters we got from the path, "path_parameters" is a better name. We always pass path_parameters to `generate`, so lets make it required. --- actionpack/lib/action_dispatch/journey/formatter.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb index 6d58323789..59b353b1b7 100644 --- a/actionpack/lib/action_dispatch/journey/formatter.rb +++ b/actionpack/lib/action_dispatch/journey/formatter.rb @@ -12,12 +12,12 @@ module ActionDispatch @cache = nil end - def generate(name, options, recall = {}, parameterize = nil) - constraints = recall.merge(options) + def generate(name, options, path_parameters, parameterize = nil) + constraints = path_parameters.merge(options) missing_keys = [] match_route(name, constraints) do |route| - parameterized_parts = extract_parameterized_parts(route, options, recall, parameterize) + parameterized_parts = extract_parameterized_parts(route, options, path_parameters, parameterize) # Skip this route unless a name has been provided or it is a # standard Rails route since we can't determine whether an options -- cgit v1.2.3 From 9ff18e4626ceb3e50b81b2966d304d02160b619e Mon Sep 17 00:00:00 2001 From: Earl J St Sauver Date: Sun, 27 Apr 2014 16:41:25 -0700 Subject: LOCALHOST definition should match any 127.0.0.0/8 address The entire 127.0.0.0/8 range is assigned to the loopback address, not only 127.0.0.0/24. This patch allows ActionDispatch::Request::LOCALHOST to match any IPv4 127.0.0.0/8 loopback address. The only place that the #local? method was previously under test was in the show_expectations_test.rb file. I don't particularly like that that's implicitly where this code is under test, and I feel like I should move some of that testing code into the test/dispatch/request_test.rb file, but I wanted some feedback first. Credit goes to @sriedel for discovering the issue and adding the patch. --- actionpack/lib/action_dispatch/http/request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 01f117be99..a519d6c1fc 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -23,7 +23,7 @@ module ActionDispatch autoload :Session, 'action_dispatch/request/session' autoload :Utils, 'action_dispatch/request/utils' - LOCALHOST = Regexp.union [/^127\.0\.0\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/] + LOCALHOST = Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/] ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_TRANSLATED REMOTE_HOST -- cgit v1.2.3 From d14f64699715d24a7ceb33e6ef8fa14127716c24 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Sun, 20 Jul 2014 22:51:39 +0800 Subject: Fix AC::TemplateAssertions instance variables not resetting. Fixes https://github.com/rails/rails/issues/16119. --- actionpack/lib/action_dispatch/testing/integration.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index cb2cb10870..12b796b95f 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -329,6 +329,7 @@ module ActionDispatch xml_http_request xhr get_via_redirect post_via_redirect).each do |method| define_method(method) do |*args| reset! unless integration_session + reset_template_assertion # reset the html_document variable, but only for new get/post calls @html_document = nil unless method == 'cookies' || method == 'assigns' integration_session.__send__(method, *args).tap do -- cgit v1.2.3 From 099fd0efc47225afde9394d5f4225fc8ddcd4ae8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 28 Jul 2014 13:57:05 -0700 Subject: remove some caching this caching doesn't increase performance, but does increase complexity. remove it for now and find better ways to speed up this code. --- actionpack/lib/action_dispatch/routing/url_for.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index e1c73f8f07..eb554ec383 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -171,8 +171,7 @@ module ActionDispatch protected def optimize_routes_generation? - return @_optimized_routes if defined?(@_optimized_routes) - @_optimized_routes = _routes.optimize_routes_generation? && default_url_options.empty? + _routes.optimize_routes_generation? && default_url_options.empty? end def _with_routes(routes) -- cgit v1.2.3 From 9f63a78d554690efba3819310710634228089d24 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 28 Jul 2014 14:07:53 -0700 Subject: remove the mounted? method we know the routes should not be "optimized" when mounting an application --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 32d963ba76..95f5f45abe 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -621,7 +621,7 @@ module ActionDispatch _routes = @set app.routes.define_mounted_helper(name) app.routes.extend Module.new { - def mounted?; true; end + def optimize_routes_generation?; false; end define_method :find_script_name do |options| super(options) || begin prefix_options = options.slice(*_route.segment_keys) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 80c705608d..947391b725 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -641,12 +641,8 @@ module ActionDispatch :trailing_slash, :anchor, :params, :only_path, :script_name, :original_script_name] - def mounted? - false - end - def optimize_routes_generation? - !mounted? && default_url_options.empty? + default_url_options.empty? end def find_script_name(options) -- cgit v1.2.3 From d2d33769030b3a560bdbc9c33e7c189274a0dc3a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Jul 2014 11:07:36 -0700 Subject: eval_block should be private --- actionpack/lib/action_dispatch/routing/route_set.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 947391b725..7259b01c99 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -334,6 +334,7 @@ module ActionDispatch mapper.instance_exec(&block) end end + private :eval_block def finalize! return if @finalized -- cgit v1.2.3 From a2e926698dfa9bb978958b181b3ed5c80fee8c6e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Jul 2014 11:28:45 -0700 Subject: only ask for the routes module once we can cache the module on the stack, then reuse it --- actionpack/lib/action_dispatch/routing/route_set.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 7259b01c99..f735b9d1c7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -401,14 +401,16 @@ module ActionDispatch def url_options; {}; end end + route_methods = routes.named_routes.module + # Make named_routes available in the module singleton # as well, so one can do: # Rails.application.routes.url_helpers.posts_path - extend routes.named_routes.module + extend route_methods # Any class that includes this module will get all # named routes... - include routes.named_routes.module + include route_methods # plus a singleton class method called _routes ... included do -- cgit v1.2.3 From 41931b8af1324f0edf6754fbbfe66433b0b02cf1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Jul 2014 11:32:17 -0700 Subject: pass the module to define_named_route_methods after this, we can disconnect @module from the instance --- actionpack/lib/action_dispatch/routing/route_set.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index f735b9d1c7..aa0803e0e3 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -109,7 +109,7 @@ module ActionDispatch def add(name, route) routes[name.to_sym] = route - define_named_route_methods(name, route) + define_named_route_methods(@module, name, route) end def get(name) @@ -253,11 +253,11 @@ module ActionDispatch # # foo_url(bar, baz, bang, sort_by: 'baz') # - def define_url_helper(route, name, opts, route_key, url_strategy) + def define_url_helper(mod, route, name, opts, route_key, url_strategy) helper = UrlHelper.create(route, opts, route_key, url_strategy) - @module.remove_possible_method name - @module.module_eval do + mod.remove_possible_method name + mod.module_eval do define_method(name) do |*args| options = nil options = args.pop if args.last.is_a? Hash @@ -268,9 +268,9 @@ module ActionDispatch helpers << name end - def define_named_route_methods(name, route) - define_url_helper route, :"#{name}_path", route.defaults, name, PATH - define_url_helper route, :"#{name}_url", route.defaults, name, FULL + def define_named_route_methods(mod, name, route) + define_url_helper mod, route, :"#{name}_path", route.defaults, name, PATH + define_url_helper mod, route, :"#{name}_url", route.defaults, name, FULL end end -- cgit v1.2.3 From 0088b08dcaf16176c8f9364d1d786f0c3728d369 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Jul 2014 11:48:14 -0700 Subject: helpers should be a Set so it doesn't grow unbounded since helpers is a set, we can be confident about when to remove methods from the module. --- actionpack/lib/action_dispatch/routing/route_set.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index aa0803e0e3..14c5d663a3 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -90,7 +90,7 @@ module ActionDispatch def initialize @routes = {} - @helpers = [] + @helpers = Set.new @module = Module.new end @@ -100,7 +100,7 @@ module ActionDispatch def clear! @helpers.each do |helper| - @module.remove_possible_method helper + @module.send :undef_method, helper end @routes.clear @@ -108,7 +108,11 @@ module ActionDispatch end def add(name, route) - routes[name.to_sym] = route + key = name.to_sym + if routes.key? key + undef_named_route_methods @module, name + end + routes[key] = route define_named_route_methods(@module, name, route) end @@ -256,7 +260,6 @@ module ActionDispatch def define_url_helper(mod, route, name, opts, route_key, url_strategy) helper = UrlHelper.create(route, opts, route_key, url_strategy) - mod.remove_possible_method name mod.module_eval do define_method(name) do |*args| options = nil @@ -272,6 +275,11 @@ module ActionDispatch define_url_helper mod, route, :"#{name}_path", route.defaults, name, PATH define_url_helper mod, route, :"#{name}_url", route.defaults, name, FULL end + + def undef_named_route_methods(mod, name) + mod.send :undef_method, :"#{name}_path" + mod.send :undef_method, :"#{name}_url" + end end # :stopdoc: -- cgit v1.2.3 From f889831ed65bea14b6b687bdaa4012d73d81b2a6 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Jul 2014 12:15:04 -0700 Subject: ask the named routes collection if the route is defined we should not be accessing internals to figure out if a method is defined. --- actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++++ actionpack/lib/action_dispatch/testing/assertions/routing.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 14c5d663a3..c2583e2be6 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -94,6 +94,10 @@ module ActionDispatch @module = Module.new end + def route_defined?(name) + @module.method_defined? name + end + def helper_names @helpers.map(&:to_s) end diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index f1f998d932..2cf38a9c2d 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -165,7 +165,7 @@ module ActionDispatch # ROUTES TODO: These assertions should really work in an integration context def method_missing(selector, *args, &block) - if defined?(@controller) && @controller && @routes && @routes.named_routes.helpers.include?(selector) + if defined?(@controller) && @controller && @routes && @routes.named_routes.route_defined?(selector) @controller.send(selector, *args, &block) else super -- cgit v1.2.3 From d7b726be00379a8e03e443425fba05341c6104cd Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Jul 2014 12:15:52 -0700 Subject: oops! :bomb: use helpers.include? so we don't get any false positives --- actionpack/lib/action_dispatch/routing/route_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index c2583e2be6..d869b62398 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -95,7 +95,7 @@ module ActionDispatch end def route_defined?(name) - @module.method_defined? name + @helpers.include? name.to_sym end def helper_names -- cgit v1.2.3 From 4efb36e7b44ae3facb948aa3c5f2790a3fd3b61a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 30 Jul 2014 09:46:08 -0300 Subject: Revert "Merge pull request #15305 from tgxworld/remove_unnecessary_require" This reverts commit f632f79b8dcd144408c66a544984b2ba9cf52f87, reversing changes made to 98c7fe87690ca4de6c46e8f69806e82e3f8af42d. Closes #16343 --- actionpack/lib/action_dispatch/testing/integration.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 12b796b95f..192ccdb9d5 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -3,6 +3,7 @@ require 'uri' require 'active_support/core_ext/kernel/singleton_class' require 'active_support/core_ext/object/try' require 'rack/test' +require 'minitest' module ActionDispatch module Integration #:nodoc: -- cgit v1.2.3 From 2bbcca004cc232cef868cd0e301f274ce5638df0 Mon Sep 17 00:00:00 2001 From: "@schneems and @sgrif" Date: Thu, 19 Jun 2014 17:26:29 -0500 Subject: Deprecate `*_path` methods in mailers Email does not support relative links since there is no implicit host. Therefore all links inside of emails must be fully qualified URLs. All path helpers are now deprecated. When removed, the error will give early indication to developers to use `*_url` methods instead. Currently if a developer uses a `*_path` helper, their tests and `mail_view` will not catch the mistake. The only way to see the error is by sending emails in production. Preventing sending out emails with non-working path's is the desired end goal of this PR. Currently path helpers are mixed-in to controllers (the ActionMailer::Base acts as a controller). All `*_url` and `*_path` helpers are made available through the same module. This PR separates this behavior into two modules so we can extend the `*_path` methods to add a Deprecation to them. Once deprecated we can use this same area to raise a NoMethodError and add an informative message directing the developer to use `*_url` instead. The module with warnings is only mixed in when a controller returns false from the newly added `supports_relative_path?`. Paired @sgrif & @schneems --- .../lib/action_dispatch/routing/route_set.rb | 120 ++++++++++++--------- 1 file changed, 72 insertions(+), 48 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index d869b62398..0906c67719 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -86,12 +86,13 @@ module ActionDispatch # named routes. class NamedRouteCollection #:nodoc: include Enumerable - attr_reader :routes, :helpers, :module + attr_reader :routes, :helpers, :url_helpers_module def initialize @routes = {} @helpers = Set.new - @module = Module.new + @url_helpers_module = Module.new + @path_helpers_module = Module.new end def route_defined?(name) @@ -104,7 +105,11 @@ module ActionDispatch def clear! @helpers.each do |helper| - @module.send :undef_method, helper + if helper =~ /_path$/ + @path_helpers_module.send :undef_method, helper + else + @url_helpers_module.send :undef_method, helper + end end @routes.clear @@ -114,10 +119,12 @@ module ActionDispatch def add(name, route) key = name.to_sym if routes.key? key - undef_named_route_methods @module, name + @path_helpers_module.send :undef_method, :"#{name}_path" + @url_helpers_module.send :undef_method, :"#{name}_url" end routes[key] = route - define_named_route_methods(@module, name, route) + define_url_helper @path_helpers_module, route, :"#{name}_path", route.defaults, name, PATH + define_url_helper @url_helpers_module, route, :"#{name}_url", route.defaults, name, FULL end def get(name) @@ -141,6 +148,26 @@ module ActionDispatch routes.length end + def path_helpers_module(warn = false) + if warn + mod = @path_helpers_module + Module.new do + include mod + + mod.instance_methods(false).each do |meth| + define_method("#{meth}_with_warning") do |*args, &block| + ActiveSupport::Deprecation.warn("The method `#{meth}` cannot be used here as a full URL is required. Use `#{meth.to_s.sub(/_path$/, '_url')}` instead") + send("#{meth}_without_warning", *args, &block) + end + + alias_method_chain meth, :warning + end + end + else + @path_helpers_module + end + end + class UrlHelper # :nodoc: def self.create(route, options, route_name, url_strategy) if optimize_helper?(route) @@ -263,7 +290,7 @@ module ActionDispatch # def define_url_helper(mod, route, name, opts, route_key, url_strategy) helper = UrlHelper.create(route, opts, route_key, url_strategy) - + mod.remove_possible_method name mod.module_eval do define_method(name) do |*args| options = nil @@ -274,16 +301,6 @@ module ActionDispatch helpers << name end - - def define_named_route_methods(mod, name, route) - define_url_helper mod, route, :"#{name}_path", route.defaults, name, PATH - define_url_helper mod, route, :"#{name}_url", route.defaults, name, FULL - end - - def undef_named_route_methods(mod, name) - mod.send :undef_method, :"#{name}_path" - mod.send :undef_method, :"#{name}_url" - end end # :stopdoc: @@ -396,44 +413,51 @@ module ActionDispatch RUBY end - def url_helpers - @url_helpers ||= begin - routes = self - - Module.new do - extend ActiveSupport::Concern - include UrlFor - - # Define url_for in the singleton level so one can do: - # Rails.application.routes.url_helpers.url_for(args) - @_routes = routes - class << self - delegate :url_for, :optimize_routes_generation?, :to => '@_routes' - attr_reader :_routes - def url_options; {}; end - end + def url_helpers(include_path_helpers = true) + routes = self - route_methods = routes.named_routes.module + Module.new do + extend ActiveSupport::Concern + include UrlFor + + # Define url_for in the singleton level so one can do: + # Rails.application.routes.url_helpers.url_for(args) + @_routes = routes + class << self + delegate :url_for, :optimize_routes_generation?, to: '@_routes' + attr_reader :_routes + def url_options; {}; end + end - # Make named_routes available in the module singleton - # as well, so one can do: - # Rails.application.routes.url_helpers.posts_path - extend route_methods + route_methods = routes.named_routes.url_helpers_module - # Any class that includes this module will get all - # named routes... - include route_methods + # Make named_routes available in the module singleton + # as well, so one can do: + # Rails.application.routes.url_helpers.posts_path + extend route_methods - # plus a singleton class method called _routes ... - included do - singleton_class.send(:redefine_method, :_routes) { routes } - end + # Any class that includes this module will get all + # named routes... + include route_methods - # And an instance method _routes. Note that - # UrlFor (included in this module) add extra - # conveniences for working with @_routes. - define_method(:_routes) { @_routes || routes } + if include_path_helpers + path_helpers = routes.named_routes.path_helpers_module + else + path_helpers = routes.named_routes.path_helpers_module(true) end + + include path_helpers + extend path_helpers + + # plus a singleton class method called _routes ... + included do + singleton_class.send(:redefine_method, :_routes) { routes } + end + + # And an instance method _routes. Note that + # UrlFor (included in this module) add extra + # conveniences for working with @_routes. + define_method(:_routes) { @_routes || routes } end end -- cgit v1.2.3 From cf6658c2842d92c7d23928ec6f72074dce345f15 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 14:38:50 -0700 Subject: `add` will remove the method if it exists already --- actionpack/lib/action_dispatch/routing/route_set.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 0906c67719..459097f327 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -290,7 +290,6 @@ module ActionDispatch # def define_url_helper(mod, route, name, opts, route_key, url_strategy) helper = UrlHelper.create(route, opts, route_key, url_strategy) - mod.remove_possible_method name mod.module_eval do define_method(name) do |*args| options = nil -- cgit v1.2.3 From 210b338db20b1cdd0684f40bd78b52ed16148b99 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 14:46:07 -0700 Subject: split path_helpers and url_helpers this lets us avoid hard coding a regexp for separating path and url helpers in the clear! method. --- .../lib/action_dispatch/routing/route_set.rb | 43 +++++++++++++--------- 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 459097f327..42d6ee40db 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -86,45 +86,54 @@ module ActionDispatch # named routes. class NamedRouteCollection #:nodoc: include Enumerable - attr_reader :routes, :helpers, :url_helpers_module + attr_reader :routes, :url_helpers_module def initialize @routes = {} - @helpers = Set.new + @path_helpers = Set.new + @url_helpers = Set.new @url_helpers_module = Module.new @path_helpers_module = Module.new end def route_defined?(name) - @helpers.include? name.to_sym + key = name.to_sym + @path_helpers.include?(key) || @url_helpers.include?(key) end def helper_names - @helpers.map(&:to_s) + @path_helpers.map(&:to_s) + @url_helpers.map(&:to_s) end def clear! - @helpers.each do |helper| - if helper =~ /_path$/ - @path_helpers_module.send :undef_method, helper - else - @url_helpers_module.send :undef_method, helper - end + @path_helpers.each do |helper| + @path_helpers_module.send :undef_method, helper + end + + @url_helpers.each do |helper| + @url_helpers_module.send :undef_method, helper end @routes.clear - @helpers.clear + @path_helpers.clear + @url_helpers.clear end def add(name, route) - key = name.to_sym + key = name.to_sym + path_name = :"#{name}_path" + url_name = :"#{name}_url" + if routes.key? key - @path_helpers_module.send :undef_method, :"#{name}_path" - @url_helpers_module.send :undef_method, :"#{name}_url" + @path_helpers_module.send :undef_method, path_name + @url_helpers_module.send :undef_method, url_name end routes[key] = route - define_url_helper @path_helpers_module, route, :"#{name}_path", route.defaults, name, PATH - define_url_helper @url_helpers_module, route, :"#{name}_url", route.defaults, name, FULL + define_url_helper @path_helpers_module, route, path_name, route.defaults, name, PATH + define_url_helper @url_helpers_module, route, url_name, route.defaults, name, FULL + + @path_helpers << path_name + @url_helpers << url_name end def get(name) @@ -297,8 +306,6 @@ module ActionDispatch helper.call self, args, options end end - - helpers << name end end -- cgit v1.2.3 From d9108abcad66412f9e8604479cdcc7795a3262b1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 14:46:45 -0700 Subject: fix variable name --- actionpack/lib/action_dispatch/routing/route_set.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 42d6ee40db..444c36a72b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -435,16 +435,16 @@ module ActionDispatch def url_options; {}; end end - route_methods = routes.named_routes.url_helpers_module + url_helpers = routes.named_routes.url_helpers_module # Make named_routes available in the module singleton # as well, so one can do: # Rails.application.routes.url_helpers.posts_path - extend route_methods + extend url_helpers # Any class that includes this module will get all # named routes... - include route_methods + include url_helpers if include_path_helpers path_helpers = routes.named_routes.path_helpers_module -- cgit v1.2.3 From 09603275e9f57ca133bd92557c1213cdfa02cff8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 14:51:28 -0700 Subject: avoid instrospection on the module we already know what helpers are path helpers, so just iterate through that list and define the helpers with warnings --- actionpack/lib/action_dispatch/routing/route_set.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 444c36a72b..6e8016d360 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -160,10 +160,11 @@ module ActionDispatch def path_helpers_module(warn = false) if warn mod = @path_helpers_module + helpers = @path_helpers Module.new do include mod - mod.instance_methods(false).each do |meth| + helpers.each do |meth| define_method("#{meth}_with_warning") do |*args, &block| ActiveSupport::Deprecation.warn("The method `#{meth}` cannot be used here as a full URL is required. Use `#{meth.to_s.sub(/_path$/, '_url')}` instead") send("#{meth}_without_warning", *args, &block) -- cgit v1.2.3 From 68aea29cf5e5b856fdfa0b3087bf68cbd6310bd6 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 14:53:28 -0700 Subject: remove alias_method_chain we can `super` in to the previous implementation. --- actionpack/lib/action_dispatch/routing/route_set.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 6e8016d360..4155efa03c 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -165,12 +165,10 @@ module ActionDispatch include mod helpers.each do |meth| - define_method("#{meth}_with_warning") do |*args, &block| + define_method(meth) do |*args, &block| ActiveSupport::Deprecation.warn("The method `#{meth}` cannot be used here as a full URL is required. Use `#{meth.to_s.sub(/_path$/, '_url')}` instead") - send("#{meth}_without_warning", *args, &block) + super(*args, &block) end - - alias_method_chain meth, :warning end end else -- cgit v1.2.3 From dc3f25c8a5aa64de9225f11498a389a2d31e880a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 17:19:00 -0700 Subject: turn scope in to a linked list this makes scope rollback much easier --- actionpack/lib/action_dispatch/routing/mapper.rb | 51 +++++++++++++++++------- 1 file changed, 36 insertions(+), 15 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 95f5f45abe..1ffe16999d 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -771,7 +771,7 @@ module ActionDispatch # end def scope(*args) options = args.extract_options!.dup - recover = {} + scope = {} options[:path] = args.flatten.join('/') if args.any? options[:constraints] ||= {} @@ -801,15 +801,15 @@ module ActionDispatch end if value - recover[option] = @scope[option] - @scope[option] = send("merge_#{option}_scope", @scope[option], value) + scope[option] = send("merge_#{option}_scope", @scope[option], value) end end + @scope = @scope.new scope yield self ensure - @scope.merge!(recover) + @scope = @scope.parent end # Scopes routes to a specific controller @@ -1645,27 +1645,26 @@ module ActionDispatch def with_exclusive_scope begin - old_name_prefix, old_path = @scope[:as], @scope[:path] - @scope[:as], @scope[:path] = nil, nil + @scope = @scope.new(:as => nil, :path => nil) with_scope_level(:exclusive) do yield end ensure - @scope[:as], @scope[:path] = old_name_prefix, old_path + @scope = @scope.parent end end def with_scope_level(kind) - old, @scope[:scope_level] = @scope[:scope_level], kind + @scope = @scope.new(:scope_level => kind) yield ensure - @scope[:scope_level] = old + @scope = @scope.parent end def resource_scope(kind, resource) #:nodoc: resource.shallow = @scope[:shallow] - old_resource, @scope[:scope_level_resource] = @scope[:scope_level_resource], resource + @scope = @scope.new(:scope_level_resource => resource) @nesting.push(resource) with_scope_level(kind) do @@ -1673,7 +1672,7 @@ module ActionDispatch end ensure @nesting.pop - @scope[:scope_level_resource] = old_resource + @scope = @scope.parent end def nested_options #:nodoc: @@ -1706,12 +1705,13 @@ module ActionDispatch end def shallow_scope(path, options = {}) #:nodoc: - old_name_prefix, old_path = @scope[:as], @scope[:path] - @scope[:as], @scope[:path] = @scope[:shallow_prefix], @scope[:shallow_path] + scope = { :as => @scope[:shallow_prefix], + :path => @scope[:shallow_path] } + @scope = @scope.new scope scope(path, options) { yield } ensure - @scope[:as], @scope[:path] = old_name_prefix, old_path + @scope = @scope.parent end def path_for_action(action, path) #:nodoc: @@ -1893,9 +1893,30 @@ module ActionDispatch end end + class Scope # :nodoc: + attr_reader :parent + + def initialize(hash, parent = {}) + @hash = hash + @parent = parent + end + + def new(hash) + self.class.new hash, self + end + + def [](key) + @hash.fetch(key) { @parent[key] } + end + + def []=(k,v) + @hash[k] = v + end + end + def initialize(set) #:nodoc: @set = set - @scope = { :path_names => @set.resources_path_names } + @scope = Scope.new({ :path_names => @set.resources_path_names }) @concerns = {} @nesting = [] end -- cgit v1.2.3 From 20ec0d2aaee0878f819c1d2278e078b1039aee3e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 17:20:37 -0700 Subject: push options inside the scope object --- actionpack/lib/action_dispatch/routing/mapper.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 1ffe16999d..6f7e6f3128 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -13,9 +13,6 @@ module ActionDispatch module Routing class Mapper URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port] - SCOPE_OPTIONS = [:path, :shallow_path, :as, :shallow_prefix, :module, - :controller, :action, :path_names, :constraints, - :shallow, :blocks, :defaults, :options] class Constraints < Endpoint #:nodoc: attr_reader :app, :constraints @@ -791,7 +788,7 @@ module ActionDispatch block, options[:constraints] = options[:constraints], {} end - SCOPE_OPTIONS.each do |option| + @scope.options.each do |option| if option == :blocks value = block elsif option == :options @@ -1894,6 +1891,10 @@ module ActionDispatch end class Scope # :nodoc: + OPTIONS = [:path, :shallow_path, :as, :shallow_prefix, :module, + :controller, :action, :path_names, :constraints, + :shallow, :blocks, :defaults, :options] + attr_reader :parent def initialize(hash, parent = {}) @@ -1901,6 +1902,10 @@ module ActionDispatch @parent = parent end + def options + OPTIONS + end + def new(hash) self.class.new hash, self end -- cgit v1.2.3 From 3429b0ccba036d09d1e6357e559be05efe3da969 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 30 Jul 2014 18:11:24 -0700 Subject: remove useless deup every call to default_resources_path_names allocates a new hash, no need to dup --- actionpack/lib/action_dispatch/routing/route_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 4155efa03c..96e23c2464 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -327,7 +327,7 @@ module ActionDispatch def initialize(request_class = ActionDispatch::Request) self.named_routes = NamedRouteCollection.new - self.resources_path_names = self.class.default_resources_path_names.dup + self.resources_path_names = self.class.default_resources_path_names self.default_url_options = {} self.request_class = request_class -- cgit v1.2.3 From 8d61463f34fd0bb7bad446f2d43aaa63fee61563 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 31 Jul 2014 13:05:56 -0300 Subject: Push options check up so we can simplify internal methods --- actionpack/lib/action_dispatch/http/url.rb | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 473f692b05..32234d18ab 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -51,28 +51,25 @@ module ActionDispatch def path_for(options) result = options[:script_name].to_s.chomp("/") result << options[:path].to_s - result = add_trailing_slash(result) if options[:trailing_slash] - - result = add_params options, result - add_anchor options, result + result = add_params(result, options[:params]) if options.key?(:params) + result = add_anchor(result, options[:anchor]) if options.key?(:anchor) + result end private - def add_params(options, result) - if options.key? :params - param = options[:params] - params = param.is_a?(Hash) ? param : { params: param } + def add_params(result, param) + params = param.is_a?(Hash) ? param : { params: param } + + params.reject! { |_,v| v.to_param.nil? } + result << "?#{params.to_query}" unless params.empty? - params.reject! { |_,v| v.to_param.nil? } - result << "?#{params.to_query}" unless params.empty? - end result end - def add_anchor(options, result) - result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor] + def add_anchor(result, anchor) + result << "##{Journey::Router::Utils.escape_fragment(anchor.to_param.to_s)}" result end -- cgit v1.2.3 From 277247110cb77e69ea113a3aa77a9c12322ffcfb Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 31 Jul 2014 13:08:58 -0300 Subject: Simplify conditional --- actionpack/lib/action_dispatch/http/url.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 32234d18ab..12d3b10981 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -59,9 +59,8 @@ module ActionDispatch private - def add_params(result, param) - params = param.is_a?(Hash) ? param : { params: param } - + def add_params(result, params) + params = { params: params } unless params.is_a?(Hash) params.reject! { |_,v| v.to_param.nil? } result << "?#{params.to_query}" unless params.empty? -- cgit v1.2.3 From fafff357cc775dab2cc46feaf43d311a7a042283 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 31 Jul 2014 13:09:32 -0300 Subject: Rename variable to better show its intent --- actionpack/lib/action_dispatch/http/url.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 12d3b10981..ef07a101ad 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -49,27 +49,27 @@ module ActionDispatch end def path_for(options) - result = options[:script_name].to_s.chomp("/") - result << options[:path].to_s - result = add_trailing_slash(result) if options[:trailing_slash] - result = add_params(result, options[:params]) if options.key?(:params) - result = add_anchor(result, options[:anchor]) if options.key?(:anchor) - result + path = options[:script_name].to_s.chomp("/") + path << options[:path].to_s + path = add_trailing_slash(path) if options[:trailing_slash] + path = add_params(path, options[:params]) if options.key?(:params) + path = add_anchor(path, options[:anchor]) if options.key?(:anchor) + path end private - def add_params(result, params) + def add_params(path, params) params = { params: params } unless params.is_a?(Hash) params.reject! { |_,v| v.to_param.nil? } - result << "?#{params.to_query}" unless params.empty? + path << "?#{params.to_query}" unless params.empty? - result + path end - def add_anchor(result, anchor) - result << "##{Journey::Router::Utils.escape_fragment(anchor.to_param.to_s)}" - result + def add_anchor(path, anchor) + path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param.to_s)}" + path end def extract_domain_from(host, tld_length) -- cgit v1.2.3 From 091a59301f65601b47c7022ac5028b7f6b569e00 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 31 Jul 2014 13:12:04 -0300 Subject: Only concatenate path if it was given rather than converting blindly --- actionpack/lib/action_dispatch/http/url.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index ef07a101ad..55baba88e4 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -50,7 +50,7 @@ module ActionDispatch def path_for(options) path = options[:script_name].to_s.chomp("/") - path << options[:path].to_s + path << options[:path] if options.key?(:path) path = add_trailing_slash(path) if options[:trailing_slash] path = add_params(path, options[:params]) if options.key?(:params) path = add_anchor(path, options[:anchor]) if options.key?(:anchor) -- cgit v1.2.3 From 0b859dfefe4f267eb86fa6194fa556caae5cb44c Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 31 Jul 2014 13:14:14 -0300 Subject: Do not reassign variable when mutation is happening These methods mutate the path variable/argument so there is no need to reassign it every time. --- actionpack/lib/action_dispatch/http/url.rb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 55baba88e4..a7dbceed67 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -51,9 +51,11 @@ module ActionDispatch def path_for(options) path = options[:script_name].to_s.chomp("/") path << options[:path] if options.key?(:path) - path = add_trailing_slash(path) if options[:trailing_slash] - path = add_params(path, options[:params]) if options.key?(:params) - path = add_anchor(path, options[:anchor]) if options.key?(:anchor) + + add_trailing_slash(path) if options[:trailing_slash] + add_params(path, options[:params]) if options.key?(:params) + add_anchor(path, options[:anchor]) if options.key?(:anchor) + path end @@ -63,13 +65,10 @@ module ActionDispatch params = { params: params } unless params.is_a?(Hash) params.reject! { |_,v| v.to_param.nil? } path << "?#{params.to_query}" unless params.empty? - - path end def add_anchor(path, anchor) path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param.to_s)}" - path end def extract_domain_from(host, tld_length) @@ -89,8 +88,6 @@ module ActionDispatch elsif !path.include?(".") path.sub!(/[^\/]\z|\A\z/, '\&/') end - - path end def build_host_url(host, port, protocol, options, path) -- cgit v1.2.3 From ddb0d4bec16aea562dd155577d891e83fa066410 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 31 Jul 2014 13:18:51 -0300 Subject: Realign assignments :scissors: --- actionpack/lib/action_dispatch/http/url.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index a7dbceed67..6b8dcaf497 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -92,13 +92,13 @@ module ActionDispatch def build_host_url(host, port, protocol, options, path) if match = host.match(HOST_REGEXP) - protocol ||= match[1] unless protocol == false - host = match[2] - port = match[3] unless options.key? :port + protocol ||= match[1] unless protocol == false + host = match[2] + port = match[3] unless options.key? :port end - protocol = normalize_protocol protocol - host = normalize_host(host, options) + protocol = normalize_protocol protocol + host = normalize_host(host, options) result = protocol.dup -- cgit v1.2.3 From 3e9158bb95de1770c5a529a903fe15b19a473439 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 31 Jul 2014 11:21:53 -0700 Subject: do a hash lookup for collision detection hash lookup should be faster than searching an array. --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 6f7e6f3128..0e8badc498 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1765,7 +1765,7 @@ module ActionDispatch # and return nil in case it isn't. Otherwise, we pass the invalid name # forward so the underlying router engine treats it and raises an exception. if as.nil? - candidate unless @set.routes.find { |r| r.name == candidate } || candidate !~ /\A[_a-z]/i + candidate unless @set.named_routes.key?(candidate) || candidate !~ /\A[_a-z]/i else candidate end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 96e23c2464..518d4ca09c 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -140,6 +140,10 @@ module ActionDispatch routes[name.to_sym] end + def key?(name) + routes.key? name.to_sym + end + alias []= add alias [] get alias clear clear! -- cgit v1.2.3 From ed9b23d8986a2d4025913e7c56f353a579ab0189 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 31 Jul 2014 11:25:01 -0700 Subject: invert check so we fail faster there's no reason to to_sym the string if it doesn't match the regexp anyway --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 0e8badc498..5982dc862c 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1765,7 +1765,7 @@ module ActionDispatch # and return nil in case it isn't. Otherwise, we pass the invalid name # forward so the underlying router engine treats it and raises an exception. if as.nil? - candidate unless @set.named_routes.key?(candidate) || candidate !~ /\A[_a-z]/i + candidate unless candidate !~ /\A[_a-z]/i || @set.named_routes.key?(candidate) else candidate end -- cgit v1.2.3 From e9bbe4a106afc9dd42464007f9fba3b54772bae0 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 31 Jul 2014 15:26:42 -0700 Subject: use `get` instead of accessing the named routes internals --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 5982dc862c..37be34abf8 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -614,7 +614,7 @@ module ActionDispatch end def define_generate_prefix(app, name) - _route = @set.named_routes.routes[name.to_sym] + _route = @set.named_routes.get name _routes = @set app.routes.define_mounted_helper(name) app.routes.extend Module.new { -- cgit v1.2.3 From 8cbcd19d7079db1b5df6ddb3b813fea57cd5cc38 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 1 Aug 2014 11:45:52 -0700 Subject: always return a string from find_script_name this allows us to avoid nil checks on the return value --- actionpack/lib/action_dispatch/routing/mapper.rb | 12 +++++++----- actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 37be34abf8..cd94f35e8f 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -620,11 +620,13 @@ module ActionDispatch app.routes.extend Module.new { def optimize_routes_generation?; false; end define_method :find_script_name do |options| - super(options) || begin - prefix_options = options.slice(*_route.segment_keys) - # we must actually delete prefix segment keys to avoid passing them to next url_for - _route.segment_keys.each { |k| options.delete(k) } - _routes.url_helpers.send("#{name}_path", prefix_options) + if options.key? :script_name + super(options) + else + prefix_options = options.slice(*_route.segment_keys) + # we must actually delete prefix segment keys to avoid passing them to next url_for + _route.segment_keys.each { |k| options.delete(k) } + _routes.url_helpers.send("#{name}_path", prefix_options) end end } diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 518d4ca09c..ce1fe2e451 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -694,7 +694,7 @@ module ActionDispatch end def find_script_name(options) - options.delete :script_name + options.delete(:script_name) { '' } end # The +options+ argument must be a hash whose keys are *symbols*. @@ -713,7 +713,7 @@ module ActionDispatch original_script_name = options.delete(:original_script_name) script_name = find_script_name options - if script_name && original_script_name + if original_script_name script_name = original_script_name + script_name end -- cgit v1.2.3 From 0b8f35dd9ca6d1ae72e6021e64688e2d88b84537 Mon Sep 17 00:00:00 2001 From: Jack Danger Canty Date: Sun, 3 Aug 2014 15:23:56 -0700 Subject: Using no_result_var in Journey's parser generator Previously the generated parser had an intermediate local variable `result` that really useful if you're building up a stateful object but Journey always discards the result argument to the reduce functions. This produces a simpler parser for anybody who actually wants to read the thing. Sadly, there's no real performance speedup with this change. --- actionpack/lib/action_dispatch/journey/parser.rb | 54 ++++++++++-------------- actionpack/lib/action_dispatch/journey/parser.y | 22 +++++----- 2 files changed, 33 insertions(+), 43 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/journey/parser.rb b/actionpack/lib/action_dispatch/journey/parser.rb index d129ba7e16..9012297400 100644 --- a/actionpack/lib/action_dispatch/journey/parser.rb +++ b/actionpack/lib/action_dispatch/journey/parser.rb @@ -86,7 +86,7 @@ racc_token_table = { racc_nt_base = 10 -racc_use_result_var = true +racc_use_result_var = false Racc_arg = [ racc_action_table, @@ -133,14 +133,12 @@ Racc_debug_parser = false # reduce 0 omitted -def _reduce_1(val, _values, result) - result = Cat.new(val.first, val.last) - result +def _reduce_1(val, _values) + Cat.new(val.first, val.last) end -def _reduce_2(val, _values, result) - result = val.first - result +def _reduce_2(val, _values) + val.first end # reduce 3 omitted @@ -151,24 +149,20 @@ end # reduce 6 omitted -def _reduce_7(val, _values, result) - result = Group.new(val[1]) - result +def _reduce_7(val, _values) + Group.new(val[1]) end -def _reduce_8(val, _values, result) - result = Or.new([val.first, val.last]) - result +def _reduce_8(val, _values) + Or.new([val.first, val.last]) end -def _reduce_9(val, _values, result) - result = Or.new([val.first, val.last]) - result +def _reduce_9(val, _values) + Or.new([val.first, val.last]) end -def _reduce_10(val, _values, result) - result = Star.new(Symbol.new(val.last)) - result +def _reduce_10(val, _values) + Star.new(Symbol.new(val.last)) end # reduce 11 omitted @@ -179,27 +173,23 @@ end # reduce 14 omitted -def _reduce_15(val, _values, result) - result = Slash.new('/') - result +def _reduce_15(val, _values) + Slash.new('/') end -def _reduce_16(val, _values, result) - result = Symbol.new(val.first) - result +def _reduce_16(val, _values) + Symbol.new(val.first) end -def _reduce_17(val, _values, result) - result = Literal.new(val.first) - result +def _reduce_17(val, _values) + Literal.new(val.first) end -def _reduce_18(val, _values, result) - result = Dot.new(val.first) - result +def _reduce_18(val, _values) + Dot.new(val.first) end -def _reduce_none(val, _values, result) +def _reduce_none(val, _values) val[0] end diff --git a/actionpack/lib/action_dispatch/journey/parser.y b/actionpack/lib/action_dispatch/journey/parser.y index 0ead222551..d3f7c4d765 100644 --- a/actionpack/lib/action_dispatch/journey/parser.y +++ b/actionpack/lib/action_dispatch/journey/parser.y @@ -1,11 +1,11 @@ class ActionDispatch::Journey::Parser - + options no_result_var token SLASH LITERAL SYMBOL LPAREN RPAREN DOT STAR OR rule expressions - : expression expressions { result = Cat.new(val.first, val.last) } - | expression { result = val.first } + : expression expressions { Cat.new(val.first, val.last) } + | expression { val.first } | or ; expression @@ -14,14 +14,14 @@ rule | star ; group - : LPAREN expressions RPAREN { result = Group.new(val[1]) } + : LPAREN expressions RPAREN { Group.new(val[1]) } ; or - : expression OR expression { result = Or.new([val.first, val.last]) } - | expression OR or { result = Or.new([val.first, val.last]) } + : expression OR expression { Or.new([val.first, val.last]) } + | expression OR or { Or.new([val.first, val.last]) } ; star - : STAR { result = Star.new(Symbol.new(val.last)) } + : STAR { Star.new(Symbol.new(val.last)) } ; terminal : symbol @@ -30,16 +30,16 @@ rule | dot ; slash - : SLASH { result = Slash.new('/') } + : SLASH { Slash.new('/') } ; symbol - : SYMBOL { result = Symbol.new(val.first) } + : SYMBOL { Symbol.new(val.first) } ; literal - : LITERAL { result = Literal.new(val.first) } + : LITERAL { Literal.new(val.first) } ; dot - : DOT { result = Dot.new(val.first) } + : DOT { Dot.new(val.first) } ; end -- cgit v1.2.3 From 930110b0452bd33e0ee54e9ec6d68e904ba7a0ad Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 9 Jul 2014 21:49:37 -0300 Subject: Regenerate sid when sbdy tries to fixate the session Fixed broken test. Thanks Stephen Richards for reporting. --- actionpack/lib/action_dispatch/middleware/session/cache_store.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/middleware/session/cache_store.rb b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb index 1db6194271..625050dc4b 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cache_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb @@ -16,9 +16,9 @@ module ActionDispatch # Get a session from the cache. def get_session(env, sid) - sid ||= generate_sid - session = @cache.read(cache_key(sid)) - session ||= {} + unless sid and session = @cache.read(cache_key(sid)) + sid, session = generate_sid, {} + end [sid, session] end -- cgit v1.2.3 From 3300fdedc748993b378288c6cbc3113885c955ed Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 4 Aug 2014 18:20:07 -0700 Subject: avoid testing only_path we know that this call only wants the path returned, so lets call a method that returns the path. --- actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index ce1fe2e451..5b3651aaee 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -697,6 +697,10 @@ module ActionDispatch options.delete(:script_name) { '' } end + def path_for(options, route_name = nil) # :nodoc: + url_for(options, route_name, PATH) + end + # The +options+ argument must be a hash whose keys are *symbols*. def url_for(options, route_name = nil, url_strategy = UNKNOWN) options = default_url_options.merge options -- cgit v1.2.3 From 2090615d39c071c9eb25e715275eb79f3f9b6266 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 6 Aug 2014 14:17:57 -0700 Subject: refactor Redirecting so we do not need a controller instance --- actionpack/lib/action_dispatch/testing/assertions/response.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index 0adc6c84ff..13a72220b3 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -73,13 +73,8 @@ module ActionDispatch if Regexp === fragment fragment else - handle = @controller || Class.new(ActionController::Metal) do - include ActionController::Redirecting - def initialize(request) - @_request = request - end - end.new(@request) - handle._compute_redirect_to_location(fragment) + handle = @controller || ActionController::Redirecting + handle._compute_redirect_to_location(@request, fragment) end end end -- cgit v1.2.3 From 1ed264bc60f3c76ba7fab339806fa1757702a46b Mon Sep 17 00:00:00 2001 From: Ryan Dao Date: Wed, 30 Jul 2014 15:35:47 +0700 Subject: Retrieve source code for the entire stack trace Provide the ability to extract the source code of the entire exception stack trace, not just the frame raising the error. This improves debugging capability of the error page, especially for framework-related errors. --- .../action_dispatch/middleware/debug_exceptions.rb | 35 +++++++++++++++-- .../middleware/exception_wrapper.rb | 17 +++++---- .../middleware/templates/rescues/_source.erb | 40 +++++++++++--------- .../middleware/templates/rescues/_trace.html.erb | 44 ++++++++++++++++++---- .../middleware/templates/rescues/_trace.text.erb | 10 +---- .../middleware/templates/rescues/layout.erb | 6 +++ .../templates/rescues/template_error.html.erb | 25 +----------- .../templates/rescues/template_error.text.erb | 1 - 8 files changed, 109 insertions(+), 69 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb index 0ca1a87645..274f6f2f22 100644 --- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -38,9 +38,7 @@ module ActionDispatch template = ActionView::Base.new([RESCUES_TEMPLATE_PATH], request: request, exception: wrapper.exception, - application_trace: wrapper.application_trace, - framework_trace: wrapper.framework_trace, - full_trace: wrapper.full_trace, + traces: traces_from_wrapper(wrapper), routes_inspector: routes_inspector(exception), source_extract: wrapper.source_extract, line_number: wrapper.line_number, @@ -95,5 +93,36 @@ module ActionDispatch ActionDispatch::Routing::RoutesInspector.new(@routes_app.routes.routes) end end + + # Augment the exception traces by providing ids for all unique stack frame + def traces_from_wrapper(wrapper) + application_trace = wrapper.application_trace + framework_trace = wrapper.framework_trace + full_trace = wrapper.full_trace + + if application_trace && framework_trace + id_counter = 0 + + application_trace = application_trace.map do |trace| + prev = id_counter + id_counter += 1 + { id: prev, trace: trace } + end + + framework_trace = framework_trace.map do |trace| + prev = id_counter + id_counter += 1 + { id: prev, trace: trace } + end + + full_trace = application_trace + framework_trace + end + + { + "Application Trace" => application_trace, + "Framework Trace" => framework_trace, + "Full Trace" => full_trace + } + end end end diff --git a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb index 2326bb043a..b98b553c38 100644 --- a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb +++ b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb @@ -61,12 +61,15 @@ module ActionDispatch end def source_extract - if application_trace && trace = application_trace.first - file, line, _ = trace.split(":") - @file = file - @line_number = line.to_i - source_fragment(@file, @line_number) - end + exception.backtrace.map do |trace| + file, line = trace.split(":") + line_number = line.to_i + { + code: source_fragment(file, line_number), + file: file, + line_number: line_number + } + end if exception.backtrace end private @@ -110,7 +113,7 @@ module ActionDispatch def expand_backtrace @exception.backtrace.unshift( @exception.to_s.split("\n") - ).flatten! + ).flatten! end end end diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_source.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_source.erb index 38429cb78e..51660a619b 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_source.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_source.erb @@ -1,25 +1,29 @@ <% if @source_extract %> -
-
- Extracted source (around line #<%= @line_number %>): -
-
- - - +
-
-            <% @source_extract.keys.each do |line_number| %>
+  <% @source_extract.each_with_index do |extract_source, index| %>
+    <% if extract_source[:code] %>
+      
" id="frame-source-<%=index%>"> +
+ Extracted source (around line #<%= extract_source[:line_number] %>): +
+
+ + + + <% end %> + + - -
+
+                  <% extract_source[:code].keys.each do |line_number| %>
 <%= line_number -%>
-            <% end %>
-          
-
-<% @source_extract.each do |line, source| -%>
"><%= source -%>
<% end -%> +<% extract_source[:code].each do |line, source| -%>
"><%= source -%>
<% end -%>
-
-
+
+
+
+ <% end %> + <% end %> <% end %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb index b181909bff..f62caf51d7 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb @@ -1,9 +1,4 @@ -<% - traces = { "Application Trace" => @application_trace, - "Framework Trace" => @framework_trace, - "Full Trace" => @full_trace } - names = traces.keys -%> +<% names = @traces.keys %>

Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %>

@@ -16,9 +11,42 @@ <%= name %> <%= '|' unless names.last == name %> <% end %> - <% traces.each do |name, trace| %> + <% @traces.each do |name, trace| %>
;"> -
<%= trace.join "\n" %>
+
<% trace.each do |frame| %><%= frame[:trace] %>
<% end %>
<% end %> + + diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb index d4af5c9b06..36b01bf952 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb @@ -1,15 +1,9 @@ -<% - 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| %> +<% @traces.each do |name, trace| %> <% if trace.any? %> <%= name %> -<%= trace.join("\n") %> +<%= trace.map(&:trace).join("\n") %> <% 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 bc5d03dc10..e0509f56f4 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb @@ -116,9 +116,15 @@ background-color: #FFCCCC; } + .hidden { + display: none; + } + a { color: #980905; } a:visited { color: #666; } + a.trace-frames { color: #666; } a:hover { color: #C52F24; } + a.trace-frames.selected { color: #C52F24 } <%= yield :style %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb index 027a0f5b3e..c1e8b6cae3 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb @@ -1,4 +1,3 @@ -<% @source_extract = @exception.source_extract(0, :html) %>

<%= @exception.original_exception.class.to_s %> in @@ -12,29 +11,7 @@

<%= h @exception.message %>
-
-
-

Extracted source (around line #<%= @exception.line_number %>):

-
-
- - - - - -
-
-            <% @source_extract.keys.each do |line_number| %>
-<%= line_number -%>
-            <% end %>
-          
-
-
-<% @source_extract.each do |line, source| -%>
"><%= source -%>
<% end -%> -
-
-
-
+ <%= render template: "rescues/_source" %>

<%= @exception.sub_template_message %>

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 index 5da21d9784..77bcd26726 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb @@ -1,4 +1,3 @@ -<% @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: -- cgit v1.2.3 From cfbedd3479d5021b9fb862ecfa49fc6bc8602994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Strza=C5=82kowski?= Date: Fri, 8 Aug 2014 21:18:30 +0200 Subject: Add config option for cookies digest You can now configure custom digest for cookies in the same way as `serializer`: config.action_dispatch.cookies_digest = \SHA256' --- actionpack/lib/action_dispatch/middleware/cookies.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index ac9e5effe2..55bb9de173 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -90,6 +90,7 @@ module ActionDispatch SECRET_TOKEN = "action_dispatch.secret_token".freeze SECRET_KEY_BASE = "action_dispatch.secret_key_base".freeze COOKIES_SERIALIZER = "action_dispatch.cookies_serializer".freeze + COOKIES_DIGEST = "action_dispatch.cookies_digest".freeze # Cookies can typically store 4096 bytes. MAX_COOKIE_SIZE = 4096 @@ -212,7 +213,8 @@ module ActionDispatch secret_token: env[SECRET_TOKEN], secret_key_base: env[SECRET_KEY_BASE], upgrade_legacy_signed_cookies: env[SECRET_TOKEN].present? && env[SECRET_KEY_BASE].present?, - serializer: env[COOKIES_SERIALIZER] + serializer: env[COOKIES_SERIALIZER], + digest: env[COOKIES_DIGEST] } end @@ -441,6 +443,10 @@ module ActionDispatch serializer end end + + def digest + @options[:digest] || 'SHA1' + end end class SignedCookieJar #:nodoc: @@ -451,7 +457,7 @@ module ActionDispatch @parent_jar = parent_jar @options = options secret = key_generator.generate_key(@options[:signed_cookie_salt]) - @verifier = ActiveSupport::MessageVerifier.new(secret, serializer: NullSerializer) + @verifier = ActiveSupport::MessageVerifier.new(secret, digest: digest, serializer: NullSerializer) end def [](name) -- cgit v1.2.3 From d70ba48c4dd6b57d8f38612ea95a3842337c1419 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 8 Aug 2014 18:20:17 -0300 Subject: Revert "Merge pull request #16434 from strzalek/cookies-digest-config-option" This reverts commit 705977620539e2be6548027042f33175ebdc2505, reversing changes made to dde91e9bf5ab246f0f684b40288b272f4ba9a699. IT BROKE THE BUILD!!! --- actionpack/lib/action_dispatch/middleware/cookies.rb | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 55bb9de173..ac9e5effe2 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -90,7 +90,6 @@ module ActionDispatch SECRET_TOKEN = "action_dispatch.secret_token".freeze SECRET_KEY_BASE = "action_dispatch.secret_key_base".freeze COOKIES_SERIALIZER = "action_dispatch.cookies_serializer".freeze - COOKIES_DIGEST = "action_dispatch.cookies_digest".freeze # Cookies can typically store 4096 bytes. MAX_COOKIE_SIZE = 4096 @@ -213,8 +212,7 @@ module ActionDispatch secret_token: env[SECRET_TOKEN], secret_key_base: env[SECRET_KEY_BASE], upgrade_legacy_signed_cookies: env[SECRET_TOKEN].present? && env[SECRET_KEY_BASE].present?, - serializer: env[COOKIES_SERIALIZER], - digest: env[COOKIES_DIGEST] + serializer: env[COOKIES_SERIALIZER] } end @@ -443,10 +441,6 @@ module ActionDispatch serializer end end - - def digest - @options[:digest] || 'SHA1' - end end class SignedCookieJar #:nodoc: @@ -457,7 +451,7 @@ module ActionDispatch @parent_jar = parent_jar @options = options secret = key_generator.generate_key(@options[:signed_cookie_salt]) - @verifier = ActiveSupport::MessageVerifier.new(secret, digest: digest, serializer: NullSerializer) + @verifier = ActiveSupport::MessageVerifier.new(secret, serializer: NullSerializer) end def [](name) -- cgit v1.2.3 From 51a759a745b065b335a0c8f49439118ac8e04586 Mon Sep 17 00:00:00 2001 From: Akshay Vishnoi Date: Tue, 12 Aug 2014 18:40:14 +0530 Subject: use 'based on' instead of 'based off' [ci skip] --- actionpack/lib/action_dispatch/http/request.rb | 2 +- actionpack/lib/action_dispatch/middleware/request_id.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_dispatch') diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index a519d6c1fc..8c035c3c6c 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -225,7 +225,7 @@ module ActionDispatch @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s end - # Returns the unique request id, which is based off either the X-Request-Id header that can + # Returns the unique request id, which is based on either the X-Request-Id header that can # be generated by a firewall, load balancer, or web server or by the RequestId middleware # (which sets the action_dispatch.request_id environment variable). # diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index 5d1740d0d4..25658bac3d 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -5,7 +5,7 @@ module ActionDispatch # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through # ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header. # - # The unique request id is either based off the X-Request-Id header in the request, which would typically be generated + # The unique request id is either based on the X-Request-Id header in the request, which would typically be generated # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only. # -- cgit v1.2.3