Amazon Glacier Parallel archive upload - c#

I have a sample application which upload a file of size 26 MB to Amazon Glacier using AWS SDK for .NET High-Level API. the code works fine without threading but with thread pool its fails at the below line
client.UploadMultipartPart(uploadMPUrequest);
saying error Message:
The request was aborted: The request was canceled.
Stack Trace: at Amazon.Runtime.AmazonWebServiceClient.handleHttpWebErrorResponse(AsyncResult asyncResult, WebException we)
at Amazon.Runtime.AmazonWebServiceClient.getRequestStreamCallback(IAsyncResult result)
at Amazon.Runtime.AmazonWebServiceClient.InvokeConfiguredRequest(AsyncResult asyncResult)
at Amazon.Runtime.AmazonWebServiceClient.InvokeHelper(AsyncResult asyncResult)
at Amazon.Runtime.AmazonWebServiceClient.Invoke(AsyncResult asyncResult)
at Amazon.Glacier.AmazonGlacierClient.invokeUploadMultipartPart(UploadMultipartPartRequest uploadMultipartPartRequest, AsyncCallback callback, Object state, Boolean synchronized)
at Amazon.Glacier.AmazonGlacierClient.UploadMultipartPart(UploadMultipartPartRequest uploadMultipartPartRequest)
Note: I am uploading the data in multi part
please find the below link for my sample code:
www.page-monitor.com/Downloads/ArchiveUploadMPU.cs
Is there any sample code for parallel upload of archive?
Thanks and Regards,
Haseena

I believe there is a race condition in the code. I am working on the same functionality. I'd be happy to share code with you. If you fixed the code you posted I'd appreciate a link to it.
Best Regards,
Bruce

Here is the sample code that works fine with threading. ChunkDetails is a custom library for passing the accessID, bucketname, offset detail, etc. I am also using ThrottledStream.
internal bool UploadUsingHighLevelAPI(String FilePath, ChunkDetails ObjMetaData,
S3Operations.UploadType uploadType,
Stream inputStream)
{
String METHOD_NAME = "UploadUsingHighLevelAPI";
String keyName;
String existingBucketName;
TransferUtilityUploadRequest fileTransferUtilityRequest = null;
int RetryTimes = 3;
ThrottledStream throttleStreamObj = null;
long bps = ThrottledStream.Infinite;
try
{
keyName = ObjMetaData.KeyName;
existingBucketName = ObjMetaData.BucketName;
TransferUtility fileTransferUtility = new
TransferUtility(ObjMetaData.AccessKeyID, ObjMetaData.SecretAccessKey);
FileInfo fin = new FileInfo(FilePath);
//streamObj = new FileStream(FilePath, FileMode.Open);
bps = (long)(1024 * ObjMetaData.MaxAvailSpeed * ((double)ObjMetaData.Bandwidth / 100.0));
throttleStreamObj = new ThrottledStream(ObjMetaData.FileStream, bps);
System.Collections.Specialized.NameValueCollection metaInfo = new System.Collections.Specialized.NameValueCollection();
if (ObjMetaData.MetaInfo != null)
{
foreach (DictionaryEntry kvp in ObjMetaData.MetaInfo)
{
metaInfo.Add(kvp.Key.ToString(), kvp.Value.ToString());
}
}
long OffDiff = ObjMetaData.EndOffset - ObjMetaData.StartOffset;
long partSize;
if (fin.Length >= OffDiff)
{
partSize = OffDiff;
}
else
partSize = fin.Length;
if (uploadType == UploadType.File)
{
//fileTransferUtility.Upload(FilePath, existingBucketName, keyName);
fileTransferUtilityRequest =
new TransferUtilityUploadRequest()
.WithBucketName(existingBucketName)
//.WithFilePath(FilePath)
.WithStorageClass(S3StorageClass.ReducedRedundancy)
.WithMetadata(metaInfo)
.WithPartSize(partSize)
.WithKey(keyName)
.WithCannedACL(S3CannedACL.PublicRead)
.WithTimeout(Int32.MaxValue - 1)
.WithInputStream(throttleStreamObj) as TransferUtilityUploadRequest;
}
else if (uploadType == UploadType.Stream)
{
fileTransferUtilityRequest =
new TransferUtilityUploadRequest()
.WithBucketName(existingBucketName)
.WithStorageClass(S3StorageClass.ReducedRedundancy)
.WithMetadata(metaInfo)
.WithPartSize(partSize)
.WithKey(keyName)
.WithCannedACL(S3CannedACL.PublicRead)
.WithTimeout(Int32.MaxValue - 1)
.WithInputStream(throttleStreamObj) as TransferUtilityUploadRequest
;
}
for (int index = 1; index <= RetryTimes; index++)
{
try
{
// Upload part and add response to our list.
fileTransferUtility.Upload(fileTransferUtilityRequest);
Console.WriteLine(" ====== Upload Done =========");
if (eventChunkUploaded != null)
eventChunkUploaded(ObjMetaData);
break;
}
catch (Exception ex)
{
if (index == RetryTimes)
{
m_objLogFile.LogError(CLASS_NAME, METHOD_NAME + " - Attempt " +
index + Environment.NewLine + FilePath, ex);
if (eventChunkUploadError != null)
eventChunkUploadError(ObjMetaData, ex.Message);
}
}
}
}
catch (Exception ex)
{
m_objLogFile.LogError(CLASS_NAME, METHOD_NAME, ex);
return false;
}
finally
{
if (throttleStreamObj != null)
{
//inputStream1.Close();
throttleStreamObj = null;
}
}
return true;
}
Let me know if you face any issue.

Related

Error during transfering Bytes xamarin forms

I try to upload at least 30 pictures to a web server but my program catch errors.
They appear randomly, sometimes at the first image, sometimes third etc.
{System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: Unable to write data to the transport connection: Connection reset by peer. ---> System.Net.Sockets.SocketException: Connection reset by peer
at System.Net.Sockets.Socket.EndSend (System.IAsyncResult asyncResult) [0x0000c] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/System/net/System/Net/Sockets/Socket.cs:3874
at System.Net.Sockets.NetworkStream.EndWrite (System.IAsyncResult asyncResult) [0x00057] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/mcs/class/referencesource/System/net/System/Net/Sockets/NetworkStream.cs:1043
--- End of inner exception stack trace ---
OR
Read error: ssl=0x7e46332e08: I/O error during system call, Connection reset by peer
I explain you the process : I got an array with image path and I created a loop to upload each image on my web server.
public async void LaunchImagesUpload()
{
for (int i = startIndex; i < picturesToDisplay.Count; i++)
{
try
{
await UploadSinglePicture(i);
}
catch (Exception e)
{
if(e.Message.Equals("The operation was canceled."))
{
hasErrors = true;
}
else if(e.Message.Equals("Error while copying content to a stream."))
{
// Sometimes program goes here
hasErrors = true;
}
else
{
// Sometimes program goes here
currentPictureGrid.ActivateCancelledMode("error , retry please");
hasErrors = true;
}
}
}
}
Here is the http call
public static async Task<string> CreateUploadTask(string file, string id, string user_id, string user_login)
{
string requestResult = "";
var cont = new MultipartFormDataContent();
var image = new StreamContent(File.OpenRead(file));
image.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "file", FileName = "imageToUpload.jpeg" };
image.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
cont.Add(image);
string id_level = id
string uri = // private uri
using (var client = new HttpClient())
{
var response = await client.PostAsync(uri, cont);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
return "error";
}
requestResult = response.Content.ReadAsStringAsync().Result;
Console.WriteLine("DATA FINAL" + requestResult);
}
return requestResult;
}
How can I upload multiple image. Do I made a mistake. There is another way to uplad pictures thank's in advance
UPDATE
I used breakpoint to see when appear error and I added a handler.HttpSendProgress to see the transfer and error appear during transfer
Here is the nuew CreateUploadTask function
public static async Task<string> CreateUploadTask(string file, string vtour_id, string user_id, string user_login)
{
string requestResult = "";
HttpContent fileStreamContent = new StreamContent(File.OpenRead(file));
await Task.Delay(500);
fileStreamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "file", FileName = "imageToUpload.jpeg" };
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
string boundary = "---8393774hhy37373773";
using (var formData = new MultipartFormDataContent(boundary))
{
handler.HttpSendProgress += (s, e) =>
{
// error is here because I display transfer and not all Bytes are transfered
float prog = (float)e.BytesTransferred / (float)File.OpenRead(file).Length;
prog = prog > 1 ? 1 : prog;
if (prog > .99)
{
currentPictureGrid.ActivateTreatmentMode();
Console.WriteLine("IMAGE IMPORT --------- Transfert -------- Mode 'en cours de traitement' activé");
}
else
{
Console.WriteLine("step 0");
byteTransferedBeforeBug = (float)e.BytesTransferred;
byteTotalBeforeBug = (float)File.OpenRead(file).Length;
currentPictureGrid.UpdateUploadRate((float)e.BytesTransferred, (float)File.OpenRead(file).Length);
}
};
formData.Add(fileStreamContent);
string id_level = (jsoncontent != null && jsoncontent.GetValue(currentPath.ToString())["floor"].ToString() != null ? jsoncontent.GetValue(currentPath.ToString())["floor"].ToString() : "0");
var response = await client.PostAsync(MY_PRIVATE_URL, formData);
requestResult = response.Content.ReadAsStringAsync().Result.ToString();
Console.WriteLine("DATA RESULT : " + requestResult);
}
return requestResult;
}

Reading attachments from mail using Microsoft exchange web service

We have the below code to read the attachments using EWS.
FindItemsResults<Item> foundItems = service.FindItems(FolderId, new ItemView(1000));
var orderItems = from list in foundItems
orderby list.DateTimeReceived
select list;
foreach (EmailMessage item in orderItems)
{
item.Load();//SARANYA
EmailMessage foundEmail = (EmailMessage)item;
EmailMessage message = EmailMessage.Bind(service, new ItemId(item.Id.ToString()), new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.Attachments, ItemSchema.Body));
if (message.Attachments.Count > 0)
{
FileAttachment[] attachments = null;
attachments = new FileAttachment[message.Attachments.Count];
foreach (Attachment attachment in message.Attachments)
{
try
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
// System.Threading.Thread.Sleep(2000);
fileAttachment.Load();
byte[] FolloupMailFileAttachmentContentBytes = fileAttachment.Content;
bool isScreenshot = false;
string ScreenfileName = "";
for (int i = 0; i < imgSrcs.Count; i++)
{
if (imgSrcs[i].ToString() == fileAttachment.Name.ToString())
{
isScreenshot = true;
if (!imgSrcs[i].ToString().Contains(".png"))
ScreenfileName = "cid:" + imgSrcs[i].ToString() + ".png";
else
ScreenfileName = "cid:" + imgSrcs[i].ToString();
break;
}
}
if (FolloupMailFileAttachmentContentBytes != null)
{
if (isScreenshot && RemoveSuccess == 1)
{
InsertMailItemAttachment(ScreenfileName, FolloupMailFileAttachmentContentBytes, caseid);
}
else
InsertMailItemAttachment(fileAttachment.Name.ToString(), FolloupMailFileAttachmentContentBytes, caseid);
}
}
else if (attachment is ItemAttachment)
{
item.Move(unreadmailFolder.Id);
}
}
catch (Exception exe)
{
if (!ReadMoved)
{
item.Move(readmailFolder.Id);
ReadMoved = true;
}
logfile.HandleError(exe, "Attachment Exception \n\nEmailbox - " + EMailBox + "\n\nEmail Subject - " + strSubject + " \n - Could not load the attachment (" + attachment.Name.ToString() + ")");
}
}
}
}
Above code is working when I provide thread.sleep() before fileattachment.load(). when thread.sleep is removed, I get the below exception.
Error Source : Microsoft.Exchange.WebServices
Target Site : Void InternalThrowIfNecessary()
System Message : The specified object was not found in the store.
Stack Trace : at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
at Microsoft.Exchange.WebServices.Data.ServiceResponse.ThrowIfNecessary()
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalGetAttachments(IEnumerable`1 attachments, Nullable`1 bodyType, IEnumerable`1 additionalProperties, ServiceErrorHandling errorHandling)
at Microsoft.Exchange.WebServices.Data.ExchangeService.GetAttachment(Attachment attachment, Nullable`1 bodyType, IEnumerable`1 additionalProperties)
at Microsoft.Exchange.WebServices.Data.Attachment.InternalLoad(Nullable`1 bodyType, IEnumerable`1 additionalProperties)
at Microsoft.Exchange.WebServices.Data.Attachment.Load()
at EMT_Office365_MailFetch_Scheduler.Program.FindEmail(Object threadState) in
Experts, Please provide your valuable inputs
Your logic doesn't look correct eg
item.Move(unreadmailFolder.Id);
Should not be inside the Foreach loop if you want to move the message at the end just use a Flag and process it once you have finished processing the attachments(you logic doesn't work if you have two ItemAttachment this would execute twice). The reason sleep is working is mostly likely an Aysnc operation is completing once you have executed the move. Thats why this should be outside of the foreach attachment loop

Can I read messages from gmail using gmail api and c#?

I want read all messages in my gmail account using c# and gmail api.
Can I do this?
I read a lot of articles in Gmail API, but i couldn't read messages.
Also I want to read a body of messages or header.
I will be very glad if someone can help me :)
I use this code snippet:
public static List<Message> ListMessages(GmailService service, String userId)
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
do
{
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
And this:
foreach (var item in ListMessages(service,"me"))
MessageBox.Show(item.Snippet);
But in a result I have empty message box.
It works for me
var inboxlistRequest = service.Users.Messages.List("your-email-address");
inboxlistRequest.LabelIds = "INBOX";
inboxlistRequest.IncludeSpamTrash = false;
//get our emails
var emailListResponse = inboxlistRequest.Execute();
foreach (var mail in emailListResponse.Messages)
{
var mailId = mail.Id;
var threadId = mail.ThreadId;
Message message = service.Users.Messages.Get("your-email-address", mailId).Execute();
Console.WriteLine(message.Snippet);
}
Yes you should have no issue doing what you say. I would suggest reading the documentation a bit more.
First you have to authenticate - the following shows how to do this with a service account (more details here https://developers.google.com/gmail/api/auth/web-server)
serviceAccountEmail = primaryLink.serviceEmailAddress;
certificate = new X509Certificate2(AppDomain.CurrentDomain.BaseDirectory + "certs//" + primaryLink.certificate, primaryLink.certificatePassword, X509KeyStorageFlags.Exportable);
try
{
credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = z.us.emailAccount,
Scopes = new[] { "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "https://mail.google.com/" }
}.FromCertificate(certificate));
if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
gs = new GmailService(
new Google.Apis.Services.BaseClientService.Initializer()
{
ApplicationName = "Example",
HttpClientInitializer = credential
});
}
else
{
throw new Exception("gmail authentication Error.");
}
}
catch (Exception ex)
{
throw ex;
}
ListMessagesResponse respM = reqM.Execute();
if (respM.Messages != null)
{
foreach (Message m in respM.Messages)
{}
}
Once you have the message List you can iterate through the messages and either use a MIME parser or traverse the message structure to get the header, body etc.
There are lots of posts in this forum which go through how to do that.
I searched for a full example, without luck, but this is my working example. Based on https://developers.google.com/gmail/api/guides
Authenticate : https://developers.google.com/gmail/api/auth/web-server
get ALL emails
loop through all emails by Id, and request message etc.
here is the code snippet to get the first email's atachments, but you can simply loop over all foundIds to get all emails, and use message.snippet to get body :
List<string> foundIds = new List<string>();
string outputDir = "/EXAMPLE/EXAMPLE/"; // your preferred Dir to save attachments to
List<Google.Apis.Gmail.v1.Data.Thread> resultThread = new List<Google.Apis.Gmail.v1.Data.Thread>();
UsersResource.ThreadsResource.ListRequest requestThread = service.Users.Threads.List("me");
do
{
try
{
ListThreadsResponse responseThread = requestThread.Execute();
resultThread.AddRange(responseThread.Threads);
foreach (var item in responseThread.Threads )
{
foundIds.Add(item.Id);
}
requestThread.PageToken = responseThread.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(requestThread.PageToken));
try
{
Message message = service.Users.Messages.Get("me", foundIds[0]).Execute();
IList<MessagePart> parts = message.Payload.Parts;
foreach (MessagePart part in parts)
{
if (!String.IsNullOrEmpty(part.Filename))
{
String attId = part.Body.AttachmentId;
MessagePartBody attachPart = service.Users.Messages.Attachments.Get("me", foundIds[0], attId).Execute();
// Converting from RFC 4648 base64 to base64url encoding
// see http://en.wikipedia.org/wiki/Base64#Implementations_and_history
String attachData = attachPart.Data.Replace('-', '+');
attachData = attachData.Replace('_', '/');
byte[] data = Convert.FromBase64String(attachData);
File.WriteAllBytes(Path.Combine(outputDir, part.Filename), data);
}
}
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
I would suggest taking a look at this article on how to handle the actual response structure. It can be somewhat complex with the way the Gmail API gives the results back to you.
https://sigparser.com/developers/email-parsing/gmail-api/
#BlackCat, Your ListMessages looks good. Now, to get the message body, you have to decode MimeType "text/plain" or "text/html". For eg:
public static void GetBody(GmailService service, String userId, String messageId, String outputDir)
{
try
{
Message message = service.Users.Messages.Get(userId, messageId).Execute();
Console.WriteLine(message.InternalDate);
if (message.Payload.MimeType == "text/plain")
{
byte[] data = FromBase64ForUrlString(message.Payload.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
else
{
IList<MessagePart> parts = message.Payload.Parts;
if (parts != null && parts.Count > 0)
{
foreach (MessagePart part in parts)
{
if (part.MimeType == "text/html")
{
byte[] data = FromBase64ForUrlString(part.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
}
}
}
Console.WriteLine("----");
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
}

Downloading file parts using HttpWebRequest C#

I am trying to download a 100GB file using HttpWebRequest. The download will be split into parts depending on a preset part size. Below is the code I use to download the file:
private static void AddRangeHeaderHack(WebHeaderCollection headers, long start, long end)
{
// Original workaround by Eric Cadwell, code taken from
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93714
Type type = headers.GetType();
System.Reflection.MethodInfo setAddVerified = type.GetMethod("SetAddVerified",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy
);
string rangeHeaderValue = String.Format("bytes={0}-{1}", start, end);
if (setAddVerified != null)
setAddVerified.Invoke(headers, new object[] { "Range", rangeHeaderValue });
}
private ulong GetRemoteFileSize(string URI)
{
ulong size = 0;
HttpWebRequest req = null;
try
{
req = (HttpWebRequest)WebRequest.Create(URI);
using (var res = (HttpWebResponse)req.GetResponse())
{
size = (ulong)res.ContentLength;
res.Close();
}
}
catch (Exception ex)
{
}
if (req != null)
{
try
{
req.Abort();
req = null;
}
catch (Exception)
{
}
}
return size;
}
private int DownloadFromLink(string sSource, string sDestination)
{
int nRetryCount = 0;
int nMaxRetry = 5;
var lastProgress = DateTime.Now;
ulong offset = 0;
var bRetrying = false;
var bResumable = false;
var fileSize = GetRemoteFileSize(sSource);
if (fileSize > 0)
bResumable = true;
while (true)
{
HttpWebRequest webRequest = null;
try
{
try
{
bRetrying = false;
do
{
try
{
if (bDownloadAbort)
{
return -1;
}
webRequest = (HttpWebRequest)WebRequest.Create(sSource);
webRequest.Timeout = 3600000;
if (offset > 0)
{
AddRangeHeaderHack(webRequest.Headers, (long)offset, (long)fileSize);
}
// Retrieve the response from the server
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
var acceptRanges = String.Compare(webResponse.Headers["Accept-Ranges"], "bytes", true) == 0;
// Open the URL for download
using (var streamResponse = webResponse.GetResponseStream())
{
if (streamResponse != null)
{
// Create a new file stream where we will be saving the data (local drive)
using (var streamLocal = new FileStream(sDestination, offset>0?FileMode.Append:FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
// It will store the current number of bytes we retrieved from the server
int bytesSize = 0;
// A buffer for storing and writing the data retrieved from the server
byte[] downBuffer = new byte[/*16384*/ 1024 * 1024];
bool binitialtry = true;
int nRetries = 0;
if (offset > 0)
{
streamLocal.Seek((long)offset, SeekOrigin.Begin);
}
// Loop through the buffer until the buffer is empty
while ((bytesSize = streamResponse.Read(downBuffer, 0, downBuffer.Length)) > 0
|| (File.Exists(sDestination) && (offset < (ulong)fileSize) && nRetries < 5 && bResumable))
{
if (binitialtry && bytesSize == 0)
{
binitialtry = false;
}
if (!binitialtry && bytesSize == 0)
{
nRetries++;
bRetrying = nRetries<5;
break;
}
if (bDownloadAbort)
{
try { streamLocal.Close(); }
catch { }
return;
}
try
{
// Write the data from the buffer to the local hard drive
streamLocal.Write(downBuffer, 0, bytesSize);
offset += (ulong)bytesSize;
}
catch (IOException ex)
{
if (streamResponse != null)
streamResponse.Close();
if (streamLocal != null)
streamLocal.Close();
if (webRequest != null)
webRequest.Abort();
return -1;
}
Interlocked.Add(ref actualDownloaded, bytesSize);
}
// When the above code has ended, close the streams
if (streamResponse != null)
streamResponse.Close();
if (streamLocal != null)
try { streamLocal.Close(); }
catch { }
if (webRequest != null)
webRequest.Abort();
if (webRequest != null)
wcDownload.Dispose();
streamLocal.Close();
}
streamResponse.Close();
}
}
webResponse.Close();
}
if(!bRetrying)
break;
}
catch (IOException ex)
{
if (webRequest != null)
webRequest.Abort();
if (wcDownload != null)
wcDownload.Dispose();
if (nRetryCount <= nMaxRetry)
{
Thread.Sleep(10000);
nRetryCount++;
bRetrying = true;
}
else
{
break;
}
}
catch (UnauthorizedAccessException ex)
{
if (webRequest != null)
webRequest.Abort();
break;
}
catch (WebException ex)
{
if (webRequest != null)
webRequest.Abort();
if (wcDownload != null)
wcDownload.Dispose();
if (nRetryCount <= nMaxRetry)
{
Thread.Sleep(10000);
nRetryCount++;
bRetrying = true;
}
else
{
break;
}
}
finally
{
}
} while (bRetrying);
}
catch (Exception ex)
{
break;
}
}
catch
{
break;
}
if(!bRetrying)
break;
}
}
If I try to download the file in 1 part, with out adding the range header, the code runs smoothly and the file downloads normally. When I add a range header, say from 10GB to 15GB or frankly any value, the code reaches streamResponse.Read and hangs there for several minutes then it throws an exception:
Unable to read data from the transport connection: An existing
connection was forcibly closed by the remote host
When the code retries the connection after the exception, the download resumes normally and the client is able to read data from the stream.
Can someone help me determine why such thing is happening?
Just to clear the matter about the server, the file is currently hosted on an Amazon S3 server, and the download is done from a generated direct link.
It could be a server setting, according to http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4
Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.
Try FDM, and see if it has a problem. http://www.freedownloadmanager.org/
I don’t know how to download a file in parts using HttpWebRequest, but I found this example online to build an own implementation. The article is about the HttpClient in C#. There is also complete code and project you can find in the download section of this page.
The Problem is that not all server support partial download. So NuGet packages can be used that handle the exceptions e.g.:
https://www.nuget.org/packages/downloader
or
https://www.nuget.org/packages/Shard.DonwloadLibrary.
These Libraries will handle the chunks and convert them back into a readable file or stream.
Downloader:
var downloader = new DownloadService(new()
{
ChunkCount = 8,
});
string file = #"Your_Path\fileName.zip";
string url = #"https://file-examples.com/fileName.zip";
await downloader.DownloadFileTaskAsync(url, file);
or Download Library:
string file = "Your_Path";
string url = "https://file-examples.com/fileName.zip";
var downloader = new LoadRequest(url,new()
{
Chunks = 8,
DestinationPath= file,
});
await downloader.Task;
I hope I could help!

get gmail contacts images

I am trying to get google contact image from gmail, using google api 3.
I have used the code below to read the stream to get the photo:
public static void DownloadPhoto(ContactsRequest cr, Contact entry)
{
string filename = "c:\\gcontacts\\" + entry.GetHashCode() + ".jpg";
Stream photoStream = cr.GetPhoto(entry);
FileStream outStream = File.OpenWrite(filename);
try
{
byte[] buffer = new byte[photoStream.Length];
photoStream.Read(buffer, 0, (int)photoStream.Length);
outStream.Write(buffer, 0, (int)photoStream.Length);
photoStream.Close();
outStream.Close();
}
catch (Exception ex)
{
}
}
I am getting the below error:
Content not modified.
https://www.google.com/m8/feeds/photos/media/myemail/610f985888b0911.
I use this function to call the service
public static void PrintAllContacts(ContactsRequest cr)
{
Feed<Contact> f = cr.GetContacts();
foreach (Contact entry in f.Entries)
{
if (entry.Name.FullName != null)
{
Console.WriteLine(entry.Name.FullName);
Console.WriteLine(entry.PhotoUri.AbsoluteUri);
DownloadPhoto(cr, entry);
}
}
}
and this is the request
RequestSettings rsLoginInfo = new RequestSettings("appname", "#gmail.com", "pass");
rsLoginInfo.AutoPaging = true;
ContactsRequest cRequest = new ContactsRequest(rsLoginInfo);
instead of
cr.GetPhoto(entry)
use
cr.Service.Query(entry.PhotoUri);
It says there is a problem in the request. You should check where you make the request and share it with us, you didn't post that part in your question.
You can find the documentation here: https://developers.google.com/google-apps/contacts/v3/#retrieving_a_contacts_photo

Categories