/usr/lib/ruby/vendor_ruby/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb is in ruby-bundler 1.13.6-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # frozen_string_literal: true
require "fileutils"
require "stringio"
require "tmpdir"
require "zlib"
class Bundler::CompactIndexClient
class Updater
class MisMatchedChecksumError < Error
def initialize(path, server_checksum, local_checksum)
@path = path
@server_checksum = server_checksum
@local_checksum = local_checksum
end
def message
"The checksum of /#{@path} does not match the checksum provided by the server! Something is wrong " \
"(local checksum is #{@local_checksum.inspect}, was expecting #{@server_checksum.inspect})."
end
end
def initialize(fetcher)
@fetcher = fetcher
end
def update(local_path, remote_path, retrying = nil)
headers = {}
Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir|
local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename)
# first try to fetch any new bytes on the existing file
if retrying.nil? && local_path.file?
FileUtils.cp local_path, local_temp_path
headers["If-None-Match"] = etag_for(local_temp_path)
headers["Range"] = "bytes=#{local_temp_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_temp_path.open(mode) {|f| f << content }
response_etag = response["ETag"].gsub(%r{\AW/}, "")
if etag_for(local_temp_path) == response_etag
FileUtils.mv(local_temp_path, local_path)
return
end
if retrying.nil?
update(local_path, remote_path, :retrying)
else
raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_temp_path))
end
end
end
def etag_for(path)
sum = checksum_for_file(path)
sum ? %("#{sum}") : nil
end
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
end
end
|