During testing of an upcoming release of one of our Azure based projects, we began getting intermittent errors while uploading images (blobs) to Windows Azure storage using writable SharedAccessSignatures. I did a search on the web, and oddly enough, one of my previous posts covered a very similar intermittent 403 error. I went through my code and looked for places I might be using Uri.ToString instead of Uri.AbsoluteUri, but even after finding and fixing a couple of those, the problem didn’t go away.
What was even more odd was that sometimes the same image would work, and sometimes it wouldn’t. What I needed was more information about exactly what was in the 403 error. I started up my trusty copy of Fiddler (and shut off TweetDeck and any other apps sending out network traffic), and started the upload process.
The upload process sends images from a WPF client app to blob storage. But it gets the SharedAccessSignature from a web service which resides on Windows Azure. The timeout on the SharedAccessSignature was set to 60 minutes, which should have been more than long enough for each one of these very small images. This seems like a horribly complicated process, but for binary files, POSTing directly to Azure Blob storage instead of going through a intermediary WCF service gave us an observed 40% speed increase. (your performance may vary).
Fiddler told me what the problem was right away:
The SharedAccessSignature maximum timeout cannot be more than 60 minutes.
What? I set it to exactly 60 minutes. How could it be more than 60? Well, I can think of two ways this could happen:
1) Here’s the code where I was setting up the SharedAccessSignature:
1: var readPolicy = new SharedAccessPolicy
2: {
3: Permissions = SharedAccessPermissions.Read | SharedAccessPermissions.Write,
4: SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(SharedAccessSignatureMaxTimeout)
5: };
where the SharedAccessSignatureMaxTimeout = 60
DateTime.UtcNow isn’t the most accurate call in the world. Potentially, this could lead to a SharedAccessExpiryTime which was just slightly greater than the max. The ticks property of the DateTime is probably more accurate.
2) If the System Times between the Storage Host, the Service Host and the Client are slightly off (something that I would expect to be quite common), I could see the scenario where it would seem like the expiry time appeared to be greater than the one hour allotted. With the large number of files we were sending up, I suspect we just hit this issue more than someone who was uploading a single file.
The solution, in either case, is to reduce SharedAccessSignatureMaxTimeout to be well short of 60 minutes. As soon as we did this, everything worked fine.
Tags:
ae436b92-2ced-403c-97b4-8a7907bae6e4|0|.0