class Roadie::NetHttpProvider

@api public External asset provider that downloads stylesheets from some other server using Ruby's built-in {Net::HTTP} library.

You can pass a whitelist of hosts that downloads are allowed on.

@example Allowing all downloads

provider = Roadie::NetHttpProvider.new

@example Only allowing your own app domains

provider = Roadie::NetHttpProvider.new(
  whitelist: ["myapp.com", "assets.myapp.com", "www.myapp.com"]
)

Attributes

whitelist[R]

Public Class Methods

new(options = {}) click to toggle source

@option options [Array<String>] :whitelist ([]) A list of host names that downloads are allowed from. Empty set means everything is allowed.

# File lib/roadie/net_http_provider.rb, line 24
def initialize(options = {})
  @whitelist = host_set(Array(options.fetch(:whitelist, [])))
end

Public Instance Methods

find_stylesheet(url) click to toggle source
# File lib/roadie/net_http_provider.rb, line 28
def find_stylesheet(url)
  find_stylesheet!(url)
rescue CssNotFound
  nil
end
find_stylesheet!(url) click to toggle source
# File lib/roadie/net_http_provider.rb, line 34
def find_stylesheet!(url)
  response = download(url)
  if response.kind_of? Net::HTTPSuccess
    Stylesheet.new url, response.body
  else
    raise CssNotFound.new(url, "Server returned #{response.code}: #{truncate response.body}", self)
  end
rescue Timeout::Error
  raise CssNotFound.new(url, "Timeout", self)
end
inspect() click to toggle source
# File lib/roadie/net_http_provider.rb, line 46
def inspect() "#<#{self.class} whitelist: #{whitelist.inspect}>" end
to_s() click to toggle source
# File lib/roadie/net_http_provider.rb, line 45
def to_s() inspect end

Private Instance Methods

access_granted_to?(host) click to toggle source
# File lib/roadie/net_http_provider.rb, line 79
def access_granted_to?(host)
  whitelist.empty? || whitelist.include?(host)
end
download(url) click to toggle source
# File lib/roadie/net_http_provider.rb, line 59
def download(url)
  url = "https:#{url}" if url.start_with?("//")
  uri = URI.parse(url)
  if access_granted_to?(uri.host)
    get_response(uri)
  else
    raise CssNotFound.new(url, "#{uri.host} is not part of whitelist!", self)
  end
end
get_response(uri) click to toggle source
# File lib/roadie/net_http_provider.rb, line 69
def get_response(uri)
  if RUBY_VERSION >= "2.0.0"
    Net::HTTP.get_response(uri)
  else
    Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == 'https')) do |http|
      http.request(Net::HTTP::Get.new(uri.request_uri))
    end
  end
end
host_set(hosts) click to toggle source
# File lib/roadie/net_http_provider.rb, line 49
def host_set(hosts)
  hosts.each { |host| validate_host(host) }.to_set
end
truncate(string) click to toggle source
# File lib/roadie/net_http_provider.rb, line 83
def truncate(string)
  if string.length > 50
    string[0, 49] + "…"
  else
    string
  end
end
validate_host(host) click to toggle source
# File lib/roadie/net_http_provider.rb, line 53
def validate_host(host)
  if host.nil? || host.empty? || host == "." || host.include?("/")
    raise ArgumentError, "#{host.inspect} is not a valid hostname"
  end
end