class Bundler::CompactIndexClient::Updater
def update(local_path, remote_path, retrying = nil)
def update(local_path, remote_path, retrying = nil) headers = {} local_temp_path = local_path.sub(/$/, ".#{$$}") local_temp_path = local_temp_path.sub(/$/, ".retrying") if retrying local_temp_path = local_temp_path.sub(/$/, ".tmp") # first try to fetch any new bytes on the existing file if retrying.nil? && local_path.file? copy_file local_path, local_temp_path headers["If-None-Match"] = etag_for(local_temp_path) headers["Range"] = if local_temp_path.size.nonzero? # Subtract a byte to ensure the range won't be empty. # Avoids 416 (Range Not Satisfiable) responses. "bytes=#{local_temp_path.size - 1}-" else "bytes=#{local_temp_path.size}-" end end response = @fetcher.call(remote_path, headers) return nil if response.is_a?(Net::HTTPNotModified) content = response.body etag = (response["ETag"] || "").gsub(%r{\AW/}, "") correct_response = SharedHelpers.filesystem_access(local_temp_path) do if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero? local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) } etag_for(local_temp_path) == etag else local_temp_path.open("wb") {|f| f << content } etag.length.zero? || etag_for(local_temp_path) == etag end end if correct_response SharedHelpers.filesystem_access(local_path) do FileUtils.mv(local_temp_path, local_path) end return nil end if retrying raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path)) end update(local_path, remote_path, :retrying) rescue Zlib::GzipFile::Error raise Bundler::HTTPError ensure FileUtils.remove_file(local_temp_path) if File.exist?(local_temp_path) end