Reputation: 1262
I am using Azure Mobile Services API endpoint to return a private shared access signature URL to my azure storage container like so:
var blobService = azure.createBlobService(accountName, key, host);
blobService.createContainerIfNotExists(containerName, function(err) {
if (err) {
cb(err, null);
return;
}
// Generate a 5 minute access
var expiryDate = minutesFromNow(5);
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
Expiry: expiryDate
}
};
// Generate the URL with read access token
var sasURL = blobService.generateSharedAccessSignature(containerName, blobName, sharedAccessPolicy);
var urlForDownloading = sasURL.baseUrl + sasURL.path + '?' + qs.stringify(sasURL.queryString);
cb(null, urlForDownloading);
});
function minutesFromNow(minutes) {
var date = new Date();
date.setMinutes(date.getMinutes() + minutes);
return date;
};
I then return this URL to my iOS client to upload the file and process it as:
client.invokeAPI("document/\(document.idValue).\(document.fileExtension)",
body: nil,
HTTPMethod: "PUT",
parameters: nil,
headers: nil) { result, response, error in
if let dictResult = result as? NSDictionary {
// Get the SAS URL to write directly to the blob storage
if let location = dictResult["location"] as? String {
let url = NSURL(string: location)
let request = NSURLRequest(URL: url)
let uploadTask = session.uploadTaskWithRequest(request, fromFile: localFile) { data, response, error in
if completionBlock != nil {
let success = (error == nil && httpResponse.statusCode == 200)
completionBlock!(success)
}
}
}
}
}
uploadTask.resume()
The iOS client gets a 404 response with a message of
<?xml version="1.0" encoding="utf-8"?><Error><Code>ResourceNotFound</Code><Message>The specified resource does not exist.
The container does exist in the storage account and requests to get blobs from the container with the access keys are successful. This new blob won't exist as it is a new upload, but why am I getting a 404 for a write request to the container?
Upvotes: 1
Views: 2536
Reputation: 1262
Found the solution...
let request = NSURLRequest(URL: url)
produces a GET request and even passing it to uploadTaskWithRequest
persists this request type, whereas I thought this call would change it to a PUT or POST request signifying the upload.
Defining the iOS request as
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "PUT"
was successful. And the response returned was a 201 created.
Upvotes: 1