I am trying to download from an HTTP stream directly to S3 without saving to memory or as a file in the first place. I already do this with Rackspace cloud files like HTTP-HTTP, however AWS authentication goes beyond me, so I'm trying to use the SDK.
The problem is that the upload thread with this exception:
"This stream does not support seek operations."
I tried with PutObject and TransferUtility.Upload , both refused with the same.
Is there a way to flow into S3 as the stream arrives, and not buffer it all to a MemoryStream or FileStream ?
or are there any good examples of performing authentication in an S3 request using HTTPWebRequest, so I can duplicate what I do with cloud files?
Edit: or is there an auxiliary function in AWSSDK to generate an authorization header?
CODE:
This is the bad part of S3 (both methods are included for completeness):
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);
And here is how I do it successfully with S3 in 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(); } }
Richard Benson
source share