配置CloudFront将代理查询字符串作为S3对象密钥的一部分?

问题描述:

我们已将AWS CloudFront配置为将请求代理到S3存储桶。配置CloudFront将代理查询字符串作为S3对象密钥的一部分?

AWS CloudFront允许您对其进行配置,以便查询字符串参数也可以代理到原始服务器(docs) - 我们也配置了该参数。

我遇到的问题是查询字符串参数看起来不包含在S3对象密钥查找中。

因此,例如,我们有像对象键:

  • foo
  • foo?a=1
  • foo?b=2

但是,如果我们提出要求像https://cf-distro-url.com/foo?a=1https://cf-distro-url.com/foo?b=2我们实际上结束了/foo内容而不是特定的关键内容。

它看起来也许CloudFront在查询字符串参数上进行代理,但它们不被用作S3对象密钥查找过程的一部分。

有没有人遇到过这个?和/或知道解决方案?

谢谢!

使用网络浏览器,如果直接访问CloudFront(也不是S3),将会如您所期望的那样在对象密钥中使用?,因为非转义的?是HTTP中查询字符串的分隔符。

根据定义,即?标志着路径的终点,因此标志着对象键的结束。

的关键是为浏览器发送与?转义为%3F,这意味着URL必须被最初呈现给浏览器的方式请求与?获取对象的唯一方法。

您无法上传对象到S3,其密钥名称中包含?,随后通过URL中的文字?从浏览器访问它。

演示与curl,但浏览器的行为是相同的。

随着在URI /foo?bar

$ curl -v 'http://.....s3.amazonaws.com/foo?bar=1' 
* About to connect() to .....s3.amazonaws.com port 80 (#0) 
* Trying x.x.x.x... connected 
> GET /foo?bar=1 HTTP/1.1 

< HTTP/1.1 404 Not Found 

<?xml version="1.0" encoding="UTF-8"?> 
<Error> 
    <Code>NoSuchKey</Code> 
    <Message>The specified key does not exist.</Message> 
    <Key>foo</Key>          <<< requested object is "foo" 
    <RequestId>...</RequestId> 
    <HostId>...</HostId> 
</Error> 

随着在URI /foo%3Fbar=1

$ curl -v 'http://.....s3.amazonaws.com/foo%3Fbar=1' 
* About to connect() to .....s3.amazonaws.com port 80 (#0) 
* Trying x.x.x.x... connected 
> GET /foo%3Fbar=1 HTTP/1.1 

< HTTP/1.1 404 Not Found 

<?xml version="1.0" encoding="UTF-8"?> 
<Error> 
    <Code>NoSuchKey</Code> 
    <Message>The specified key does not exist.</Message> 
    <Key>foo?bar=1</Key>        <<< requested object is "foo?bar=1" 
    <RequestId>...</RequestId> 
    <HostId>...</HostId> 
</Error> 

这在方式URL的限制上形成,而不是在S3(或CloudFront的).. 。但S3文档中提到:在一键名

下面的字符可能需要额外的代码处理,有可能需进行URL编码或十六进制

引用...

问号( “?”)

http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#object-keys

如果你能上传这样的画线C或者正确地使用SDK,那么它会为你逃脱角色。网络浏览器不会隐含地这样做,因为?具有特定的含义。

无论CloudFront是否将查询字符串传递到S3,网络行为都是相同的 - 查询字符串不是密钥的一部分。

+0

Doh,但当然。非常有意义。不知道我是如何错过的。谢谢你清理那个.. – Integralist

看起来您是以CloudFront翻译的方式发送的。您需要查询对象像下面

https://cf-distro-url.com/foo%3Fa%3D1

您需要在这些字符进行URI编码,使他们获得的对象名S3传递。

希望它有帮助。