5
votes

I see people talking about how to rewrite a URI based on various information. But I'd like to normalize the domain name that is being requested. Here's what I've tried:

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

    if (request.method.toUpperCase() != 'GET') {
        callback(null, request);
        return;
    }

    request.origin = {
        custom: {
            domainName: 'slashdot.org',
            port: 443,
            protocol: 'https',
            path: request.uri
        }
    };
    request.headers.host = {
        "key": "Host",
        "value": request.origin.custom.domainName
    };

    console.log("returning req:", request);

    callback(null, request);
}

I was hoping that would pull up the request and that cloudfront would then make a request against my canonicalized domain. (for the example and testing, I'm using slashdot, since it's obvious it isn't my content).

Ultimately, I'm trying to canonicalize a request without doing redirects, but instead rewriting the request before hit hits the origin.

1
You shouldn't test against anybody else's site, because in addition to the etiquette aspect, they may have scraping protections or other anti-abuse mechanisms in place that cause the site to behave unexpectedly in cases like this.Michael - sqlbot
Does this not work for you ?Archit Jain
No, it doesn't work. I haven't been able to rewrite a request.tedder42

1 Answers

6
votes

Oh, neat. I finally figured out how to do this. First, some restrictions:

  • With https this only works for domains under your certificate. So I can't use mydomain.com and slashdot.org unless I'm CmdrTaco. That's fine, my AWS ACM cert includes three domains, one of which is my actual domain. I'll call that actualdomain.com below.
  • This cannot be done on the viewer request, only the origin request, as host is read-only for the viewer request.

Given that, I used "Example: Using an Origin-Request Trigger to Change From an Amazon S3 Origin to a Custom Origin" with some minor modifications. Here's the full Lambda code.

'use strict';

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const destDomain = 'actualdomain.com';


    /* Set custom origin fields*/
    request.origin = {
        custom: {
            domainName: destDomain,
            port: 443,
            protocol: 'https',
            path: '',
            sslProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2'],
            readTimeout: 5,
            keepaliveTimeout: 5,
            customHeaders: {}
        }
    };
    request.headers['host'] = [{ key: 'host', value: destDomain}];

    callback(null, request);
};

So, similar to the example given in the docs, destDomain is the actual domain, and any legitimate domain in my certificate is proxied to that dest, without the end user actually seeing actualdomain.com.