Permalink
Browse files

Fix improperly configured host

If the host in default_url_options is accidentally set with a protocol such as `:host => "http://example.com"` then the generated url will have the protocol twice `http://http://example.com` which is not what the user intended. Likely they wanted to define a host `:host => "example.com"` and a `:protocol => "http://"` but did not know the convention.

This is may not the most common problem, but when it happens it can go undetected for a while. I accidentally added `http://` out of habit recently only to find all the links in my emails were broken after deploying a demo site to production. Rather than allow this accident go undetected, we can fix the problem in line by properly setting the protocol and host.


I was able to find this related question on stack overflow: http://stackoverflow.com/questions/5878329/rails-3-devise-how-do-i-make-the-email-confirmation-links-use-secure-https-n
 where the answer was highly upvoted. 

ATP Action Mailer, Actionpack, and Railties
  • Loading branch information...
1 parent 2e299fc commit 759335b76b50cd8451875019a4441a36843a51fc @schneems committed Aug 21, 2012
Showing with 30 additions and 0 deletions.
  1. +10 −0 actionmailer/test/url_test.rb
  2. +8 −0 actionpack/CHANGELOG.md
  3. +12 −0 actionpack/lib/action_dispatch/routing/url_for.rb
@@ -84,4 +84,14 @@ def test_signed_up_with_url
delivered.message_id = '<123@456>'
assert_equal expected.encoded, delivered.encoded
end
+
+ def test_improperly_assigned_options_raise_an_error
+ original_host = UrlTestMailer.default_url_options[:host]
+ UrlTestMailer.default_url_options = {host: 'http://www.basecamphq.com'}
+
+ assert_equal UrlTestMailer.default_url_options[:host], 'www.basecamphq.com'
+ assert_equal UrlTestMailer.default_url_options[:protocol], 'http://'
+ ensure
+ UrlTestMailer.default_url_options[:host] = original_host
+ end
end
View
@@ -1,4 +1,12 @@
## Rails 4.0.0 (unreleased) ##
+
+* Allow action mailer default url options to accept host with protocol such as `http://`
+
+ config.action_mailer.default_url_options = { :host => "http://mydomain.com" }
+
+
+ *Richard Schneeman*
+
* Add :if / :unless conditions to fragment cache:
<%= cache @model, if: some_condition(@model) do %>
@@ -93,6 +93,18 @@ module UrlFor
mattr_writer :default_url_options
end
+ instance_eval do
+ alias :original_default_url_options= :default_url_options=
+
+ # check for improperly formatted options in default_url_options on assignment
+ def default_url_options=(options = {})
+ if options[:host] && match = options[:host].match(/(^.*:\/\/)(.*)/)
+ options[:protocol] ||= match[1]
+ options[:host] = match[2]
+ end
+ self.original_default_url_options = options
+ end
+ end
self.default_url_options = {}
end

0 comments on commit 759335b

Please sign in to comment.