[小ネタ]Lambda@Edge で別のサイトの情報を取得してみた

Lambda@Edgeで、URLリクエストを行いコンテンツを返すサンプルコードです。
2022.07.07

7月7日本日はクラスメソッドの創立記念日ということで、多くのブログが投稿されているかと思います。

そこで、Lambda@EdgeからDevelopersIOの情報を取得して見ようと思います。

というのは、建前で。

Lambda@Edgeの処理でエラーステータスコードを書き換えたり、簡易でコンテンツを返したいときにS3や特定のURLから情報を取得するサンプルがあまり見つからなかったのでご共有します。

取得するURLによっては、時間がかかりエラーとなる場合もありますので取得先のサイトはS3やご自分の管理下のサイトとしてください。

Lambda@Edgeでエラーが多い場合は、CloudFrontの方でリクエストができなくなる場合ありますのでご注意ください。

ということで、以下Lambda@Edgeのコードです。

Lambda@Edge 関数

Lambda@Edge関数を作成し、オリジンリクエストとして指定します。

Bodyの内容を書き換えているので、特にオリジンには依存しません。

URL = 'https://dev.classmethod.jp'

の部分を取得元のURLに変更すれば、Lambda@Edgeの中でコンテンツを取得し、クライアントに返します。

import urllib.request

def request_get(url: str):
    try:
        req = urllib.request.Request(url, method='GET')
        res = urllib.request.urlopen(req)
    except urllib.error.HTTPError as e:
        print(e.code)
        print(e.reason)
    else:
        # print(res.status)
        return res.read().decode('utf-8')

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']

    URL = 'https://dev.classmethod.jp'
    
    CONTENT = request_get(URL)

    # Generate HTTP OK response using 200 status code with HTML body.
    response = {
        'status': '200',
        'statusDescription': 'OK',
        'headers': {
            'cache-control': [
                {
                    'key': 'Cache-Control',
                    'value': 'max-age=100'
                }
            ],
            "content-type": [
                {
                    'key': 'Content-Type',
                    'value': 'text/html'
                }
            ]
        },
        'body': CONTENT
    }

    # print(response)
    return response

requests ライブラリをurllib として追加のライブラリなしで取得するようにしています。

まとめ

備忘録レベルですが、コードを共有します。 勘の良い方向けですが、request['uri'] にクライアントからリクエストされるURIが含まれるのでリクエストによって処理を変更するといろいろ応用がきくかと思います。

参考

requestsライブラリを使わず ‘botocore.vendored.requests’ を置き換える

レスポンスの生成

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html#lambda-examples-static-web-server