最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

amazon web services - Lambda@Edge not getting triggered when hitting cloudfront - Stack Overflow

programmeradmin1浏览0评论

I have a cloudfront that is supposed to get images from 2 different S3 buckets. Fetching logic is decided by my lambda function based on the URL.

I have created a CloudFront

  1. added both the buckets as origin
  2. In default(*) behaviour, selected one of my buckets and added my lambda function's latest version in Origin Request as I want cache to handle incoming request and only call my lambda when cache missed.

In my lambda function

  1. Added necessary permissions for CloudWatch, CloudFront and S3.

When I hit the cloudfront URL for a specific object, it is not calling my lambda at all. I am able to access data in the bucket through cloudfront that I mentioned in my default behaviour. Which means there is no issue in Cloudfront able to connect to S3.

For all other URLs(which should have been handled by the Lambda) it is returning 403.

I have tried to verify requried permissions and connected Lambda edge with cloudfront as per docs, and expected Lambda to be called.

Also I am new to AWS and handling everything from console.

Edit 1 -

Adding my code

import { S3Client, HeadObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({ region: "us-east-1" });
const ORIGINAL_BUCKET = "abc";
const RESIZED_BUCKET = "def";

export const handler = async (event) => {
    console.log("cloudfront-image-redirect lambda called");
    try {
        const { request } = event.Records[0].cf;
        let uri = request.uri; // Example: /products/12345/red/winter/thumbnails/image1.jpg

        console.log(`Received request for: ${uri}`);

        // Extract productId, size, filename, and any nested paths (variation ID)
        const match = uri.match(/^\/products\/([^/]+)\/((?:[^/]+\/)*)([^/]+)\/([^/]+)$/) || [];
        const [, productId, nestedPath = "", size, fileName] = match;

        if (!productId || !size || !fileName) {
            console.log("Invalid URI structure:", uri);
            return request; // If invalid, let CloudFront handle it
        }

        // Remove trailing slash from nestedPath
        let variationPath = nestedPath.replace(/\/$/, "");

        // Determine the correct bucket to check
        let bucketToCheck, s3Key;

        if (size === "original") {
            bucketToCheck = ORIGINAL_BUCKET;
            s3Key = variationPath
                ? `products/${productId}/${variationPath}/${fileName}`
                : `products/${productId}/${fileName}`;
        } else {
            bucketToCheck = RESIZED_BUCKET;
            s3Key = variationPath
                ? `products/${productId}/${variationPath}/${size}/${fileName}`
                : `products/${productId}/${size}/${fileName}`;
        }

        try {
            // ✅ Try fetching the exact image
            await s3.send(new HeadObjectCommand({ Bucket: bucketToCheck, Key: s3Key }));
            console.log(`Serving from ${bucketToCheck}: ${s3Key}`);
            return request;
        } catch (error) {
            console.log(`Image not found: ${s3Key} in ${bucketToCheck}`);
        }

        // ✅ Fall back to the closest available image by reducing nested path depth
        let pathSegments = variationPath.split("/").filter(Boolean);

        while (pathSegments.length > 0) {
            let reducedPath = pathSegments.join("/");
            let fallbackKey = size === "original"
                ? `products/${productId}/${reducedPath}/${fileName}`
                : `products/${productId}/${reducedPath}/${size}/${fileName}`;

            try {
                await s3.send(new HeadObjectCommand({ Bucket: bucketToCheck, Key: fallbackKey }));
                console.log(`Falling back to: ${fallbackKey}`);
                request.uri = `/products/${productId}/${reducedPath}/${size}/${fileName}`;
                return request;
            } catch (error) {
                console.log(`Fallback not found: ${fallbackKey}`);
            }

            pathSegments.pop(); // Remove the last segment and try again
        }

        // ✅ Final fallback to completely original image (no variations)
        if (size !== "original") {
            let fallbackOriginalKey = `products/${productId}/${fileName}`;
            try {
                await s3.send(new HeadObjectCommand({ Bucket: ORIGINAL_BUCKET, Key: fallbackOriginalKey }));
                console.log(`Final fallback to original: ${fallbackOriginalKey}`);
                request.uri = `/products/${productId}/original/${fileName}`;
                return request;
            } catch (error) {
                console.log("Original image not found either.");
            }
        }

        console.log("No suitable image found, returning default response");
        return request; // Let CloudFront handle 404
    } catch (error) {
        console.error("Lambda Execution Error:", error);
        return {
            status: "500",
            statusDescription: "Internal Server Error",
            body: JSON.stringify({ error: "Lambda function execution failed." }),
        };
    }
};

发布评论

评论列表(0)

  1. 暂无评论