5

我为 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,那么这段代码就可以完美运行。

我知道该文件存在于亚马逊中,但如果使用上述签名的 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;

}
4

2 回答 2

4

当使用CURLOPT_NOBODY 时,libcurl 发送一个 HTTPHEAD请求,而不是一个GET请求。

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

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

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

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

于 2013-09-07T22:51:08.020 回答
1

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

$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.
于 2019-10-09T10:22:29.737 回答