werkzeug icon indicating copy to clipboard operation
werkzeug copied to clipboard

Several issues with CacheControl types

Open RazerM opened this issue 2 months ago • 1 comments

This issue is in three parts:

no-transform directive always returns None

This directive has no arguments (either in current RFC 9111 or older RFC 2616)

from werkzeug.http import parse_cache_control_header

cc = parse_cache_control_header("no-transform")
print(f"{cc.no_transform=}")

Output:

cc.no_transform=None

Expected: boolean based on presence

min-fresh directive returns "*" if missing required argument

from werkzeug.http import parse_cache_control_header

cc = parse_cache_control_header("min-fresh")
print(f"{cc.min_fresh=}")

Output:

cc.min_fresh='*'

Expected: None since the argument is required and "*" doesn't have a semantic meaning for this directive.

type stubs are incorrect

  • no_cache returns str not bool.
  • bool properties never return None
  • max_stale returns "*" in addition to int.
  • RequestCacheControl immutability is not reflected.

Environment:

  • Python version: N/A
  • Werkzeug version: 3.0.2

RazerM avatar Apr 19 '24 10:04 RazerM

They are all None if not present, the empty value is used if the directive is present but has no argument:

>>> from werkzeug.http import parse_cache_control_header
>>> parse_cache_control_header("max-stale").max_stale
'*'
>>> parse_cache_control_header("max-stale=1").max_stale
1
>>> parse_cache_control_header("").max_stale
None

* is currently used in a few other places that you haven't called out here

Those have optional arguments and * is at least handy as a truthy value.

-1 also doesn't make sense for max-age compared to None if not given

I agree. iirc Chromium treats max-age without the required argument as if the directive wasn't there.

RazerM avatar May 04 '24 18:05 RazerM