Reputation: 138
I have an issue with Azure storage blob is not returning 206 Partial content for video files.
Problem: videos are fully downloaded(20-40s for 300mb videos) and the seek bar is not working. I am using Laravel and this problem occurs only when I try to retrieve the .mp4 files from Azure Blob Storage. It was working fine when I was storing the media files on the public disk.
A Microsoft employee states that changing the x-ms-version to 2011-01-18 or later will fix my issue. LINK to the discussion:
Microsoft have a post related to setting the blob service properties: HERE
Note their sample for achieving that: https://learn.microsoft.com/en-us/rest/api/storageservices/set-blob-service-properties#sample-request-and-response
I am trying to send the request via Postman like this:
PUT https://{account-name}.blob.core.windows.net/?restype=service&comp=properties
Included Headers and Response in Postman:
I searched for the error and found this question on SO: The MAC signature found in the HTTP request '...' is not the same as any computed signature
It has an accepted answer but I don't seem to get it. Is there something wrong with my Request/ Authorization header? Or I need to take a different approach?
My code in LARAVEL:
$date = gmdate('D, d M Y H:i:s \G\M\T');
$account_name = "xyz";
$containername = "media";
$account_key = "access_key";
$canonicalizedHeaders = "x-ms-date:$date\nx-ms-version:2017-11-09";
$canonicalizedResource = "/$account_name/$containername\ncomp:list\nrestype:container";
$arraysign = array();
$arraysign[] = 'GET'; /*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 . '/' . $containername . '?restype=container';
$headers = [
"x-ms-date:{$date}",
'x-ms-version:2017-11-09',
'Accept:application/json;odata=nometadata',
"Authorization:{$signature}"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
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);
Upvotes: 0
Views: 925
Reputation: 30015
I suggest you should use SAS token instead of shared key
for authentication. SAS token is easy to generate and manage.
Here are the steps to set blob service properties by using SAS token:
1.Nav to azure portal -> your storage account -> Settings -> Shared access signature: select the proper options as per your need -> Then click "Generate SAS and connection string" button -> at last, after the SAS token
is generated, copy and save it in some editors like .txt file. The screenshot like below:
2.Build the url with SAS token. For example, the request url is https://xx.blob.core.windows.net/?restype=service&comp=properties
, then put the SAS token at the end of the request url. Note: you should remove the first "?" from the SAS token, and put a "&" at the beginning of SAS token.
If the SAS token is ?sv=2020-02-10&ss=b&srt=sco&sp=rwdlacx&se=2021-02-25T10:44:44Z&st=2021-02-25T02:44:44Z&spr=https&sig=xx
Then the request url with SAS
token should look like below:
https://xx.blob.core.windows.net/?restype=service&comp=properties&sv=2020-02-10&ss=b&srt=sco&sp=rwdlacx&se=2021-02-25T10:44:44Z&st=2021-02-25T02:44:44Z&spr=https&sig=xxx
3.In postman, use the request url with SAS token
as request url, and in the Headers tab, just fill in the 2 headers x-ms-date
and x-ms-version
. Since we use SAS token, then no need to use Authorization
header. Here is the screenshot:
4.In the Body tab, write the proper request body as per the Request Body doc. Since I'm using x-ms-version == 2020-04-08
, I follow this section "For version 2019-12-12 or later, the format of the request body is as follows:" in the doc. The screenshot as below(I just modify the soft-delete property, and its retention period):
5.After run the test, In postman, I can see the response code is 202. And in azure portal, the soft-delete property is turned on, and the retention period is also set correctly:
Upvotes: 0
Reputation: 14108
I can reproduce your error when using Shared key(This problem comes from you give the storage account key instead of the key after signed by HMAC.):
But if I use AD bearer token, then it will be no problem:
Python code to get the bearer token:
import requests
from azure.identity import ClientSecretCredential
client_id = 'xxx'
tenant_id = 'xxx'
client_secret = 'xxx'
credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret)
accesstoken = str(credential.get_token('https://yourstoragename.blob.core.windows.net/.default'))[19:1282]
print(str(credential.get_token('https://yourstoragename.blob.core.windows.net/.default')))
Upvotes: 0