Edge response cache stores 206 partial responses under the full-URL key Issue open
Found while researching the edge asset cache design (origin/main fef28dc5). Not fixed here.
What the code does
internal/edge/edge.go:1867(maybeStore): the status gate isrec.status < 200 || rec.status >= 300, so a206 Partial Contentis admitted.ServeHTTPcomputescacheablefrom method and route kind only (~line 1765 on main). The request'sRangeheader is not consulted, andCacheKey(internal/edge/cache.go:35-41) is{Host, Method, Path, RawQuery, VaryValue}, so it does not carryRange.git grep -i rangeovercache.go,cache_test.goandedge_test.gofinds no Range handling or test.
Failure scenario
An app serves files with Go's http.FileServer / http.ServeContent (which answers Range with 206) and sets Cache-Control: max-age=60 on them. A browser, a download manager or a media element sends GET /file.bin with Range: bytes=0-1023. The app answers 206 with 1 KiB and Content-Range. The edge stores that response under GET /file.bin. Every following plain GET /file.bin for up to DefaultCacheMaxTTL (5 minutes) is answered from cache with the 206 status and the 1 KiB body. On a hibernating route this is the path that avoids the wake, so the wrong answer is also the one that gets served most.
I have not reproduced it end to end. The reading above is from the code.
Fix shape (suggestion)
Refuse to look up or store when the request carries Range (or If-Range), and refuse to store any status other than 200 (203 too, if anyone relies on it). Add a test that a Range request to a cacheable route neither fills nor is answered from the cache. The asset-cache spec on edge-asset-cache will serve ranges from a complete cached object instead, but the shared LRU needs the refusal on its own.
maybeStore admits any 2xx including 206, and nothing in the cache keys on or refuses Range, so a Range request to a cacheable URL can store a partial body that is replayed to full GETs for up to 5 minutes.