AWS S3查询字符串参数导致方法不允许错误



对此URL的GET请求按预期返回文件。。。

curl -v 'http://xxx.s3.amazonaws.com/lineitems/58ecfff764a6036d96deaa69/bootstrap.min.js'

然而,当我添加特定的查询字符串参数"select"时,我会得到一个405方法不允许的错误。

curl -v 'http://xxx.s3.amazonaws.com/lineitems/58ecfff764a6036d96deaa69/bootstrap.min.js?select='
< HTTP/1.1 405 Method Not Allowed
< x-amz-request-id: 7F3339518976EB66
< x-amz-id-2: 8YmXqeME+Y5bLRdlMhDKQyrznjNJr/gw7ortpLjXqFDlPfYR1Ckqz+2Gr2/35/SWKaNviMLZLEk=
< Allow: POST
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Date: Thu, 02 Nov 2017 10:50:33 GMT
< Server: AmazonS3

其他查询字符串参数名称不会导致此问题。它似乎只影响此文件夹中的文件,并且最近(上周)才开始发生。

我在这个文件夹中的文件的属性中看不到任何异常,所有内容都通过相同的代码上传到了bucket中。

我无法解释为什么会发生这种事。

您需要使用不同的参数名称。select现在对S3有意义,因此它不再被悄悄丢弃。

更新?select子资源的突然出现似乎是在AWS开始部署一项新功能S3 Select时,该功能允许使用SQL表达式实际查询JSON和CSV对象的内容子集。该功能于同月晚些时候发布。

原来的答案如下。


由于无法解释的原因,查询字符串中的select=导致S3将您的请求解释为……不同的东西。具体是什么还不清楚。

<ResourceType>SELECT</ResourceType>

有趣的是,如果您尝试POST,您会收到一条错误消息,说POST也不被允许,但Allow: POST不再在响应标头中。

bucket日志将请求操作显示为REST.GET.SELECT,这似乎没有记录在案,其中普通的GET请求记录为REST.GET.OBJECT

所以你正在触发一些意想不到的行为,你需要使用一些不同的东西。

它以前有效的事实往往排除了我最初的理论,即你以某种方式提示S3假设你想发出一个不推荐的SOAP请求(需要POST),但如果这真的一直有效,那么我倾向于认为你可能无意中发现了一个尚未发布的功能。

非官方地,S3静默地忽略大多数意外的查询字符串参数。签名V2也完全忽略了它们(如果我正确记得该算法的测试结果,实际上需要对它们进行签名而不是)。

官方表示,如果您不想让服务对其进行解释,那么您似乎应该使用以x-开头的查询字符串参数。这也会将参数写入日志,这可能会在未来的调试中产生有用的副作用。

您可以通过向请求的URL添加自定义查询字符串参数,将要存储在请求的访问日志记录中的自定义信息包括在内Amazon S3将忽略以x-开头的查询字符串参数,但会将这些参数包含在请求的访问日志记录中,作为日志记录的请求URI字段的一部分(增加强调)

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

最新更新