class Bundler::CompactIndexClient::Updater

Public Class Methods

new(fetcher) click to toggle source
# File lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb, line 20
def initialize(fetcher)
  @fetcher = fetcher
end

Public Instance Methods

checksum_for_file(path) click to toggle source
# File lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb, line 62
def checksum_for_file(path)
  return nil unless path.file?
  # This must use IO.read instead of Digest.file().hexdigest
  # because we need to preserve \n line endings on windows when calculating
  # the checksum
  Digest::MD5.hexdigest(IO.read(path))
end
etag_for(path) click to toggle source
# File lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb, line 57
def etag_for(path)
  sum = checksum_for_file(path)
  sum ? %Q("#{sum}") : nil
end
update(local_path, remote_path, retrying = nil) click to toggle source
# File lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb, line 24
def update(local_path, remote_path, retrying = nil)
  headers = {}

  if local_path.file?
    headers["If-None-Match"] = etag_for(local_path)
    headers["Range"] = "bytes=#{local_path.size}-"
  else
    # Fastly ignores Range when Accept-Encoding: gzip is set
    headers["Accept-Encoding"] = "gzip"
  end

  response = @fetcher.call(remote_path, headers)
  return if response.is_a?(Net::HTTPNotModified)

  content = response.body
  if response["Content-Encoding"] == "gzip"
    content = Zlib::GzipReader.new(StringIO.new(content)).read
  end

  mode = response.is_a?(Net::HTTPPartialContent) ? "a" : "w"
  local_path.open(mode) {|f| f << content }

  response_etag = response["ETag"]
  return if etag_for(local_path) == response_etag

  if retrying.nil?
    local_path.delete
    update(local_path, remote_path, :retrying)
  else
    raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_path))
  end
end