Class: HTML::Pipeline::CamoFilter

Inherits:
Filter
  • Object
show all
Defined in:
lib/html/pipeline/camo_filter.rb

Overview

HTML Filter for replacing http image URLs with camo versions. See:

github.com/atmos/camo

All images provided in user content should be run through this filter so that http image sources do not cause mixed-content warnings in browser clients.

Context options:

:asset_proxy (required) - Base URL for constructed asset proxy URLs.
:asset_proxy_secret_key (required) - The shared secret used to encode URLs.
:asset_proxy_whitelist - Array of host Strings or Regexps to skip
                         src rewriting.

This filter does not write additional information to the context.

Instance Attribute Summary

Attributes inherited from Filter

#context, #result

Instance Method Summary collapse

Methods inherited from Filter

#base_url, call, #current_user, #doc, #has_ancestor?, #html, #initialize, #needs, #parse_html, #repository, to_document, to_html

Constructor Details

This class inherits a constructor from HTML::Pipeline::Filter

Instance Method Details

#asset_host_whitelisted?(host) ⇒ Boolean


82
83
84
85
86
# File 'lib/html/pipeline/camo_filter.rb', line 82

def asset_host_whitelisted?(host)
  asset_proxy_whitelist.any? do |test|
    test.is_a?(String) ? host == test : test.match(host)
  end
end

#asset_proxy_enabled?Boolean

Private: Return true if asset proxy filter should be enabled


65
66
67
# File 'lib/html/pipeline/camo_filter.rb', line 65

def asset_proxy_enabled?
  !context[:disable_asset_proxy]
end

#asset_proxy_hostObject

Private: the host to use for generated asset proxied URLs.


70
71
72
# File 'lib/html/pipeline/camo_filter.rb', line 70

def asset_proxy_host
  context[:asset_proxy]
end

#asset_proxy_secret_keyObject


74
75
76
# File 'lib/html/pipeline/camo_filter.rb', line 74

def asset_proxy_secret_key
  context[:asset_proxy_secret_key]
end

#asset_proxy_url(url) ⇒ Object

The camouflaged URL for a given image URL.


55
56
57
# File 'lib/html/pipeline/camo_filter.rb', line 55

def asset_proxy_url(url)
  "#{asset_proxy_host}/#{asset_url_hash(url)}/#{hexencode(url)}"
end

#asset_proxy_whitelistObject


78
79
80
# File 'lib/html/pipeline/camo_filter.rb', line 78

def asset_proxy_whitelist
  context[:asset_proxy_whitelist] || []
end

#asset_url_hash(url) ⇒ Object

Private: calculate the HMAC digest for a image source URL.


60
61
62
# File 'lib/html/pipeline/camo_filter.rb', line 60

def asset_url_hash(url)
  OpenSSL::HMAC.hexdigest('sha1', asset_proxy_secret_key, url)
end

#callObject

Hijacks images in the markup provided, replacing them with URLs that go through the github asset proxy.


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/html/pipeline/camo_filter.rb', line 26

def call
  return doc unless asset_proxy_enabled?

  doc.search('img').each do |element|
    original_src = element['src']
    next unless original_src

    begin
      uri = URI.parse(original_src)
    rescue Exception
      next
    end

    next if uri.host.nil?
    next if asset_host_whitelisted?(uri.host)

    element['src'] = asset_proxy_url(original_src)
    element['data-canonical-src'] = original_src
  end
  doc
end

#hexencode(str) ⇒ Object

Private: helper to hexencode a string. Each byte ends up encoded into two characters, zero padded value in the range [0-9a-f].


90
91
92
# File 'lib/html/pipeline/camo_filter.rb', line 90

def hexencode(str)
  str.unpack('H*').first
end

#validateObject

Implementation of validate hook. Errors should raise exceptions or use an existing validator.


50
51
52
# File 'lib/html/pipeline/camo_filter.rb', line 50

def validate
  needs :asset_proxy, :asset_proxy_secret_key
end