I have a question regarding using an AWS S3 presigned URL to download a file to a remote server. I was able to successfully create the presigned URLs for a zip file. If I type the presigned URL into the browser I can successfully download the zip file. However, I also need our users’ site to get that zip file, download it to their server and unzip it. So what I did was use PHP CURL and provided the presigned URL for the CURLOPT_URL parameter. However, when I do this the zip file is empty and I get an error message. Since I am using a presigned url it already has the required authorization & signature headers to download the file. My question is why doesn’t it work in PHP CURL but only in the browser? What am I not doing right here?
Example Presigned URL:
https://xxxxxxx-xxxxxxxxxx-xxxxxxx-231481972270.s3-accesspoint.us-east-1.amazonaws.com/serenity-pro/serenity-pro.zip?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATLZLGSYXEHERUI4Z%2F20210913%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210913T042133Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=62ba2cb3d434f8643cd5099b74523234df46b3c9fdb0f5ab75d962c8ab4d0428
My Code:
// Download zip file
// The $download_url is the presigned URL I generated for the user
$ch = curl_init();
$fp = fopen($theme_zip_path, "w+");
curl_setopt_array($ch, array(
CURLOPT_URL => $download_url,
CURLOPT_TIMEOUT => 600,
CURLOPT_FILE => $fp
));
$contents = curl_exec($ch);
curl_close($ch);
fclose($fp);
Error Message:
InvalidRequest The authorization mechanism you have provided is not supported. Please use Signature Version 4
3
Answers
In case anyone is encountering the same issue the solution is to use CloudFront signed URLs.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateURL_PHP.html
if your url contains https then try adding this
CURLOPT_SSL_VERIFYHOST
CURLOPT_SSL_VERIFYPEER