I am trying to copy blob from one container to another in the same storage account. The documentation of azure rest api is not clear and does not say how to copy from source container to destination container also how to copy blobs from one storage account to another storage account.
I have tried to copy blob using the below code its throws an error saying "AuthenticationFailedServer failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature."
$date = gmdate('D, d M Y H:i:s \G\M\T');
$account_name = "accname";
$destcontainername = "destcontainer";
$blobname = "blob.png";
$sourcecontainer = "sourcecontainer";
$account_key = "asdf";
$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.windows.net/".$sourcecontainer."/".$blobname."\nx-ms-version:2015-04-05";
$canonicalizedResource = "/$account_name/$destcontainername/$blobname";
$arraysign = array();
$arraysign[] = 'PUT'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = 1; /*Content-Length (include value when zero)*/
$arraysign[] = ''; /*Content-MD5*/
$arraysign[] = ''; /*Content-Type*/
$arraysign[] = ''; /*Date*/
$arraysign[] = ''; /*If-Modified-Since */
$arraysign[] = ''; /*If-Match*/
$arraysign[] = ''; /*If-None-Match*/
$arraysign[] = ''; /*If-Unmodified-Since*/
$arraysign[] = ''; /*Range*/
$arraysign[] = $canonicalizedHeaders; /*CanonicalizedHeaders*/
$arraysign[] = $canonicalizedResource; /*CanonicalizedResource*/
$stringtosign = implode("\n", $arraysign);
$signature = 'SharedKey'.' '.$account_name.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));
$endpoint = 'https://'.$account_name.'.blob.core.windows.net';
$url = $endpoint.'/'.$containername.'/blob.png';
$headers = [
'x-ms-copy-source:https://'.$account_name.'.blob.core.windows.net/'.$sourcecontainer.'/'.$blobname.'',
//"x-ms-date:{$date}",
'x-ms-version:2015-04-05',
'Accept:application/json;odata=nometadata',
'Accept-Charset:UTF-8',
'Content-Length:1',
"Authorization:{$signature}"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);
echo '<pre>';print_r($response);
x-ms-copy-source
value should be same in$headers
and in$canonicalizedHeaders
. In both places it should be the URL of the source blob. – Gaurav Mantri$canonicalizedHeaders
must be alphabetically sorted. So it should be$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.windows.net/".$containername."/".$blobname."\nx-ms-version:2015-04-05";
– Gaurav Mantri