I would like to copy blob from one storage account to another storage account in the same subscription using Rest API and PHP. I am able to do a copy blob from one container to another in the same storage account using the below code
<?php
$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-date:$date\nx-ms-version:2015-04-05";
$canonicalizedResource = "/$account_name/$destcontainername/$blobname";
$arraysign = array();
$arraysign[] = 'PUT'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = ''; /*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.'/'.$destcontainername.'/'.$blobname;
$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:0',
"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);
I would like to know if i have to use the same copy blob rest API to accomplish it. If yes than what will be the $canonicalizedHeaders
and $canonicalizedResource
and resquest rest API. I am able to do copy blob from one storage account to another using the powershell command below
Start-AzureStorageBlobCopy -DestContainer $destinationContainerName -DestContext $destinationContext -SrcBlob $vhdName -Context $sourceContext -SrcContainer $sourceSAContainerName
You would use the same code for copying blobs across storage accounts as well. While
$canonicalizedResource
remain the same, you would need to include the URL of the source blob inx-ms-copy-source
header in$canonicalizedHeaders
.One important thing to keep in mind is that the source blob URL that you specify in
x-ms-copy-source
header must be publicly accessible. What that means is that if you take that URL and paste that in browser's address bar, you should be able to access the blob. If the source blob container's ACL isBlob
orContainer
, then you can simply specify the blob URL (https://sourceaccountname.blob.core.windows.net/sourceblobcontainer/sourceblobname
) however if the source blob container's ACL isPrivate
then you would need to create aShared Access Signature (SAS)
on the source blob with at leastRead
permission and use the SAS URL for this header's value.Another thing to understand is that copying across storage accounts is an asynchronous operation. So when the code above executes successfully, the blob copy operation is queued. You must check if the copy operation has completed before deleting source blob or making any changes to that otherwise the copy operation will fail.