GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Abort the response when a cached artifact fails its integrity check by orshih6 · Pull Request #504 · git-pkgs/proxy

Conversation

@orshih6

@orshih6 orshih6 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

The cache-hit path wrapped the stored artifact with checks.wrap. That reader reports a digest mismatch to its callback but still returns io.EOF, so the client got the full corrupted body with a 200 and a matching Content-Length. The upstream streaming path used wrapFailOnMismatch, which does return an error, but only together with the final read, after every byte had already been written.

Changes:

  • verifyingReader in fail-on-mismatch mode now runs one chunk behind its source. It holds the latest chunk until the next read shows it isn't the last one, or until EOF, when the digest is checked. If the digest matches, the held chunk is released. If it doesn't, the chunk is dropped and ErrArtifactDigestMismatch is returned. Only one chunk is buffered, sized to the caller's read buffer, so streaming is kept.
  • wrapFailOnMismatch now keeps the seekable wrapper like wrap does, so range requests on cached artifacts still work.
  • The cache-hit path in readStored uses wrapFailOnMismatch. The mismatch callback still logs, records the metric and discards the entry. copyArtifactBody already panics with http.ErrAbortHandler when the copy errors, so the client gets a body shorter than Content-Length and a read error.

The non-failing wrap behaves as before. Its existing tests are unchanged.

Testing:

  • TestCorruptCachedArtifactAbortsResponse seeds a cached artifact, flips its last stored byte, and serves it through httptest.Server to a real client. It asserts that the body read fails, that the body is shorter than Content-Length, and that the cache record is cleared.
  • TestFailOnMismatchHoldsBackFinalChunk covers the reader with whole reads, one-byte reads and data returned together with EOF, for both matching and mismatched bytes.
  • Both tests fail without the change. go test ./internal/handler/ and go vet ./internal/handler/ pass.

🤖 Generated with Claude Code

Fixes #498


This change was prepared with an AI coding agent (Claude) and reviewed by me before submitting. I'm happy to make any changes you'd like.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@orshih6
Abort the response when a cached artifact fails its integrity check
4b23b3f
@andrew andrew mentioned this pull request Oct 18, 2026
Verify artifact integrity and support sigstore attestations #42
Open
andrew
andrew approved these changes Oct 18, 2026
View reviewed changes

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final-chunk buffering prevents a digest mismatch from completing a successful download, and the HTTP-client regression test covers the corrupted cache-hit response. No blocking findings.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@simonchrz simonchrz mentioned this pull request Oct 19, 2026
Stream conda repodata through the cooldown filter #527
Merged
andrew
andrew requested changes Oct 20, 2026
View reviewed changes

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the integrity regression test for the current storage API. The combined code no longer compiles against main because storage.ArtifactPath was removed after the earlier approval.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread internal/handler/integrity_test.go Outdated
proxy, db, store, _ := setupTestProxy(t)
content := strings.Repeat("cached content ", 10000)
seedPackage(t, db, store, "npm", "corrupt", "1.0.0", "corrupt-1.0.0.tgz", content)
storagePath := storage.ArtifactPath("npm", "", "corrupt", "1.0.0", "corrupt-1.0.0.tgz")

@andrew andrew Oct 20, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current main removed storage.ArtifactPath, so this test no longer compiles when the PR is merged. Reproduced against the combined tree with go test ./internal/handler -run '^TestCorruptCachedArtifactAbortsResponse$' -count=1: internal/handler/integrity_test.go:364:25: undefined: storage.ArtifactPath. Read the seeded artifact's StoragePath from the database and corrupt that stored object instead of reconstructing its path, then rerun the regression test against current main.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

orshih6 reacted with rocket emoji orshih6 reacted with eyes emoji
All reactions
  • 🚀 1 reaction
  • 👀 1 reaction
@orshih6
Read the seeded artifact's storage path from the database in the inte…
c5b3ce8
…grity test
@orshih6

orshih6 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

@andrew Thanks, fixed. The test now gets the seeded artifact's StoragePath from the database and corrupts that object, so it no longer uses storage.ArtifactPath. I merged the branch with current main locally and ran go test ./internal/handler -run '^TestCorruptCachedArtifactAbortsResponse$' -count=1, and it passes. The rest of go test ./internal/handler passes on the merged tree too.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@andrew
andrew merged commit 6857fad into git-pkgs:main Oct 20, 2026
6 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@simonchrz simonchrz mentioned this pull request Oct 24, 2026
Stream metadata cache hits for ProxyCached #575
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@andrew andrew andrew requested changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Corrupted cached artifacts are served with a complete 200 response

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@orshih6 @andrew
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.