diff options
author | Sean McGivern <sean@mcgivern.me.uk> | 2016-10-18 20:49:51 +0000 |
---|---|---|
committer | Sean McGivern <sean@mcgivern.me.uk> | 2016-10-18 20:49:51 +0000 |
commit | 95f7d6bcbdb55aaf96edcd672362ae0f99836420 (patch) | |
tree | 9143f1b8068a74d53b5c9b1b1a2d425772e64e25 /lib | |
parent | 2c00d00ec1c39dbea0e0e54265027b5476b78e3c (diff) | |
parent | 3db585d27c005397aab3fa05cbe77853bc1019be (diff) | |
download | gitlab-ce-95f7d6bcbdb55aaf96edcd672362ae0f99836420.tar.gz |
Merge branch '22782-external-link-filter-with-non-lowercase-scheme' into 'master'
Add Nofollow for uppercased external url protocols
Closes #22782
See merge request !6820
Diffstat (limited to 'lib')
-rw-r--r-- | lib/banzai/filter/external_link_filter.rb | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/lib/banzai/filter/external_link_filter.rb b/lib/banzai/filter/external_link_filter.rb index 0a29c547a4d..2f19b59e725 100644 --- a/lib/banzai/filter/external_link_filter.rb +++ b/lib/banzai/filter/external_link_filter.rb @@ -3,10 +3,17 @@ module Banzai # HTML Filter to modify the attributes of external links class ExternalLinkFilter < HTML::Pipeline::Filter def call - # Skip non-HTTP(S) links and internal links - doc.xpath("descendant-or-self::a[starts-with(@href, 'http') and not(starts-with(@href, '#{internal_url}'))]").each do |node| - node.set_attribute('rel', 'nofollow noreferrer') - node.set_attribute('target', '_blank') + links.each do |node| + href = href_to_lowercase_scheme(node["href"].to_s) + + unless node["href"].to_s == href + node.set_attribute('href', href) + end + + if href =~ /\Ahttp(s)?:\/\// && external_url?(href) + node.set_attribute('rel', 'nofollow noreferrer') + node.set_attribute('target', '_blank') + end end doc @@ -14,6 +21,25 @@ module Banzai private + def links + query = 'descendant-or-self::a[@href and not(@href = "")]' + doc.xpath(query) + end + + def href_to_lowercase_scheme(href) + scheme_match = href.match(/\A(\w+):\/\//) + + if scheme_match + scheme_match.to_s.downcase + scheme_match.post_match + else + href + end + end + + def external_url?(url) + !url.start_with?(internal_url) + end + def internal_url @internal_url ||= Gitlab.config.gitlab.url end |