Skip to content
Advertisement

AWS Lambda@Edge 502 LambdaValidationError in CloudFront for redirect

I have a lambda function which performs 301 redirect if it has uri that is generated using regex.

const redirects = {
    xyz: '/contact',
    abc: '/about',
};

const arrRegex = [
    { regex: /xyz/faq/max, redirect: redirects.xyz },
    { regex: /abc/faq/min, redirect: redirects.abc },
    { regex: /lmn?page=[1-9]/, redirectNotNeeded }
];

function redirect(request) {
    
    let requests = request.uri;
    let finalUrl = '';

    arrRegex.some(reg => {
        const re = new RegExp(reg.regex);
        if (requests.match(re) && reg.redirectNotNeeded) {
            finalUrl = request;
            return true;
        } else if (requests.match(re) && reg.redirect) {
            finalUrl = reg.redirect;
            return true;
        } else {
            return requests.match(re) && !reg.redirect;
        }
    });
    return finalUrl;
}

exports.handler = (event, context, callback) => {
    
    // find request URL
    const request = event.Records[0].cf.request;
    request.uri = redirect(request);

    
    let prefixPath; // needed for 2nd condition

    if (request.uri.match('.+/$')) {
    request.uri += 'index.html';
    callback(null, request);
    } else if (prefixPath = request.uri.match('(.+)/index.html')) {
    const response = {
      status: '301',
      statusDescription: 'Found',
      headers: {
        location: [{
          key: 'Location', value: prefixPath[1] + '/',
        }],
      }
    };
    callback(null, response);
    } else if (request.uri.match('/[^/.]+$')) {
    const response = {
      status: '301',
      statusDescription: 'Found',
      headers: {
        location: [{
          key: 'Location', value: request.uri + '/',
        }],
      }
    };
    callback(null, response);
    } else {
    callback(null, request);
    }
};

On deploying the function and adding it to the cloudfront behaviors, when I go to to the url https:my-website/xyz/faq/max, eventhough I see the status of 301 for https:my-website/xyz/faq/max after correctly re-routing to https:my-website/contact, it shows 502 Error. It shows the same error for https:my-website as well. In the chrome under status I see LambdaValidationError from cloudfront under Response Header. May I know what am I doing wrong here to throw this error? The pages are just static pages stored in AWS S3 bucket served using Amazon CloudFront.

Advertisement

Answer

Changing let finalUrl = ''; to let finalUrl = request.uri; helped me get rid of the error as I was setting it to empty string, the lambda was throwing 502 error as it wasn’t able re-direct the traffic when there is no uri in the request.

const redirects = {
    xyz: '/contact',
    abc: '/about',
};

const arrRegex = [
    { regex: /xyz/faq/max, redirect: redirects.xyz },
    { regex: /abc/faq/min, redirect: redirects.abc },
    { regex: /lmn?page=[1-9]/, redirectNotNeeded }
];

function redirect(request) {
    
    let requests = request.uri;
    let finalUrl = request.uri;

    arrRegex.some(reg => {
        const re = new RegExp(reg.regex);
        if (requests.match(re) && reg.redirectNotNeeded) {
            finalUrl = request;
            return true;
        } else if (requests.match(re) && reg.redirect) {
            finalUrl = reg.redirect;
            return true;
        } else {
            return requests.match(re) && !reg.redirect;
        }
    });
    return finalUrl;
}

exports.handler = (event, context, callback) => {
    
    // find request URL
    const request = event.Records[0].cf.request;
    request.uri = redirect(request);

    
    let prefixPath; // needed for 2nd condition

    if (request.uri.match('.+/$')) {
    request.uri += 'index.html';
    callback(null, request);
    } else if (prefixPath = request.uri.match('(.+)/index.html')) {
    const response = {
      status: '301',
      statusDescription: 'Found',
      headers: {
        location: [{
          key: 'Location', value: prefixPath[1] + '/',
        }],
      }
    };
    callback(null, response);
    } else if (request.uri.match('/[^/.]+$')) {
    const response = {
      status: '301',
      statusDescription: 'Found',
      headers: {
        location: [{
          key: 'Location', value: request.uri + '/',
        }],
      }
    };
    callback(null, response);
    } else {
    callback(null, request);
    }
};
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement