对 Amazon s3 的 cURL 重定向请求返回 400 代码


cURL redirect request to amazon s3 returns 400 code

使用 PHP curl 从 github 获取发布标记文件。 Github以重定向标头响应到S3,cURL确实遵循该标头。 例如:

https://github.com/twbs/bootstrap/releases/download/v3.3.1/bootstrap-3.3.1-dist.zip

结果为 302,其中包含指向 s3 的位置标头,其中包含各种身份验证详细信息

  https://s3.amazonaws.com/github-cloud/releases/2126244/558cd3fe-6a4b-11e4-9a0e-d0e8b6837eb8.zip?response-content-disposition=attachment%3b%20filename%3dbootstrap-3.3.1-dist.zip&response-content-type=application/octet-stream&awsaccesskeyid=kwy&expires=1417038428&signature=signature%3d

在重定向位置标头之后,亚马逊以 400 响应

请求特定的响应标头不能用于匿名 GET 请求。

作为实验,我尝试将重定向位置作为 POST 发送,并使用设置为 GET 的CURLOPT_CUSTOMREQUEST并将 GET 参数放在CURLOPT_POSTFIELDS中。 这些结果是 405 不允许针对此资源指定方法。

PHP 代码是基本的 cURL,并设置以下内容:

CURLOPT_RETURNTRANSFER  => 1,
CURLOPT_HEADER          => 1,
CURLOPT_FOLLOWLOCATION  => 0,
CURLOPT_CONNECTTIMEOUT  => 10,
CURLOPT_TIMEOUT         => 10,
CURLOPT_MAXREDIRS       => 3,
CURLOPT_ENCODING        => 'gzip,deflate',
CURLOPT_POST            => 0,

它还设置

CURLOPT_REFERER

在重定向上

不过,在 *nix 命令行上做一个直的 curl -L 工作正常,所以它似乎是 PHP 如何处理重定向细节的问题

您粘贴的 URL 无效,如下所示,因为三个查询字符串参数已以某种方式转换为小写。 他们应该是...

AWSAccessKeyID
Expires
Signature

来自AWSAccessKeyID和签名的值也被强制为小写,这也是错误的。 它们也绝对区分大小写。

response-content-*参数正确,如图所示。

我不是 php 专家,所以我不知道这是怎么发生的,但是在这些区分大小写的参数名称上的大小写错误会导致您看到的错误,因为 S3 认为请求是匿名的,匿名请求不支持通过查询字符串设置响应属性。

这也让我觉得不正确,但目前尚不清楚为什么,鉴于此,会遵循重定向:

 CURLOPT_FOLLOWLOCATION => 0,