Azure download with GetSharedAccessSignature of la

2019-08-05 05:23发布

Through a webpage, I want to allow users to download (very large) file stored on Azure Cloud storage. I use the GetSharedAccessSignature to allow users to download it (note: the Container is protected and not publicly readable). I use the following code:

// get the file blob
// CloudBlockBlob blob set previously and check (it exists)

        string sas = blob.GetSharedAccessSignature(
            new SharedAccessPolicy() { 
                Permissions = SharedAccessPermissions.Read,
                SharedAccessStartTime = DateTime.Now.AddMinutes(-5),
                SharedAccessExpiryTime = DateTime.Now.AddMinutes(54) 
            });

        Response.Redirect(blob.Attributes.Uri.AbsoluteUri + sas);

This works EXCEPT when the download takes more than 1 hour (as I said, very large files being downloaded over not so good internet connection...). If the download takes longer, a time-out occurs and the download stops as the Shared Access Expired Time has passed.

How can I solve this?

Kind regards, Robbie De Sutter

1条回答
Summer. ? 凉城
2楼-- · 2019-08-05 06:15

From the code, it seems that you're actually letting the browser do the download. In that scenario, I believe the option is to have shared access signatures valid for longer duration.

Yet another idea is to have your code read the chunks of the blob and then transmit those chunks. That way if there's a need you could create a new SAS URI and use that if the SAS URI timeout has expired and the blob has not downloaded completely.

Take a look at sample code below. Basically in this sample, I have a 200 MB blob. In loop, my code reads 1 MB chunk of the blob and sends that chunk down.

        protected void ButtonDownload_Click(object sender, EventArgs e)
    {
        var blobUri = "http://127.0.0.1:10000/devstoreaccount1/abc/test2.vhd?sr=b&st=2012-08-17T10%3A29%3A46Z&se=2012-08-17T11%3A29%3A46Z&sp=r&sig=dn7cnFhP1xAPIq0gH6klc4nifqgk7jfOgb0hV5Koi4g%3D";
        CloudBlockBlob blockBlob = new CloudBlockBlob(blobUri);
        var blobSize = 200 * 1024 * 1024;
        int blockSize = 1024 * 1024;
        Response.Clear();
        Response.ContentType = "APPLICATION/OCTET-STREAM";
        System.String disHeader = "Attachment; Filename=\"" + blockBlob.Name + "\"";
        Response.AppendHeader("Content-Disposition", disHeader);
        for (long offset = 0; offset < blobSize; offset += blockSize)
        {
            using (var blobStream = blockBlob.OpenRead())
            {
                if ((offset + blockSize) > blobSize)
                    blockSize = (int)(blobSize - offset);
                byte[] buffer = new byte[blockSize];
                blobStream.Read(buffer, 0, buffer.Length);
                Response.BinaryWrite(buffer);
                Response.Flush();
            }
        }
        Response.End();
    }

Hope this helps.

查看更多
登录 后发表回答