はじめに
CloudFront にきた特定ホスト向けのリクエストを、 Lambda@Edge(以後L@E) で URI を維持しながらリダイレクトするコードを Node.js で書いてみました。
記事目安...5分~10分
コードについて
'use strict';
// Input Redirect source URL & Redirect URL.
const redirectSrcHost = 'hogehoge.com';
const redirectHost = 'www.hogehoge.com';
exports.handler = (event, context, callback) => {
const originalRequest = event.Records[0].cf.request;
//Extact require param from "originalRequest".
const originalHost = originalRequest.headers.host[0].value;
const originalUri = originalRequest.uri;
// response to User or Origin.
if (originalHost == redirectSrcHost){
//Generate HTTP redirect response.
const redirectResponse = {
status: '301',
statusDescription: 'Redirect',
headers: {
'location': [{
key: 'Location',
value: 'https://' + redirectHost + originalUri,
}],
},
};
callback(null, redirectResponse);
} else {
callback(null, originalRequest)
}
};
サンプルでは、URI を維持したまま hogehoge.com → www.hogehoge.com にリダイレクトします。
hogehoge.com 以外のホスト名指定でリクエストが来た場合は、オリジンにリクエストを通します。
使い方
STEP1. コードを変更する
redirectSrcHostにリダイレクト元のホスト名を挿入します
const redirectSrcHost = 'hogehoge.com';
redirectHostにリダイレクト先のホスト名を挿入します
const redirectHost = 'www.hogehoge.com';
STEP2. L@E をデプロイする
デプロイの詳細手順は省きますが、
L@E の処理をキャッシュしたい場合は、 オリジンリクエスト にデプロイしてください。
テスト用リクエストについて
Lambda でのテストで使用したリクエストの Json もおいておきます。
パターン1: hogehoge.com へリクエストを投げた場合
{ "Records": [ { "cf": { "config": { "distributionDomainName": "d111111abcdef8.cloudfront.net", "distributionId": "EDFDVBD6EXAMPLE", "eventType": "origin-request", "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ==" }, "request": { "clientIp": "203.0.113.178", "headers": { "x-forwarded-for": [ { "key": "X-Forwarded-For", "value": "203.0.113.178" } ], "user-agent": [ { "key": "User-Agent", "value": "Amazon CloudFront" } ], "via": [ { "key": "Via", "value": "2.0 2afae0d44e2540f472c0635ab62c232b.cloudfront.net (CloudFront)" } ], "host": [ { "key": "Host", "value": "hogehoge.com" } ], "cache-control": [ { "key": "Cache-Control", "value": "no-cache, cf-no-cache" } ] }, "method": "GET", "origin": { "custom": { "customHeaders": {}, "domainName": "hogehoge.com", "keepaliveTimeout": 5, "path": "", "port": 443, "protocol": "https", "readTimeout": 30, "sslProtocols": [ "TLSv1", "TLSv1.1", "TLSv1.2" ] } }, "querystring": "", "uri": "/test" } } } ] }
パターン2: fugafuga.hogehoge.com へリクエストを投げた場合
{ "Records": [ { "cf": { "config": { "distributionDomainName": "d111111abcdef8.cloudfront.net", "distributionId": "EDFDVBD6EXAMPLE", "eventType": "origin-request", "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ==" }, "request": { "clientIp": "203.0.113.178", "headers": { "x-forwarded-for": [ { "key": "X-Forwarded-For", "value": "203.0.113.178" } ], "user-agent": [ { "key": "User-Agent", "value": "Amazon CloudFront" } ], "via": [ { "key": "Via", "value": "2.0 2afae0d44e2540f472c0635ab62c232b.cloudfront.net (CloudFront)" } ], "host": [ { "key": "Host", "value": "fugafuga.hogehoge.com" } ], "cache-control": [ { "key": "Cache-Control", "value": "no-cache, cf-no-cache" } ] }, "method": "GET", "origin": { "custom": { "customHeaders": {}, "domainName": "fugafuga.hogehoge.com", "keepaliveTimeout": 5, "path": "", "port": 443, "protocol": "https", "readTimeout": 30, "sslProtocols": [ "TLSv1", "TLSv1.1", "TLSv1.2" ] } }, "querystring": "", "uri": "/test" } } } ] }
参考: Lambda@Edge イベント構造 - Amazon CloudFront -オリジンリクエストの例
参考
菅谷 歩 (記事一覧)