class HTMLPipeline::NodeFilter::AssetProxyFilter

Proxy images/assets to another server, such as [cactus/go-camo](github.com/cactus/go-camo#). Reduces mixed content warnings as well as hiding the customer’s IP address when requesting images. Copies the original img ‘src` to `data-canonical-src` then replaces the `src` with a new url to the proxy server.

Based on github.com/gjtorikian/html-pipeline/blob/v2.14.3/lib/html/pipeline/camo_filter.rb

Constants

SELECTOR

Public Class Methods

compile_allowlist(domain_list) click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 61
def compile_allowlist(domain_list)
  return if domain_list.empty?

  escaped = domain_list.map { |domain| Regexp.escape(domain).gsub("\\*", ".*?") }
  Regexp.new("^(#{escaped.join("|")})$", Regexp::IGNORECASE)
end
determine_allowlist(proxy_settings) click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 68
def determine_allowlist(proxy_settings)
  proxy_settings[:allowlist] || []
end
transform_context(context, proxy_settings = {}) click to toggle source

This helps setup the context. It’s not needed if you’re always providing all the necessary keys in the context. One example would be to override this and pull the settings from a set of global application settings.

# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 51
def transform_context(context, proxy_settings = {})
  context[:asset_proxy] = proxy_settings[:url] if proxy_settings[:url]
  context[:asset_proxy_secret_key] = proxy_settings[:secret_key] if proxy_settings[:secret_key]

  allowlist = determine_allowlist(proxy_settings)
  context[:asset_proxy_domain_regexp] ||= compile_allowlist(allowlist)

  context
end

Public Instance Methods

asset_host_allowed?(host) click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 43
def asset_host_allowed?(host)
  context[:asset_proxy_domain_regexp] ? context[:asset_proxy_domain_regexp].match?(host) : false
end
handle_element(element) click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 22
def handle_element(element)
  original_src = element["src"]
  return unless original_src

  begin
    uri = URI.parse(original_src)
  rescue StandardError
    return
  end

  return if uri.host.nil? && !original_src.start_with?("///")
  return if asset_host_allowed?(uri.host)

  element["src"] = asset_proxy_url(original_src)
  element["data-canonical-src"] = original_src
end
selector() click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 18
def selector
  SELECTOR
end
validate() click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 39
def validate
  needs(:asset_proxy, :asset_proxy_secret_key)
end

Private Instance Methods

asset_proxy_url(url) click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 73
        def asset_proxy_url(url)
  "#{context[:asset_proxy]}/#{asset_url_hash(url)}/#{hexencode(url)}"
end
asset_url_hash(url) click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 77
        def asset_url_hash(url)
  OpenSSL::HMAC.hexdigest("sha1", context[:asset_proxy_secret_key], url)
end
hexencode(str) click to toggle source
# File lib/html_pipeline/node_filter/asset_proxy_filter.rb, line 81
        def hexencode(str)
  str.unpack1("H*")
end