Skip to content

Commit ad9dafd

Browse files
authored
Merge pull request #94 from 2manymws/fix-storable
fix(rfc9111): correct status code understanding logic per RFC 9111 Section 3
2 parents 63ee03c + 77d5bdd commit ad9dafd

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

rfc9111/default.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,17 @@ var defaultUnderstoodStatusCodes = []int{
2727
http.StatusNonAuthoritativeInfo, // 203 / RFC 9110, 15.3.4
2828
http.StatusNoContent, // 204 / RFC 9110, 15.3.5
2929
http.StatusResetContent, // 205 / RFC 9110, 15.3.6
30-
http.StatusPartialContent, // 206 / RFC 9110, 15.3.7
31-
http.StatusMultiStatus, // 207 / RFC 4918, 11.1
32-
http.StatusAlreadyReported, // 208 / RFC 5842, 7.1
33-
http.StatusIMUsed, // 226 / RFC 3229, 10.4.1
30+
// http.StatusPartialContent, // 206 / RFC 9110, 15.3.7
31+
// 206 is excluded from understood status codes by default because:
32+
// - 206 responses are for Range requests and contain only partial content
33+
// - Caching 206 without proper Range-aware cache key management can cause incorrect cache hits
34+
// (e.g., a cached 206 response for bytes 0-1023 might be returned for a request wanting the full resource)
35+
// - This implementation does not currently handle Vary: Range or range-specific cache keys
36+
// - While RFC 9110 defines 206 as heuristically cacheable, safe caching requires understanding Range semantics
37+
// - Users can explicitly add 206 to understood status codes via UnderstoodStatusCodes option if needed
38+
http.StatusMultiStatus, // 207 / RFC 4918, 11.1
39+
http.StatusAlreadyReported, // 208 / RFC 5842, 7.1
40+
http.StatusIMUsed, // 226 / RFC 3229, 10.4.1
3441

3542
http.StatusMultipleChoices, // 300 / RFC 9110, 15.4.1
3643
http.StatusMovedPermanently, // 301 / RFC 9110, 15.4.2

rfc9111/shared.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,9 @@ func (s *Shared) Storable(req *http.Request, res *http.Response, now time.Time)
125125
rescc := ParseResponseCacheControlHeader(res.Header.Values("Cache-Control"))
126126

127127
// - if the response status code is 206 or 304, or the must-understand cache directive (see https://www.rfc-editor.org/rfc/rfc9111#section-5.2.2.3) is present: the cache understands the response status code;
128-
if contains(res.StatusCode, []int{
129-
http.StatusPartialContent,
130-
http.StatusNotModified,
131-
}) || (rescc.MustUnderstand && !contains(res.StatusCode, s.understoodStatusCodes)) {
128+
if (contains(res.StatusCode, []int{http.StatusPartialContent, http.StatusNotModified}) &&
129+
!contains(res.StatusCode, s.understoodStatusCodes)) ||
130+
(rescc.MustUnderstand && !contains(res.StatusCode, s.understoodStatusCodes)) {
132131
return s.storableWithExtendedRules(req, res, now)
133132
}
134133

0 commit comments

Comments
 (0)