检查Amazon s3签名URL上是否存在文件

时间:2013-09-05 11:33:23

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

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

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

**在此示例中更改了存储桶名称和访问键

然而,我尝试使用下面的函数检查(使用curl)文件是否存在。它未通过CURL连接。如果我用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;

}

2 个答案:

答案 0 :(得分:4)

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

  

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

     

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

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

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

答案 1 :(得分: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.