Skip to content

Commit d1c1b75

Browse files
Merge pull request #890 from crungehottman/flush-encoded-paths
Flush lowercase percent-encoded URLs [RHELDST-37769]
2 parents 4fac6bd + a5ba5ce commit d1c1b75

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

exodus_gw/worker/cache.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ def _encode_path(self, path: str) -> str:
7878
# URL-encode a path, preserving only forward slashes.
7979
return quote(path, safe="/")
8080

81+
def _lowercase_percent_encoding(self, path: str) -> str:
82+
# Convert percent-encoded hex digits to lowercase.
83+
# E.g., "%2B" -> "%2b"
84+
return re.sub(r"%[0-9A-F]{2}", lambda m: m.group(0).lower(), path)
85+
8186
@property
8287
def urls_for_flush(self):
8388
out: list[str] = []
@@ -91,14 +96,22 @@ def urls_for_flush(self):
9196
]
9297

9398
for path in path_list:
94-
# Generate URL-encoded path
99+
# Generate URL-encoded path (uppercase by default)
95100
encoded_path = self._encode_path(path)
96101

97-
# Only include both paths if encoding changes the path
98-
if path == encoded_path:
99-
paths_to_flush = [path]
100-
else:
101-
paths_to_flush = [path, encoded_path]
102+
# Start with the original path
103+
paths_to_flush = [path]
104+
105+
# If encoding changes the path, add both uppercase and lowercase variants.
106+
# Akamai's cache flush requests are case-sensitive, and some clients (e.g., dnf)
107+
# request the lowercase percent-encoded path.
108+
if path != encoded_path:
109+
paths_to_flush.extend(
110+
[
111+
encoded_path,
112+
self._lowercase_percent_encoding(encoded_path),
113+
]
114+
)
102115

103116
for path_variant in paths_to_flush:
104117
# Figure out the templates applicable to this path

tests/worker/test_cdn_cache.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,22 +319,31 @@ def test_flush_cdn_cache_typical(
319319
"https://cdn2.example.com/root/some/kickstart/treeinfo",
320320
"https://cdn2.example.com/root/third/path",
321321
# Flush both encoded and non-encoded paths for modular RPMs
322+
# Includes both uppercase (%2B) and lowercase (%2b) percent-encoding
322323
"https://cdn1.example.com/path/one-dest/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm",
323324
"https://cdn1.example.com/path/one-dest/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm",
325+
"https://cdn1.example.com/path/one-dest/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm",
324326
"https://cdn1.example.com/path/one/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm",
325327
"https://cdn1.example.com/path/one/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm",
328+
"https://cdn1.example.com/path/one/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm",
326329
"https://cdn2.example.com/root/path/one-dest/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm",
327330
"https://cdn2.example.com/root/path/one-dest/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm",
331+
"https://cdn2.example.com/root/path/one-dest/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm",
328332
"https://cdn2.example.com/root/path/one/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm",
329333
"https://cdn2.example.com/root/path/one/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm",
334+
"https://cdn2.example.com/root/path/one/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm",
330335
"S/=/123/4567/30d/cdn1.example.com/path/one-dest/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm cid=///",
331336
"S/=/123/4567/30d/cdn1.example.com/path/one-dest/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm cid=///",
337+
"S/=/123/4567/30d/cdn1.example.com/path/one-dest/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm cid=///",
332338
"S/=/123/4567/30d/cdn1.example.com/path/one/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm cid=///",
333339
"S/=/123/4567/30d/cdn1.example.com/path/one/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm cid=///",
340+
"S/=/123/4567/30d/cdn1.example.com/path/one/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm cid=///",
334341
"S/=/234/6677/30d/cdn2.example.com/other/path/one-dest/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm x/y/z",
335342
"S/=/234/6677/30d/cdn2.example.com/other/path/one-dest/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm x/y/z",
343+
"S/=/234/6677/30d/cdn2.example.com/other/path/one-dest/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm x/y/z",
336344
"S/=/234/6677/30d/cdn2.example.com/other/path/one/galera-26.4.20-1.module+el9.5.0+22578+dc54e53f.x86_64.rpm x/y/z",
337345
"S/=/234/6677/30d/cdn2.example.com/other/path/one/galera-26.4.20-1.module%2Bel9.5.0%2B22578%2Bdc54e53f.x86_64.rpm x/y/z",
346+
"S/=/234/6677/30d/cdn2.example.com/other/path/one/galera-26.4.20-1.module%2bel9.5.0%2b22578%2bdc54e53f.x86_64.rpm x/y/z",
338347
]
339348
)
340349

0 commit comments

Comments
 (0)