@@ -62,6 +62,12 @@ func handleImageRequest(logger *zap.Logger, cache *ristretto.Cache[string, Cache
6262
6363// processImageResponse handles the common image processing logic
6464func processImageResponse (c * fiber.Ctx , logger * zap.Logger , cache * ristretto.Cache [string , CacheValue ], config * config.Config , counters * metrics.Metrics , params * validation.ImageContext , s3cache * S3Cache ) error {
65+ // If no URL is provided but a custom location is set, this is location-based retrieval only
66+ if params .Url == "" && params .CustomObjectKey == "" {
67+ logger .Error ("neither url nor custom location provided" , zap .String ("custom_object_key" , params .CustomObjectKey ))
68+ return c .Status (fiber .StatusBadRequest ).SendString ("neither url nor custom location provided" )
69+ }
70+
6571 cacheKey := cacheKey (params .Url , params )
6672 cacheValue , ok := cache .Get (cacheKey )
6773 if ok {
@@ -86,17 +92,28 @@ func processImageResponse(c *fiber.Ctx, logger *zap.Logger, cache *ristretto.Cac
8692 }
8793 }
8894
89- if s3val , err := s3cache .Get (context .Background (), cacheKey ); err == nil && s3val != nil {
90- counters .SuccessfullyServed .WithLabelValues ("image" , metrics .CleanHostname (params .Hostname ), metrics .HashURL (params .Url )).Inc ()
91- counters .ServedCached .WithLabelValues ("image" , metrics .CleanHostname (params .Hostname ), metrics .HashURL (params .Url )).Inc ()
92- c .Set ("Content-Type" , s3val .ContentType )
93- c .Set ("X-Cache-Place" , cachePlaceS3Cache )
94- // backfill in-memory cache
95- cache .SetWithTTL (cacheKey , * s3val , 1000 , time .Duration (config .CacheTTL )* time .Second )
96- return c .Send (s3val .Body )
95+ if params .Url != "" {
96+ if s3val , err := s3cache .Get (context .Background (), cacheKey ); err == nil && s3val != nil {
97+ counters .SuccessfullyServed .WithLabelValues ("image" , metrics .CleanHostname (params .Hostname ), metrics .HashURL (params .Url )).Inc ()
98+ counters .ServedCached .WithLabelValues ("image" , metrics .CleanHostname (params .Hostname ), metrics .HashURL (params .Url )).Inc ()
99+ c .Set ("Content-Type" , s3val .ContentType )
100+ c .Set ("X-Cache-Place" , cachePlaceS3Cache )
101+ // backfill in-memory cache
102+ cache .SetWithTTL (cacheKey , * s3val , 1000 , time .Duration (config .CacheTTL )* time .Second )
103+ logger .Debug ("image served from S3 cache" , zap .String ("cache_key" , cacheKey ), zap .String ("content_type" , s3val .ContentType ), zap .String ("url" , params .Url ))
104+ return c .Send (s3val .Body )
105+ } else if err != nil {
106+ logger .Debug ("S3 cache lookup failed" , zap .String ("cache_key" , cacheKey ), zap .Error (err ), zap .String ("url" , params .Url ))
107+ }
97108 }
98109 }
99110
111+ // If no URL is provided at this point, we can only serve from S3 cache
112+ if params .Url == "" {
113+ logger .Error ("image not found in S3 cache and no URL provided to fetch from remote" , zap .String ("custom_object_key" , params .CustomObjectKey ))
114+ return c .Status (fiber .StatusNotFound ).SendString ("image not found" )
115+ }
116+
100117 response , err := client .GetHTTPClient ().Get (params .Url )
101118 if err != nil {
102119 logger .Error ("failed to fetch image" , zap .Error (err ), zap .String ("url" , params .Url ), zap .String ("hostname" , params .Hostname ))
0 commit comments