gpt4 book ai didi

c# - 从 C# 中的 HTTPWebResponse.GetResponseStream() 上传到 S3

转载 作者:太空狗 更新时间:2023-10-29 20:10:28 27 4
gpt4 key购买 nike

我正在尝试从 HTTP 流直接上传到 S3,而不是首先存储在内存中或作为文件。我已经将 Rackspace 云文件作为 HTTP 到 HTTP 来执行此操作,但是 AWS 身份验证超出了我的范围,因此我正在尝试使用 SDK。

问题是上传流失败并出现以下异常:

“此流不支持查找操作。”

我尝试过使用 PutObjectTransferUtility.Upload,但都因同样的事情而失败。

有什么方法可以在流进入时流式传输到 S3,而不是将整个内容缓冲到 MemoryStreamFileStream

是否有任何使用 HTTPWebRequest 对 S3 请求进行身份验证的好示例,这样我就可以复制我对 Cloud Files 所做的操作?

编辑:AWSSDK 中是否有用于生成授权 header 的辅助函数?

代码:

这是失败的 S3 部分(包括两种方法以确保完整性):

string uri = RSConnection.StorageUrl + "/" + container + "/" + file.SelectSingleNode("name").InnerText;
var req = (HttpWebRequest)WebRequest.Create(uri);
req.Headers.Add("X-Auth-Token", RSConnection.AuthToken);
req.Method = "GET";

using (var resp = req.GetResponse() as HttpWebResponse)
{
using (Stream stream = resp.GetResponseStream())
{
Amazon.S3.Transfer.TransferUtility trans = new Amazon.S3.Transfer.TransferUtility(S3Client);
trans.Upload(stream, config.Element("root").Element("S3BackupBucket").Value, container + file.SelectSingleNode("name").InnerText);

//Use EITHER the above OR the below

PutObjectRequest putReq = new PutObjectRequest();
putReq.WithBucketName(config.Element("root").Element("S3BackupBucket").Value);
putReq.WithKey(container + file.SelectSingleNode("name").InnerText);
putReq.WithInputStream(Amazon.S3.Util.AmazonS3Util.MakeStreamSeekable(stream));
putReq.WithMetaData("content-length", file.SelectSingleNode("bytes").InnerText);

using (S3Response putResp = S3Client.PutObject(putReq))
{

}
}

}

这就是我成功从 S3 到 Cloud Files 的方法:

using (GetObjectResponse getResponse = S3Client.GetObject(new GetObjectRequest().WithBucketName(bucket.BucketName).WithKey(file.Key)))
{
using (Stream s = getResponse.ResponseStream)
{
//We can stream right from s3 to CF, no need to store in memory or filesystem.
var req = (HttpWebRequest)WebRequest.Create(uri);
req.Headers.Add("X-Auth-Token", RSConnection.AuthToken);
req.Method = "PUT";

req.AllowWriteStreamBuffering = false;
if (req.ContentLength == -1L)
req.SendChunked = true;


using (Stream stream = req.GetRequestStream())
{
byte[] data = new byte[32768];
int bytesRead = 0;
while ((bytesRead = s.Read(data, 0, data.Length)) > 0)
{
stream.Write(data, 0, bytesRead);
}
stream.Flush();
stream.Close();
}
req.GetResponse().Close();
}
}

最佳答案

由于似乎没有人回答过,我花时间根据史蒂夫回答的指导来解决这个问题:

在回答这个问题“是否有任何使用 HTTPWebRequest 对 S3 请求进行身份验证的好例子,这样我就可以复制我对 Cloud Files 所做的事情?”,这里是如何手动生成 auth header :

string today = String.Format("{0:ddd,' 'dd' 'MMM' 'yyyy' 'HH':'mm':'ss' 'zz00}", DateTime.Now);

string stringToSign = "PUT\n" +
"\n" +
file.SelectSingleNode("content_type").InnerText + "\n" +
"\n" +
"x-amz-date:" + today + "\n" +
"/" + strBucketName + "/" + strKey;

Encoding ae = new UTF8Encoding();
HMACSHA1 signature = new HMACSHA1(ae.GetBytes(AWSSecret));
string encodedCanonical = Convert.ToBase64String(signature.ComputeHash(ae.GetBytes(stringToSign)));

string authHeader = "AWS " + AWSKey + ":" + encodedCanonical;

string uriS3 = "https://" + strBucketName + ".s3.amazonaws.com/" + strKey;
var reqS3 = (HttpWebRequest)WebRequest.Create(uriS3);
reqS3.Headers.Add("Authorization", authHeader);
reqS3.Headers.Add("x-amz-date", today);
reqS3.ContentType = file.SelectSingleNode("content_type").InnerText;
reqS3.ContentLength = Convert.ToInt32(file.SelectSingleNode("bytes").InnerText);
reqS3.Method = "PUT";

请注意添加的 x-amz-date header ,因为 HTTPWebRequest 以与 AWS 期望的格式不同的格式发送日期。

从那里开始只是重复我已经在做的事情。

关于c# - 从 C# 中的 HTTPWebResponse.GetResponseStream() 上传到 S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16917768/

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