class Roadie::NetHttpProvider
)
whitelist: [“myapp.com”, “assets.myapp.com”, “www.myapp.com”]
provider = Roadie::NetHttpProvider.new(
@example Only allowing your own app domains
provider = Roadie::NetHttpProvider.new
@example Allowing all downloads
You can pass a whitelist of hosts that downloads are allowed on.
using Ruby’s built-in {Net::HTTP} library.
External asset provider that downloads stylesheets from some other server
@api public
def access_granted_to?(host)
def access_granted_to?(host) whitelist.empty? || whitelist.include?(host) end
def download(url)
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( css_name: url, message: "#{uri.host} is not part of whitelist!", provider: self ) end end
def find_stylesheet(url)
def find_stylesheet(url) find_stylesheet!(url) rescue CssNotFound nil end
def find_stylesheet!(url)
def find_stylesheet!(url) response = download(url) if response.is_a? Net::HTTPSuccess Stylesheet.new(url, response_body(response)) else raise CssNotFound.new( css_name: url, message: "Server returned #{response.code}: #{truncate response.body}", provider: self ) end rescue Timeout::Error raise CssNotFound.new(css_name: url, message: "Timeout", provider: self) end
def get_response(uri)
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
def host_set(hosts)
def host_set(hosts) hosts.each { |host| validate_host(host) }.to_set end
def initialize(options = {})
(**options)
-
:whitelist
(Array
) -- A list of host names that downloads are allowed from. Empty set means everything is allowed.
def initialize(options = {}) @whitelist = host_set(Array(options.fetch(:whitelist, []))) end
def inspect
def inspect "#<#{self.class} whitelist: #{whitelist.inspect}>" end
def response_body(response)
def response_body(response) # Make sure we respect encoding because Net:HTTP will encode body as ASCII by default # which will break if the response is not compatible. supplied_charset = response.type_params["charset"] body = response.body if supplied_charset body.force_encoding(supplied_charset).encode!("UTF-8") else # Default to UTF-8 when server does not specify encoding as that is the # most common charset. body.force_encoding("UTF-8") end end
def to_s
def to_s inspect end
def truncate(string)
def truncate(string) if string.length > 50 string[0, 49] + "…" else string end end
def validate_host(host)
def validate_host(host) if host.nil? || host.empty? || host == "." || host.include?("/") raise ArgumentError, "#{host.inspect} is not a valid hostname" end end