从AWS中的通配符域提供大量静态站点 [英] Serving a multitude of static sites from a wildcard domain in AWS

查看:115
本文介绍了从AWS中的通配符域提供大量静态站点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里遇到了一个非常具体的问题,我们已经拥有并维护了一个系统,该系统涉及使用子域将人员路由到特定应用.

I've got a pretty specific problem here, we've got a system that we already have and maintain, the system involves using subdomains to route people to specific apps.

如下所示;我们有一个通配符子域* .domain.com,该子域路由到nginx并提供一个文件夹

on a traditional server that goes like follows; we have a wildcard subdomain, *.domain.com that routes to nginx and serves up a folder

所以myapp.domain.com> nginx>提供了myapp应用文件夹> myapp文件夹包含静态站点

so myapp.domain.com > nginx > serves up myapp app folder > myapp folder contains a static site

我正在尝试以某种方式将此迁移到AWS,我基本上需要在AWS中做类似的事情,我的想法是将每个静态应用程序放入s3存储桶,然后放入53号路由中的通配符域,但是我不确定s3如何知道要提供哪个文件夹,因为该功能不是Route 53的一部分

I'm trying to migrate this in some way to AWS, I basically need to do a similar thing in AWS, I toyed with the idea of putting each static app into an s3 bucket and then the wildcard domain in route 53 but i'm unsure how s3 would know which folder to serve up as that functionality isn't part of route 53

有人有建议吗?

感谢您的所有帮助

推荐答案

CloudFront + Lambda @ Edge + S3可以做到此无服务器".

CloudFront + Lambda@Edge + S3 can do this "serverless."

Lambda @ Edge是CloudFront的增强功能,它允许将请求和响应的属性表示和操纵为简单的JavaScript对象.可以设置触发器以在请求处理期间触发,可以在检查缓存之前(查看器请求"触发器),也可以在请求进行到后端之前(在这种情况下为S3网站托管端点起源服务器")在缓存未命中(原始请求"触发器)之后...或在响应处理期间,从原始接收到响应之后,才考虑将其存储在CloudFront缓存中(原始响应"触发器),或者在完成对浏览器的响应(查看器响应"触发器).响应触发器还可以检查原始请求对象.

Lambda@Edge is a CloudFront enhancement that allows attributes of requests and responses to be represented and manipulated as simple JavaScript objects. Triggers can be provisioned to fire during request processing, either before the cache is checked ("viewer request" trigger) or before the request proceeds to the back-end ("origin server", an S3 web site hosting endpoint, in this case) following a cache miss ("origin request" trigger)... or during response processing, after the response is received from the origin but before it is considered for storing in the CloudFront cache ("origin response" trigger), or when finalizing the response to the browser ("viewer response" trigger). Response triggers can also examine the original request object.

以下代码段是我最初发布的内容AWS论坛.它是一个Origin Request触发器,用于将原始主机名与您的模式进行比较(例如,域必须匹配*.example.com),如果匹配,则主机名前缀subdomain-here.example.com是从为该子域命名的文件夹中请求的.

The following snippet is something I originally posted at the AWS Forums. It is an Origin Request trigger which compares the original hostname to your pattern (e.g. the domain must match *.example.com) and if it does, the hostname prefix subdomain-here.example.com is request is served from a folder named for the subdomain.

lol.example.com/cat.jpg        -> my-bucket/lol/cat.jpg
funny-pics.example.com/cat.jpg -> my-bucket/funny-pics/cat.jpg

通过这种方式,可以从一个存储桶中提供任意数量的子域中的静态内容.

In this way, static content from as many subdomains as you like can all be served from a single bucket.

为了访问原始传入的Host标头,需要将CloudFront配置为

In order to access the original incoming Host header, CloudFront needs to be configured to whitelist the Host header for forwarding to the origin even though the net result of the Lambda function's execution will be to modify that value before the origin acually sees it.

该代码实际上非常简单-以下大部分是解释性注释.

The code is actually very simple -- most of the following is explanatory comments.

'use strict';

// if the end of incoming Host header matches this string, 
// strip this part and prepend the remaining characters onto the request path,
// along with a new leading slash (otherwise, the request will be handled
// with an unmodified path, at the root of the bucket)

const remove_suffix = '.example.com';

// provide the correct origin hostname here so that we send the correct 
// Host header to the S3 website endpoint

const origin_hostname = 'example-bucket.s3-website.us-east-2.amazonaws.com'; // see comments, below

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

    if(host_header.endsWith(remove_suffix))
    {
        // prepend '/' + the subdomain onto the existing request path ("uri")
        request.uri = '/' + host_header.substring(0,host_header.length - remove_suffix.length) + request.uri;
    }

    // fix the host header so that S3 understands the request
    headers.host[0].value = origin_hostname;

    // return control to CloudFront with the modified request
    return callback(null,request);
};

请注意,索引文档和从S3重定向也可能需要Origin Response触发器,以针对原始请求将Location标头标准化.这将取决于您所使用的S3网站功能.但是,以上是一个可以说明总体思路的有效示例.

Note that index documents and redirects from S3 may also require an Origin Response trigger to normalize the Location header against the original request. This will depend on exactly which S3 website features you use. But the above is a working example that illustrates the general idea.

请注意,需要按照CloudFront原始设置中的配置将const origin_hostname设置为存储桶的端点主机名.在此示例中,存储桶位于us-east-2中,并且网站托管功能处于活动状态.

Note that const origin_hostname needs to be set to the bucket's endpoint hostname as configured in the CloudFront origin settings. In this example, the bucket is in us-east-2 with the web site hosting feature active.

这篇关于从AWS中的通配符域提供大量静态站点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆