private async Task DownloadChunk(Request downloadRequest, CancellationToken token) { token.ThrowIfCancellationRequested(); if (Chunk.IsDownloadCompleted() == false) { HttpWebRequest request = downloadRequest.GetRequest(); SetRequestRange(request); using HttpWebResponse downloadResponse = request.GetResponse() as HttpWebResponse; if (downloadResponse.StatusCode == HttpStatusCode.OK || downloadResponse.StatusCode == HttpStatusCode.PartialContent || downloadResponse.StatusCode == HttpStatusCode.Created || downloadResponse.StatusCode == HttpStatusCode.Accepted || downloadResponse.StatusCode == HttpStatusCode.ResetContent) { Configuration.RequestConfiguration.CookieContainer = request.CookieContainer; using Stream responseStream = downloadResponse?.GetResponseStream(); if (responseStream != null) { using ThrottledStream destinationStream = new ThrottledStream(responseStream, Configuration.MaximumSpeedPerChunk); await ReadStream(destinationStream, token).ConfigureAwait(false); } } else { throw new WebException($"Download response status was {downloadResponse.StatusCode}: {downloadResponse.StatusDescription}"); } } }
private async Task DownloadChunk(Request downloadRequest, long maximumSpeed, CancellationToken token) { if (token.IsCancellationRequested || Chunk.IsDownloadCompleted()) { return; } if (Chunk.IsValidPosition() == false) { Chunk.Position = 0; } HttpWebRequest request = downloadRequest.GetRequest(); request.AddRange(Chunk.Start + Chunk.Position, Chunk.End); using HttpWebResponse downloadResponse = request.GetResponse() as HttpWebResponse; using Stream responseStream = downloadResponse?.GetResponseStream(); if (responseStream != null) { using ThrottledStream destinationStream = new ThrottledStream(responseStream, maximumSpeed); await ReadStream(destinationStream, token); } }
private async Task DownloadChunk(Request downloadRequest, CancellationToken token) { token.ThrowIfCancellationRequested(); if (Chunk.IsDownloadCompleted() == false) { HttpWebRequest request = downloadRequest.GetRequest(); SetRequestRange(request); using HttpWebResponse downloadResponse = request.GetResponse() as HttpWebResponse; using Stream responseStream = downloadResponse?.GetResponseStream(); if (responseStream != null) { using ThrottledStream destinationStream = new ThrottledStream(responseStream, Configuration.MaximumSpeedPerChunk); await ReadStream(destinationStream, token).ConfigureAwait(false); } } }
protected async Task <Chunk> DownloadChunk(Uri address, Chunk chunk, CancellationToken token) { try { if (token.IsCancellationRequested) { return(chunk); } var request = GetRequest("GET", address); if (chunk.Start + chunk.Position >= chunk.End && chunk.Data?.LongLength == chunk.Length) { return(chunk); // downloaded completely before } if (chunk.Position >= chunk.Length && chunk.Data == null) { chunk.Position = 0; // downloaded again and reset chunk position } request.AddRange(chunk.Start + chunk.Position, chunk.End); using var httpWebResponse = request.GetResponse() as HttpWebResponse; if (httpWebResponse == null) { return(chunk); } var stream = httpWebResponse.GetResponseStream(); var destinationStream = new ThrottledStream(stream, Package.Options.ParallelDownload ? Package.Options.MaximumBytesPerSecond / Package.Options.ChunkCount : Package.Options.MaximumBytesPerSecond); using (stream) { if (stream == null) { return(chunk); } if (Package.Options.OnTheFlyDownload) { await ReadStreamOnTheFly(destinationStream, chunk, token); } else { await ReadStreamOnTheFile(destinationStream, chunk, token); } } return(chunk); } catch (TaskCanceledException) // when stream reader timeout occured { // re-request if (token.IsCancellationRequested == false) { await DownloadChunk(address, chunk, token); } } catch (WebException) when(token.IsCancellationRequested == false && chunk.FailoverCount++ <= Package.Options.MaxTryAgainOnFailover) // when the host forcibly closed the connection. { await Task.Delay(Package.Options.Timeout, token); chunk.Checkpoint(); // re-request await DownloadChunk(address, chunk, token); } catch (Exception e) when(token.IsCancellationRequested == false && chunk.FailoverCount++ <= Package.Options.MaxTryAgainOnFailover && (e.HasSource("System.Net.Http") || e.HasSource("System.Net.Sockets") || e.HasSource("System.Net.Security") || e.InnerException is SocketException)) { // wait and decrease speed to low pressure on host Package.Options.Timeout += chunk.CanContinue() ? 0 : 500; chunk.Checkpoint(); await Task.Delay(Package.Options.Timeout, token); // re-request await DownloadChunk(address, chunk, token); } catch (Exception e) // Maybe no internet! { OnDownloadFileCompleted(new AsyncCompletedEventArgs(e, false, Package)); Debugger.Break(); } return(chunk); }