Skip to content

Instantly share code, notes, and snippets.

@jeremyroman
Created July 28, 2011 15:54
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jeremyroman/1111803 to your computer and use it in GitHub Desktop.
Save jeremyroman/1111803 to your computer and use it in GitHub Desktop.
An HTTP importer for Sass
# Additional caching and such might be helpful for performance.
# Sass's regeneration only on changed files should work as long as the server provides the Last-Modified header
require 'net/http'
require 'time'
require 'sass'
module Sass
module Importers
# Importer which issues HTTP requests
class HTTP < Base
def initialize(root)
@root = URI.parse(root)
unless @root.absolute? && @root.scheme == 'http'
raise ArgumentError, "Absolute HTTP URIs only"
end
end
def find_relative(uri, base, options)
_find(@root + base + uri, options)
end
def find(uri, options)
_find(@root + uri, options)
end
def mtime(uri, options)
uri = URI.parse(uri)
return unless uri.absolute? && uri.scheme == 'http'
Net::HTTP.start(uri.host, uri.port) do |http|
response = http.head(uri.request_uri)
if response.is_a?(Net::HTTPOK) && response['Last-Modified']
Time.parse(response['Last-Modified'])
elsif response.is_a? Net::HTTPOK
# we must assume that it just changed
Time.now
else
nil
end
end
end
def key(uri, options)
[self.class.name, uri]
end
def to_s
@root.to_s
end
protected
def extensions
{'.sass' => :sass, '.scss' => :scss}
end
private
def exists?(uri)
Net::HTTP.start(uri.host, uri.port) do |http|
http.head(uri.request_uri).is_a? Net::HTTPOK
end
end
def _find(uri, options)
return unless uri.absolute? && uri.scheme == 'http'
# determine the syntax being used
ext = File.extname(uri.path)
syntax = extensions[ext]
# this must not be the full path: try another
if syntax.nil?
ext, syntax = extensions.find do |possible_ext, possible_syntax|
new_uri = uri.dup
new_uri.path += possible_ext
exists? new_uri
end
return if syntax.nil?
uri.path += ext
end
# fetch the content
Net::HTTP.start(uri.host, uri.port) do |http|
response = http.get(uri.request_uri)
response.value
options[:importer] = self
options[:filename] = uri.to_s
options[:syntax] = syntax
Sass::Engine.new(response.body, options)
end
rescue
nil
end
end
end
end
@joeellis
Copy link

Jeremy,
I had a great use for this the other day, and spent a day or so just packaging it up into a gem here: https://github.com/joeellis/remote-sass , complete with tests, README, some minor changes, etc. If it suits you, I'd like to add you in as an author as i didn't really make too many changes to your original code, so I believe you should have credit for that. Anyways, just let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment