Created
November 11, 2013 08:52
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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