gpt4 book ai didi

rest - 使用 SAS 和 REST 上传到 Azure Blob

转载 作者:行者123 更新时间:2023-12-02 07:23:09 24 4
gpt4 key购买 nike

我在使用 SAS(共享访问签名)从 C++ 写入 Azure block Blob 时遇到问题。我正在使用 Blob REST API 和 Poco。 HTTP请求返回错误404(资源不存在),但我不知道我做错了什么。

我在服务器上用 C# 生成 SAS,如下所示(似乎工作正常):

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 容器正在按预期创建。我使用 HTTP 请求以 C++ 形式接收此 SAS。我得到的看起来像这样(出于安全原因替换了一些名称和签名):

https://myname.blob.core.windows.net/my-blob?sv=2012-02-12&se=2016-06-07T11%3A13%3A19Z&sr=c&sp=wl&sig=%%%%%%%%%%%%%%%%%%%%%%%

然后我尝试使用 Poco 和 Blob REST API 创建文件。看起来像这样:

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());
}

我查过here REST API 的工作原理。我发现here使用 SAS 时,我不需要进行常规身份验证。

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

最佳答案

我终于弄清楚这里出了什么问题。 :)

上面的代码有两个问题。首先,文件名需要插入到 URL 中,正如 Gaurav Mantri 所解释的那样。这可以解决问题:

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

另一个问题是我没有上传足够的字节。 sizeof(int) 是 4 个字节,而将 42 插入流中会将其转换为字符,使其只有 2 个字节。然后服务器继续等待剩余的 2 个字节。这使得这是上面示例代码中的正确行:

request->setContentLength(2);

此外,它无需这三行即可工作,因此我认为不需要它们:

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=container"

最后,不需要编写 SharedAccessBlobPermissions.List 权限,因此可以在服务器端的 SAS 生成中忽略这些权限。

关于rest - 使用 SAS 和 REST 上传到 Azure Blob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37678058/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com