Skip to content

Don't hide upstream 404 and 401/403 behind stale metadata - #541

Open
simonchrz wants to merge 3 commits into
git-pkgs:mainfrom
simonchrz:fix/stale-metadata-definite-errors
Open

simonchrz wants to merge 3 commits into
git-pkgs:mainfrom
simonchrz:fix/stale-metadata-definite-errors

Conversation

@simonchrz

Copy link
Copy Markdown
Contributor

Fixes #499.

With cache_metadata on, fetchMetadataFromUpstream fell back to the cached copy on any upstream error. A 404 (package removed) and a 401/403 (the proxy's credentials rejected) are answers rather than outages, and serving the old version list in their place kept them from the client.

  • 404 and 401/403 no longer fall back. A 404 reaches the client as 404. A 401/403 becomes the 502 other upstream failures already get: passing a 401 on would make clients ask their user for credentials for the proxy, when it's the proxy's own credentials the upstream rejected. Timeouts, connection errors, 5xx and 429 still fall back.
  • npm, Composer and Chef serve metadata through the rewrite cache, which dropped the stale flag, so a fallback looked like a fresh 200. They now set the same Warning: 110 - "Response is Stale" as other metadata.

This affects every ecosystem using the metadata cache, not just npm. It also touches #486: after pointing an upstream at a registry that lacks a package, clients now get the 404 rather than the old version list.

Not included: a maximum stale age. That would be a new config option, so I'd rather settle it here first. Is it wanted, and with what default?

Testing

npm handler tests cover an upstream 5xx, a timeout, a 304, a 404, a 401 and a 403 after a cached fetch, checking the status, the stale warning and whether the cached packument is served. Composer tests cover a 5xx, a 404, a 401 and a 403 the same way; on main all four fail there too. A ProxyCached test checks that 404, 401 and 403 aren't hidden for other ecosystems. Without the fix the 404/401/403 cases fail, and without the warning the 5xx and timeout cases do.

With cache_metadata on, a failed upstream metadata fetch fell back to the
cached copy for any error. A 404 (package removed) and a 401/403 (the
proxy's credentials rejected) are definite answers, though, and serving
the old version list in their place kept them from reaching the client.
They now pass through: 404 as 404, 401/403 as 502 like other upstream
failures. Timeouts, connection errors, 5xx and 429 still fall back.

The npm, Composer and Chef handlers serve metadata through the rewrite
cache, which dropped the stale flag, so a fallback looked like a fresh
200. They now set the same Warning: 110 header as other metadata.

Fixes git-pkgs#499

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The stale-warning fix misses handleFilteredNPMVersionMetadata. With cooldown or a version denylist enabled, version/tag requests take this separate path, which still discards the stale flag. A targeted handler test with a denylist entry for another version reproduced /left-pad/1.0.0 returning cached metadata as 200 with no Warning after upstream returned 503. Please carry the stale flag through this path and add a regression test that enters through the npm route.

With cooldown or a version denylist, /pkg/<version> reads the filtered
packument through handleFilteredNPMVersionMetadata, which dropped the
stale flag.
@simonchrz

Copy link
Copy Markdown
Contributor Author

Done: the filtered version path now carries the stale flag, with a regression test through the npm route (denylist entry for another version, upstream 503).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

npm returns stale metadata as a plain 200 after upstream 404 or 401/403

2 participants