繁体   English   中英

具有行为路径重定向的多个 Cloudfront 源

[英]Multiple Cloudfront Origins with Behavior Path Redirection

我有两个 S3 存储桶用作我的 Cloudfront 源服务器:

example-bucket-1
example-bucket-2

两个存储桶的内容都位于这些存储桶的根目录中。 我正在尝试将我的 Cloudfront 分发配置为基于 URL 模式进行路由或重写。 例如,使用这些文件

example-bucket-1/something.jpg
example-bucket-2/something-else.jpg

我想让这些 URL 指向相应的文件

http://example.cloudfront.net/path1/something.jpg
http://example.cloudfront.net/path2/something-else.jpg

我尝试设置匹配 path1 和 path2 模式的缓存行为,但它不起作用。 这些模式是否必须实际存在于 S3 存储桶中?

更新:原始答案(如下所示)在 2015 年编写时是准确的,并且基于 CloudFront 本身的内置行为是正确的。 最初,整个请求路径需要存在于原点。

如果 URI 是/download/images/cat.png但源只需要/images/cat.png那么 CloudFront 缓存行为/download/*将不会执行您可能假设的操作——缓存行为的路径模式仅用于匹配-- 匹配的前缀不会被删除。

在向源发送请求时,CloudFront 本身不提供从浏览器请求的路径中删除元素的方法。 如果指定了原始路径,则请求总是在收到时转发,或者在开头带有额外的字符。

然而,2017 年Lambda@Edge的引入改变了动态。

Lambda@Edge 允许您在 CloudFront 流中声明触发器挂钩并编写小的 Javascript 函数来检查和修改传入请求,无论是在检查 CloudFront 缓存之前(查看器请求),还是在检查缓存之后(源请求)。 这允许您重写请求 URI 中的路径。 例如,您可以将/download/images/cat.png浏览器中的请求路径转换为删除/download ,从而将请求发送到/images/cat.png S3(或自定义源)。

此选项不会修改哪个缓存行为将实际为请求提供服务,因为这始终基于浏览器请求的路径——但您可以在运行中修改路径,以便实际请求的对象位于其他路径比浏览器请求的那个。 在 Origin Request 触发器中使用时,响应缓存在浏览器请求的路径下,因此不需要重写后续响应——它们可以从缓存中提供——并且触发器不需要触发对于每个请求。

Lambda@Edge 函数的实现非常简单。 这是一个示例函数,它将删除第一个路径元素,无论它是什么。

'use strict';

// lambda@edge Origin Request trigger to remove the first path element
// compatible with either Node.js 6.10 or 8.10 Lambda runtime environment

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;           // extract the request object
    request.uri = request.uri.replace(/^\/[^\/]+\//,'/');  // modify the URI
    return callback(null, request);                        // return control to CloudFront
};

就是这样。 .replace(/^\\/[^\\/]+\\//,'/') ,我们将 URI 与匹配前导/后跟 1 个或多个不能是/字符的正则表达式匹配,然后再添加一个/ ,并用单个/替换整个匹配项——因此无论abc的确切值如何,路径都会从/abc/def/ghi/...重写为/def/ghi/... 这可能会变得更复杂以适应特定的要求,而不会显着增加执行时间……但请记住,Lambda@Edge 函数与一个或多个缓存行为相关联,因此您不需要单个函数来处理所有请求通过分发——只是与相关缓存行为的路径模式匹配的请求。

要简单地在来自浏览器的请求中添加前缀,仍然可以使用 Origin Path 设置,如下所述,但删除或修改路径组件需要 Lambda@Edge,如上所述。


原答案

是的,模式必须存在于原点。

CloudFront 本身可以预先添加到给定源的路径,但它目前没有删除路径元素的能力(没有 Lambda@Edge,如上所述)。

如果您的文件在源的/secret/files/中,您可以通过设置“源路径”在将请求发送到源之前转换路径模式/files/*

反之则不然。 如果文件位于/files中,则没有内置方法可以从路径模式/download/files/*提供这些文件。

您可以添加(前缀)但不能删除。

一个相对简单的解决方法是在与 S3 存储桶位于同一区域的 EC2 实例上使用反向代理服务器,将 CloudFront 指向代理,将代理指向 S3。 代理将在到达 S3 的途中重写 HTTP 请求,并将结果响应流式传输回 CloudFront。 我使用这样的设置,它的性能从未让我失望。 (我开发的反向代理软件实际上可以并行或串行检查多个存储桶,并将它收到的第一个非错误响应返回给 CloudFront 和请求者)。

或者,如果使用 S3 网站终端节点作为自定义源,您可以使用 S3 重定向路由规则将重定向返回到 CloudFront,将删除未处理前缀的浏览器发送回。 这意味着对每个对象都有一个额外的请求,在一定程度上增加了延迟和成本,但 S3 重定向规则可以设置为仅在请求实际上与存储桶中的文件不匹配时触发。 这对于从一种层次结构过渡到另一种层次结构很有用。

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html

http://docs.aws.amazon.com/AmazonS3/latest/dev/HowDoIWebsiteConfiguration.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM