* fix(handler): preserve upstream content-encoding for cached metadata
Signed and hash-pinned index files (debian Release/Packages.gz, rpm
repomd.xml, helm index.yaml, conda repodata.json, apk APKINDEX.tar.gz)
were cached after Go's transport transparently decompressed any
Content-Encoding: gzip response, so the proxy served bytes that differ
from what the upstream signed and broke client verification.
Request the identity encoding on the shared metadata fetch so Go no
longer auto-decompresses, and persist the upstream Content-Encoding in
a new metadata_cache column so both the cached and offline responses
replay the exact bytes and header. The uncached streaming path now
forwards Content-Encoding too.
Fixes#300
* fix(handler): scope verbatim metadata fetch to the ProxyCached path
The first cut forced Accept-Encoding: identity in the shared
fetchUpstreamMetadata, which an adversarial review showed both missed
the bug and regressed unrelated ecosystems:
- proxyMetadataStream (the default path, since cache_metadata is off)
never forced identity, so a client sending no Accept-Encoding still
triggered Go's transparent gzip decompression and served altered bytes
for apk/debian/rpm/conda indexes.
- Direct FetchOrCacheMetadata callers that parse or rewrite the body
(npm, pypi, cargo, composer, pub, nuget, swift, maven, helm) were
forced to identity too, losing wire compression and 502-ing against
upstreams that ignore identity and gzip anyway (helm rewriteIndex).
- Rows cached before the fix kept serving decompressed bytes via ETag
304 revalidation.
Scope the verbatim behavior to the ProxyCached code path, which serves
upstream bytes through unchanged (apk, debian, rpm, go, hex, conda,
cran, gem, conan, julia). That path now requests identity on both the
cached fetch and the uncached stream branch and replays Content-Encoding;
direct callers keep transparent compression, matching main. Migration
008 clears etag/fetched_at so legacy rows refetch once with identity.
Tests now exercise the stream path with no client Accept-Encoding and
pin that direct callers are not forced to identity.