33import gzip
44import json
55import os
6+ import re
67import time
78from base64 import b64decode
89from datetime import datetime , timedelta , timezone
@@ -87,7 +88,7 @@ def definitions(self):
8788
8889 return out
8990
90- def uri_alias (self , uri , aliases ):
91+ def uri_alias (self , uri , aliases , ignore_exclusions = False ):
9192 # Resolve every alias between paths within the uri (e.g.
9293 # allow RHUI paths to be aliased to non-RHUI).
9394 #
@@ -102,7 +103,15 @@ def uri_alias(self, uri, aliases):
102103 processed = []
103104
104105 for alias in remaining :
105- if uri .startswith (alias ["src" ] + "/" ) or uri == alias ["src" ]:
106+ exclusion_match = not ignore_exclusions and any (
107+ [
108+ re .search (exclusion , uri )
109+ for exclusion in alias .get ("exclude_paths" , [])
110+ ]
111+ )
112+ if (
113+ uri .startswith (alias ["src" ] + "/" ) or uri == alias ["src" ]
114+ ) and not exclusion_match :
106115 uri = uri .replace (alias ["src" ], alias ["dest" ], 1 )
107116 processed .append (alias )
108117
@@ -117,17 +126,23 @@ def uri_alias(self, uri, aliases):
117126
118127 return uri
119128
120- def resolve_aliases (self , uri ):
129+ def resolve_aliases (self , uri , ignore_exclusions = False ):
121130 # aliases relating to origin, e.g. content/origin <=> origin
122- uri = self .uri_alias (uri , self .definitions .get ("origin_alias" ))
123131
132+ uri = self .uri_alias (
133+ uri , self .definitions .get ("origin_alias" ), ignore_exclusions
134+ )
124135 # aliases relating to rhui; listing files are a special exemption
125136 # because they must be allowed to differ for rhui vs non-rhui.
126137 if not uri .endswith ("/listing" ):
127- uri = self .uri_alias (uri , self .definitions .get ("rhui_alias" ))
138+ uri = self .uri_alias (
139+ uri , self .definitions .get ("rhui_alias" ), ignore_exclusions
140+ )
128141
129142 # aliases relating to releasever; e.g. /content/dist/rhel8/8 <=> /content/dist/rhel8/8.5
130- uri = self .uri_alias (uri , self .definitions .get ("releasever_alias" ))
143+ uri = self .uri_alias (
144+ uri , self .definitions .get ("releasever_alias" ), ignore_exclusions
145+ )
131146
132147 self .logger .debug ("Resolved request URI: %s" , uri )
133148
@@ -304,33 +319,8 @@ def validate_request(self, request):
304319 valid = False
305320 return valid
306321
307- def handler (self , event , context ):
308- # pylint: disable=unused-argument
309-
310- request = event ["Records" ][0 ]["cf" ]["request" ]
311-
312- if not self .validate_request (request ):
313- return {"status" : "400" , "statusDescription" : "Bad Request" }
314-
315- self .logger .debug (
316- "Incoming request value for origin_request" ,
317- extra = {"request" : request },
318- )
319-
320- request ["uri" ] = unquote (request ["uri" ])
321- original_uri = request ["uri" ]
322-
323- if request ["uri" ].startswith ("/_/cookie/" ):
324- return self .handle_cookie_request (event )
325-
326- uri = self .resolve_aliases (request ["uri" ])
327-
328- listing_response = self .handle_listing_request (uri )
329- if listing_response :
330- self .set_cache_control (uri , listing_response )
331- return listing_response
332-
333- table = self .conf ["table" ]["name" ]
322+ def handle_file_request (self , request , table , original_uri , uri ):
323+ # Try find the db entry corresponding to the uri.
334324
335325 # Do not permit clients to explicitly request an index file
336326 if not uri .endswith ("/" + self .index ):
@@ -374,7 +364,47 @@ def handler(self, event, context):
374364 return response
375365
376366 return out
377- self .logger .info ("No item found for URI: %s" , uri )
367+
368+ def handler (self , event , context ):
369+ # pylint: disable=unused-argument
370+ request = event ["Records" ][0 ]["cf" ]["request" ]
371+
372+ if not self .validate_request (request ):
373+ return {"status" : "400" , "statusDescription" : "Bad Request" }
374+
375+ self .logger .debug (
376+ "Incoming request value for origin_request" ,
377+ extra = {"request" : request },
378+ )
379+
380+ request ["uri" ] = unquote (request ["uri" ])
381+ original_uri = request ["uri" ]
382+
383+ if request ["uri" ].startswith ("/_/cookie/" ):
384+ return self .handle_cookie_request (event )
385+
386+ preferred_uri = self .resolve_aliases (request ["uri" ])
387+ fallback_uri = self .resolve_aliases (
388+ request ["uri" ], ignore_exclusions = True
389+ )
390+ uris = [preferred_uri ]
391+ # Some file keys might take a while to update to reflect URI alias exclusions.
392+ # Allowing the original behaviour as a fallback will avoid a flood of 404 errors
393+ if preferred_uri != fallback_uri :
394+ uris .append (fallback_uri )
395+
396+ for uri in uris :
397+ if listing_response := self .handle_listing_request (uri ):
398+ self .set_cache_control (uri , listing_response )
399+ return listing_response
400+
401+ table = self .conf ["table" ]["name" ]
402+ if out := self .handle_file_request (
403+ request , table , original_uri , uri
404+ ):
405+ return out
406+
407+ self .logger .info ("No item found for URI: %s" , uri )
378408 return {"status" : "404" , "statusDescription" : "Not Found" }
379409
380410
0 commit comments