html-pipeline 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 255c35bcd09c89964eafb3a2f6a6593acc003a9b
4
- data.tar.gz: b18754600751cf85ed04a96e44fa16a60070604e
3
+ metadata.gz: 6a991b217bf4c9c658d1843fe35e6a9ba989b180
4
+ data.tar.gz: 24763a9cac62ba2047a64e2c42bfee4107e00ae3
5
5
  SHA512:
6
- metadata.gz: 00048b649ab9e2514e26215265e9b137d2654096fa68c8a183623cb1270a26288c0d65377a432c9893528d7ff367e35dc2feaeed987bb0c562c28d7d7a8257b2
7
- data.tar.gz: a8275a10d2ef7dc1dccbcfa454840914519a7e08baef0739de29bd3b9de1e717798dc22330e02cde9b8c46a3d27341d54447e1b4b556c73e3b7b2f906315cbed
6
+ metadata.gz: 8433da8334030909b29622d615aa693117c89fdcb06ce581d2dfae7e1a14dee705e3c60fbfbebb8d1c1227ee80d279aded108a1d7491305279d0994195b03c2c
7
+ data.tar.gz: 34cd18428fdf6b408347ffc6d5e5eb95e6f6ee0dfff098b2a5114ecbb73bc4f78931baabaee145abf070cd2b2df6e1edfb6d28a9b6ad49d53c5ccb156db006d2
data/.travis.yml CHANGED
@@ -7,7 +7,6 @@ before_install:
7
7
  script: "bundle exec rake"
8
8
 
9
9
  rvm:
10
- - 1.8.7
11
10
  - 1.9.2
12
11
  - 1.9.3
13
12
  - 2.0.0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.3.0
4
+
5
+ 1.2.0 didn't actually include the following changes. Yanked that release.
6
+
7
+ * CamoFilter now camos https images. #96 josh
8
+
3
9
  ## 1.1.0
4
10
 
5
11
  * escape emoji filenames in urls #92 jayroh
@@ -1,4 +1,5 @@
1
1
  require 'openssl'
2
+ require 'uri'
2
3
 
3
4
  module HTML
4
5
  class Pipeline
@@ -13,27 +14,34 @@ module HTML
13
14
  # Context options:
14
15
  # :asset_proxy (required) - Base URL for constructed asset proxy URLs.
15
16
  # :asset_proxy_secret_key (required) - The shared secret used to encode URLs.
17
+ # :asset_proxy_whitelist - Array of host Strings or Regexps to skip
18
+ # src rewriting.
16
19
  #
17
20
  # This filter does not write additional information to the context.
18
21
  class CamoFilter < Filter
19
22
  # Hijacks images in the markup provided, replacing them with URLs that
20
23
  # go through the github asset proxy.
21
24
  def call
25
+ return unless asset_proxy_enabled?
26
+
22
27
  doc.search("img").each do |element|
23
28
  next if element['src'].nil?
24
- src = element['src'].strip
25
- src = src.sub(%r!^http://github.com!, 'https://github.com')
26
- next if context[:disable_asset_proxy]
27
29
 
28
- if src =~ /^http:/ || src =~ /^https:\/\/img.skitch.com\//
29
- element['src'] = asset_proxy_url(src)
30
- else
31
- element['src'] = src
30
+ begin
31
+ uri = URI.parse(element['src'])
32
+ rescue Exception
33
+ next
32
34
  end
35
+
36
+ next if uri.host.nil?
37
+ next if asset_host_whitelisted?(uri.host)
38
+
39
+ element['src'] = asset_proxy_url(uri.to_s)
40
+ element['data-canonical-src'] = uri.to_s
33
41
  end
34
42
  doc
35
43
  end
36
-
44
+
37
45
  # Implementation of validate hook.
38
46
  # Errors should raise exceptions or use an existing validator.
39
47
  def validate
@@ -51,7 +59,12 @@ module HTML
51
59
  OpenSSL::HMAC.hexdigest(digest, asset_proxy_secret_key, url)
52
60
  end
53
61
 
54
- # Private: the hostname to use for generated asset proxied URLs.
62
+ # Private: Return true if asset proxy filter should be enabled
63
+ def asset_proxy_enabled?
64
+ !context[:disable_asset_proxy]
65
+ end
66
+
67
+ # Private: the host to use for generated asset proxied URLs.
55
68
  def asset_proxy_host
56
69
  context[:asset_proxy]
57
70
  end
@@ -60,6 +73,16 @@ module HTML
60
73
  context[:asset_proxy_secret_key]
61
74
  end
62
75
 
76
+ def asset_proxy_whitelist
77
+ context[:asset_proxy_whitelist] || []
78
+ end
79
+
80
+ def asset_host_whitelisted?(host)
81
+ asset_proxy_whitelist.any? do |test|
82
+ test.is_a?(String) ? host == test : test.match(host)
83
+ end
84
+ end
85
+
63
86
  # Private: helper to hexencode a string. Each byte ends up encoded into
64
87
  # two characters, zero padded value in the range [0-9a-f].
65
88
  def hexencode(str)
@@ -67,4 +90,4 @@ module HTML
67
90
  end
68
91
  end
69
92
  end
70
- end
93
+ end
@@ -1,5 +1,5 @@
1
1
  module HTML
2
2
  class Pipeline
3
- VERSION = "1.1.0"
3
+ VERSION = "1.3.0"
4
4
  end
5
5
  end
@@ -8,7 +8,8 @@ class HTML::Pipeline::CamoFilterTest < Test::Unit::TestCase
8
8
  @asset_proxy_secret_key = 'ssssh-secret'
9
9
  @options = {
10
10
  :asset_proxy => @asset_proxy_url,
11
- :asset_proxy_secret_key => @asset_proxy_secret_key
11
+ :asset_proxy_secret_key => @asset_proxy_secret_key,
12
+ :asset_proxy_whitelist => [/(^|\.)github\.com$/]
12
13
  }
13
14
  end
14
15
 
@@ -16,17 +17,49 @@ class HTML::Pipeline::CamoFilterTest < Test::Unit::TestCase
16
17
  orig = %(<p><img src="http://twitter.com/img.png"></p>)
17
18
  assert_includes 'img src="' + @asset_proxy_url,
18
19
  CamoFilter.call(orig, @options).to_s
20
+ assert_includes 'data-canonical-src="http://twitter.com/img.png"',
21
+ CamoFilter.call(orig, @options).to_s
19
22
  end
20
23
 
21
- def test_rewrites_dotcom_image_urls
22
- orig = %(<p><img src="http://github.com/img.png"></p>)
24
+ def test_doesnt_rewrite_dotcom_image_urls
25
+ orig = %(<p><img src="https://github.com/img.png"></p>)
23
26
  assert_equal "<p><img src=\"https://github.com/img.png\"></p>",
24
27
  CamoFilter.call(orig, @options).to_s
25
28
  end
26
29
 
27
- def test_not_camouflaging_https_image_urls
30
+ def test_doesnt_rewrite_dotcom_subdomain_image_urls
31
+ orig = %(<p><img src="https://raw.github.com/img.png"></p>)
32
+ assert_equal "<p><img src=\"https://raw.github.com/img.png\"></p>",
33
+ CamoFilter.call(orig, @options).to_s
34
+ end
35
+
36
+ def test_doesnt_rewrite_dotcom_subsubdomain_image_urls
37
+ orig = %(<p><img src="https://f.assets.github.com/img.png"></p>)
38
+ assert_equal "<p><img src=\"https://f.assets.github.com/img.png\"></p>",
39
+ CamoFilter.call(orig, @options).to_s
40
+ end
41
+
42
+ def test_camouflaging_github_prefixed_image_urls
43
+ orig = %(<p><img src="https://notgithub.com/img.png"></p>)
44
+ assert_includes 'img src="' + @asset_proxy_url,
45
+ CamoFilter.call(orig, @options).to_s
46
+ end
47
+
48
+ def test_doesnt_rewrite_absolute_image_urls
49
+ orig = %(<p><img src="/img.png"></p>)
50
+ assert_equal "<p><img src=\"/img.png\"></p>",
51
+ CamoFilter.call(orig, @options).to_s
52
+ end
53
+
54
+ def test_doesnt_rewrite_relative_image_urls
55
+ orig = %(<p><img src="img.png"></p>)
56
+ assert_equal "<p><img src=\"img.png\"></p>",
57
+ CamoFilter.call(orig, @options).to_s
58
+ end
59
+
60
+ def test_camouflaging_https_image_urls
28
61
  orig = %(<p><img src="https://foo.com/img.png"></p>)
29
- assert_doesnt_include 'img src="' + @asset_proxy_url,
62
+ assert_includes 'img src="' + @asset_proxy_url,
30
63
  CamoFilter.call(orig, @options).to_s
31
64
  end
32
65
 
@@ -36,10 +69,10 @@ class HTML::Pipeline::CamoFilterTest < Test::Unit::TestCase
36
69
  CamoFilter.call(orig, @options).to_s
37
70
  end
38
71
  end
39
-
72
+
40
73
  def test_required_context_validation
41
- exception = assert_raise(ArgumentError) {
42
- CamoFilter.call("", {})
74
+ exception = assert_raise(ArgumentError) {
75
+ CamoFilter.call("", {})
43
76
  }
44
77
  assert_match /:asset_proxy[^_]/, exception.message
45
78
  assert_match /:asset_proxy_secret_key/, exception.message
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-pipeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Tomayko
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-20 00:00:00.000000000 Z
12
+ date: 2014-01-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  version: '0'
116
116
  requirements: []
117
117
  rubyforge_project:
118
- rubygems_version: 2.0.3
118
+ rubygems_version: 2.0.14
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: Helpers for processing content through a chain of filters