Skip to content

Instantly share code, notes, and snippets.

@felipeelias
Forked from fnando/rubygems_proxy.rb
Created April 29, 2011 01:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save felipeelias/947682 to your computer and use it in GitHub Desktop.
Save felipeelias/947682 to your computer and use it in GitHub Desktop.
Rack app for caching RubyGems files. Very useful in our build server that sometimes fails due to our network or rubygems.org timeout.
require "./rubygems_proxy"
run RubygemsProxy
require "open-uri"
require "fileutils"
require "logger"
class RubygemsProxy
attr_reader :env
def self.call(env)
new(env).run
end
def initialize(env)
@env = env
end
def run
[200, {"Content-Type" => "application/octet-stream"}, [contents]]
end
private
def logger
@logger ||= Logger.new("log/application.log")
end
def cache_dir
File.expand_path "../cache", __FILE__
end
def contents
if cached? && valid?
logger.info "Read from cache: #{filepath}"
open(filepath).read
else
logger.info "Read from interwebz: #{url}"
open(url).read.tap {|content| save(content)}
end
rescue Exception => error
# Just try to load from file if something goes wrong.
# This includes HTTP timeout, or something.
# If it fails again, we won't have any files anyway!
logger.error "Error: #{error.class} => #{error.message}"
open(filepath).read
end
def save(contents)
FileUtils.mkdir_p File.dirname(filepath)
File.open(filepath, "wb") {|handler| handler << contents}
end
def valid?
filepath =~ /specs\..+\.gz$/ ? Time.now - File.mtime(filepath) < 300 : true
end
def cached?
File.file?(filepath)
end
def filepath
File.join(cache_dir, env["PATH_INFO"])
end
def url
File.join("http://rubygems.org", env["PATH_INFO"])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment