上传到Azure的斑点使用SAS和REST [英] Upload to Azure Blob using SAS and REST

查看:123
本文介绍了上传到Azure的斑点使用SAS和REST的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法写一个蓝色的斑点座从C ++使用SAS(共享访问签名)。我使用的斑点REST API和波科。 HTTP请求返回错误404(资源不存在),但我想不出我做错了什么。

I'm having trouble writing to an Azure Block Blob from C++ using a SAS (Shared Access Signature). I'm using the Blob REST API and Poco. The HTTP request returns error 404 (resource does not exist), but I can't figure out what I'm doing wrong.

我产生SAS在C#这样的服务器上(似乎很好地工作):

I generate the SAS on the server in C# like this (seems to work fine):

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("my-blob");
container.CreateIfNotExists();
SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(40);
sasConstraints.Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List;
string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);
return Request.CreateResponse(HttpStatusCode.OK, container.Uri + sasContainerToken);

在Azure的门户,我可以看到确实如预期正在创建的Blob容器。我收到此SAS在C ++中使用HTTP请求。我所得到的是这样的(一些名字和签名改为出于安全原因):

In the Azure portal I can indeed see the Blob container being created as expected. I receive this SAS in C++ using an HTTP request. What I get looks like this (some names and signature replaced for security reasons):

<一个href=\"https://myname.blob.core.windows.net/my-blob?sv=2012-02-12&se=2016-06-07T11%3A13%3A19Z&sr=c&sp=wl&sig=%%%%%%%%%%%%%%%%%%%%%%%\" rel=\"nofollow\">https://myname.blob.core.windows.net/my-blob?sv=2012-02-12&se=2016-06-07T11%3A13%3A19Z&sr=c&sp=wl&sig=%%%%%%%%%%%%%%%%%%%%%%%

然后我尝试创建使用波科和斑点REST API的文件。这看起来是这样的:

Then I try to create the file using Poco and the Blob REST API. That looks like this:

std::string cloudUrl = sasURI + "&restype=container";
std::string fileName = "fname.ext";
Poco::URI* uri = new Poco::URI(cloudUrl.c_str());
std::string* path = new std::string(uri->getPathAndQuery());
Poco::Net::HTTPSClientSession* session = new Poco::Net::HTTPSClientSession(uri->getHost(), uri->getPort());
std::string method = Poco::Net::HTTPRequest::HTTP_PUT;
Poco::Net::HTTPRequest* request = new Poco::Net::HTTPRequest(method, *path, Poco::Net::HTTPMessage::HTTP_1_1);
request->add("x-ms-blob-content-disposition", "attachment; filename=\"" + fileName + "\"");
request->add("x-ms-blob-type", "BlockBlob");
request->add("x-ms-meta-m1", "v1");
request->add("x-ms-meta-m2", "v2");
Poco::Net::HTTPResponse* httpResponse = new Poco::Net::HTTPResponse();
int fileContent = 42;
request->setContentLength(sizeof(int));
request->setKeepAlive(true);
std::ostream& outputStream = session->sendRequest(*request);
outputStream << fileContent;
std::istream &is = session->receiveResponse(*httpResponse);
Poco::Net::HTTPResponse::HTTPStatus status = httpResponse->getStatus();
std::ostringstream outString;
Poco::StreamCopier::copyStream(is, outString);
if (status != Poco::Net::HTTPResponse::HTTP_OK)
{
    Logger::log("Connection failed\nstatus:", status, "\nreason:", httpResponse->getReason(), "\nreasonForStatus:", httpResponse->getReasonForStatus(status), "\nresponseContent:", outString.str());
}

我抬头这里怎么REST API作品。我发现这里 的是使用SAS的时候我不需要做定期的验证。

I've looked up here how the REST API works. I found here that when using a SAS I don't need to do regular authentication.

我在做什么错在这里?为什么我会收到错误404?

What am I doing wrong here? Why am I getting error 404?

推荐答案

我终于想通了什么事情错在这里。 :)

I've finally figured out what was going wrong here. :)

有分别在上述code两个问题。第一个是所需要的文件名被插入到该网址,拉夫Mantri说明。这是卓有成效的:

There were two problems in the above code. The first is that the filename needed to be inserted into the URL, as Gaurav Mantri explained. This does the trick:

int indexOfQuestionMark = cloudUrl.find('?');
cloudUrl = cloudUrl.substr(0, indexOfQuestionMark) + "/" + fileName + cloudUrl.substr(indexOfQuestionMark);

另一个问题是,我没有足够的上传字节。 的sizeof(INT) 4字节,而42推到一个流把它变成文字,使得它只有2个字节。然后,服务器将一直等待剩余的2个字节。这使得这个在上面的例子code正确的路线:

The other problem is that I wasn't uploading enough bytes. sizeof(int) is 4 bytes while pushing 42 into a stream turns it into characters, making it only 2 bytes. The server then keeps waiting for the remaining 2 bytes. That makes this the correct line in the example code above:

request->setContentLength(2);

此外,它的工作原理没有这三条线,所以我想是不需要的:

Also, it works without these three lines so I suppose they're not needed:

request->add("x-ms-blob-content-disposition", "attachment; filename=\"" + fileName + "\"");
request->add("x-ms-meta-m1", "v1");
request->add("x-ms-meta-m2", "v2");

同样,添加此似乎没有必要:&放大器; restype =容器

最后,写 SharedAccessBlobPermissions.List 不需要权利,让那些在SAS一代被排除在服务器端。

Finally, for writing the SharedAccessBlobPermissions.List rights aren't needed so those can be left out in SAS generation on the server side.

这篇关于上传到Azure的斑点使用SAS和REST的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆