[rubygems/rubygems] Retry gracefully on blank partial response in compact index

https://github.com/rubygems/rubygems/commit/fafb9ae090
This commit is contained in:
Martin Emde 2025-02-21 17:57:16 -08:00 committed by Hiroshi SHIBATA
parent 223f37c002
commit 19bdcc8f0c
No known key found for this signature in database
GPG Key ID: F9CF13417264FAC2
2 changed files with 19 additions and 1 deletions

View File

@ -37,7 +37,8 @@ module Bundler
file.digests = parse_digests(response)
# server may ignore Range and return the full response
if response.is_a?(Gem::Net::HTTPPartialContent)
break false unless file.append(response.body.byteslice(1..-1))
tail = response.body.byteslice(1..-1)
break false unless tail && file.append(tail)
else
file.write(response.body)
end

View File

@ -115,6 +115,23 @@ RSpec.describe Bundler::CompactIndexClient::Updater do
expect(local_path.read).to eq(full_body)
expect(etag_path.read).to eq("NewEtag")
end
it "tries the request again if the partial response is blank" do
allow(response).to receive(:[]).with("Repr-Digest") { "sha-256=:baddigest:" }
allow(response).to receive(:body) { "" }
allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { true }
expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
full_response = double(:full_response, body: full_body, is_a?: false)
allow(full_response).to receive(:[]).with("Repr-Digest") { "sha-256=:#{digest}:" }
allow(full_response).to receive(:[]).with("ETag") { '"NewEtag"' }
expect(fetcher).to receive(:call).once.with(remote_path, { "If-None-Match" => '"LocalEtag"' }).and_return(full_response)
updater.update(remote_path, local_path, etag_path)
expect(local_path.read).to eq(full_body)
expect(etag_path.read).to eq("NewEtag")
end
end
context "without an etag file" do