【问题标题】:Check if File Exists on Amazon s3 Signed URL检查 Amazon s3 签名 URL 上是否存在文件
【发布时间】:2013-09-09 05:20:09
【问题描述】:

我为 Amazon s3 创建了一个签名的 $URL,它可以在浏览器中完美打开。

http://testbucket.com.s3.amazonaws.com/100-game-play-intro-1.m4v?AWSAccessKeyId=AKIAJUAjhkhkjhMO73BF5Q&Expires=1378465934&Signature=ttmsAUDgJjCXepwEXvl8JdFu%2F60%3D

**此示例中的存储桶名称和访问密钥已更改

然而,我试图使用下面的函数来检查(使用 curl)文件是否存在。它使 CURL 连接失败。如果我将上面的 $URL 替换为 s3 之外的图像的 url,那么这段代码就可以完美运行。

我知道该文件存在于 amazon 中,但如果使用上述签名的 url,则无法弄清楚为什么此代码会失败

有什么想法吗?

谢谢

这是我的代码。

function remoteFileExists($url) {

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    //don't fetch the actual file, only get header to check if file exists
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_NOBODY, true);

    $result = curl_exec($ch);
    curl_close($ch);



    if ($result !== false) {

        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);  

        if ($statusCode == 200) {
            $ret = true;   
        } else {
            $ret = false;
        }

    } else {
        $ret='connection failed';
    }

    return $ret;

}

【问题讨论】:

  • 当我使用此代码检查 s3 上是否存在带有签名 url 的文件时,因为它是私有存储桶(即没有公共策略),它总是失败并显示“连接失败”,表明 CURL 连接本身失败。
  • 抱歉,这很容易使用 AWS PHP SDK 解决,但我试图在没有 SDK 的情况下使其工作,因为我正在将功能添加到 wordpress 插件中。谢谢

标签: php curl amazon-web-services amazon-s3


【解决方案1】:

当使用CURLOPT_NOBODY 时,libcurl 发送 HTTP HEAD 请求,而不是 GET 请求。

...要签名的字符串是通过附加 REST 动词、content-md5 值、content-type 值、expires 参数值、规范化的 x-amz 标头形成的(参见下面的配方)和资源;全部用换行符分隔。

——http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

“REST 动词”——例如,GETHEAD——必须在您生成的签名和发出的请求之间保持一致,因此对 GET 有效的签名将无效对于HEAD,反之亦然。

您需要签署HEAD 请求而不是GET 请求才能以这种方式验证文件。

【讨论】:

  • 感谢您的回答。从我的研究看来,鉴于我不使用 SDK 的要求,这是正确的答案。话虽如此,我现在已经在插件中实现了 SDK,因为它似乎是最强大的解决方案,并且可以访问我可能会使用的其他功能。再次感谢。
【解决方案2】:

您可以通过标题部分检查。

$full_url = 'https://www.example.com/image.jpg';
$file_headers = @get_headers($full_url);
if($file_headers && strpos($file_headers[0], '200 OK')){
    // enter code here
}

或者,如果您使用的是 AWS S3,那么您也可以使用这个。

if(!class_exists('S3')){
    require('../includes/s3/S3.php');
}
S3::setAuth(awsAccessKey, awsSecretKey);
$info = S3::getObjectInfo($bucketName, $s3_furl);
// check for $info value and apply your condition.

【讨论】:

    猜你喜欢
    • 2018-08-01
    • 2020-06-14
    • 2018-04-02
    • 2013-06-12
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2013-09-06
    相关资源
    最近更新 更多