Skip to content

Instantly share code, notes, and snippets.

@reggieb
Created November 11, 2013 08:52
Show Gist options
  • Save reggieb/7410001 to your computer and use it in GitHub Desktop.
Save reggieb/7410001 to your computer and use it in GitHub Desktop.
geminabox hostess. Version at point where rolled back to just proxy bundler actions.
require 'sinatra/base'
require 'httpclient'
module Geminabox
class Hostess < Sinatra::Base
%w[/specs.4.8.gz
/latest_specs.4.8.gz
/prerelease_specs.4.8.gz
].each do |index|
get index do
content_type('application/x-gzip')
serve
end
end
%w[/quick/Marshal.4.8/*.gemspec.rz
/yaml.Z
/Marshal.4.8.Z
].each do |deflated_index|
get deflated_index do
content_type('application/x-deflate')
serve
end
end
%w[/yaml
/Marshal.4.8
/specs.4.8
/latest_specs.4.8
/prerelease_specs.4.8
].each do |old_index|
get old_index do
serve
end
end
get "/gems/*.gem" do
serve
end
def serve
proxy_prep if Geminabox.rubygems_proxy
send_file(File.expand_path(File.join(Server.data, *request.path_info)), :type => response['Content-Type'])
end
def proxy_prep
p request.path_info
case request.path_info.to_s
when /\.gem$/
puts ".gem"
get_from_rubygems_if_not_local
when /\.gz/
puts ".gz"
splice_specs
else
puts "else"
copy_file
end
end
def get_from_rubygems_if_not_local
file = File.expand_path(File.join(Server.data, *request.path_info))
unless File.exists?(file)
Net::HTTP.start("production.cf.rubygems.org") do |http|
path = File.join(*request.path_info)
response = http.get(path)
GemStore.create(IncomingGem.new(StringIO.new(response.body)))
end
end
end
def copy_file
file_name = File.expand_path(File.join(Server.data, *request.path_info))
unless File.exists?(file_name)
content = HTTPClient.get_content("https://rubygems.org#{request.path_info}")
File.write(file_name, content )
end
end
def splice_specs
splice_specs!(request.path_info)
end
def splice_specs!(file_name)
local_specs_file = Geminabox.data + file_name
copy_file unless File.exists?(local_specs_file)
local_specs = marshal_load(file_name, local_specs_file)
rubygems_url = "https://rubygems.org#{file_name}"
rubygems_specs = marshal_load(file_name, open(rubygems_url))
new_specs = local_specs | rubygems_specs
File.open(local_specs_file, 'w') { |file| marshal_dump(file, new_specs) }
end
def marshal_load(file_name, path)
content = File.read(path)
return [] if content.empty?
content = Gem.gunzip(content) if /.gz$/ =~ file_name
Marshal.load content
rescue Zlib::GzipFile::Error
Marshal.load content
end
def marshal_dump(file, content)
content = Marshal.dump(content)
content = Gem.gzip(content) if /.gz$/ =~ file.path
file.write content
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment