private void Download(ResourceUrl url, CancellationToken cancellationToken) { DebugLogger.Log(string.Format("Trying to download from {0}", url)); long offset = CurrentFileSize(); DebugLogger.LogVariable(offset, "offset"); var downloadJobQueue = BuildDownloadJobQueue(url, offset); foreach (DownloadJob downloadJob in downloadJobQueue) { BaseHttpDownloader baseHttpDownloader = new BaseHttpDownloader(downloadJob.Url, _timeout); baseHttpDownloader.SetBytesRange(downloadJob.Offset); baseHttpDownloader.DataAvailable += (bytes, length) => { bool retry = !_fileStream.Write(bytes, 0, length); if (retry) { throw new DownloaderException("Corrupt data.", DownloaderExceptionStatus.CorruptData); } OnDownloadProgressChanged(CurrentFileSize(), _resource.Size); }; baseHttpDownloader.Download(cancellationToken); } if (_fileStream.RemainingLength > 0) { throw new DownloaderException("Data download hasn't been completed.", DownloaderExceptionStatus.Other); } }
private bool TryDownload(ResourceUrl url, ChunkedFileStream fileStream, CancellationToken cancellationToken) { try { _logger.LogDebug(string.Format("Trying to download from {0}", url.Url)); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); var downloadJobQueue = BuildDownloadJobQueue(url, fileStream.VerifiedLength); foreach (var downloadJob in downloadJobQueue) { _logger.LogDebug(string.Format("Executing download job {0} with offest {1}", downloadJob.Url, downloadJob.Range.Start)); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); _logger.LogTrace("fileStream.SavedLength = " + fileStream.SavedLength); var baseHttpDownloader = new BaseHttpDownloader(downloadJob.Url, 30000); baseHttpDownloader.SetBytesRange(downloadJob.Range); const long downloadStatusLogInterval = 5000L; var stopwatch = Stopwatch.StartNew(); long downloadedBytes = 0; var job = downloadJob; baseHttpDownloader.DataAvailable += (bytes, length) => { fileStream.Write(bytes, 0, length); downloadedBytes += length; if (stopwatch.ElapsedMilliseconds > downloadStatusLogInterval) { stopwatch.Reset(); stopwatch.Start(); _logger.LogDebug(string.Format("Downloaded {0} from {1}", downloadedBytes, job.Url)); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); _logger.LogTrace("fileStream.SavedLength = " + fileStream.SavedLength); } OnDownloadProgressChanged(fileStream.VerifiedLength); }; baseHttpDownloader.Download(cancellationToken); _logger.LogDebug("Download job execution success."); _logger.LogTrace("fileStream.VerifiedLength = " + fileStream.VerifiedLength); _logger.LogTrace("fileStream.SavedLength = " + fileStream.SavedLength); } if (fileStream.RemainingLength != 0) { throw new IncompleteDataException("Chunks downloading must finish downloading whole file"); } _logger.LogDebug(string.Format("Download from {0} has been successful.", url.Url)); return(true); } catch (IncompleteDataException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (InvalidChunkDataException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (DataNotAvailableException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (ServerErrorException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } catch (ConnectionFailureException e) { _logger.LogWarning(string.Format("Unable to download from {0}", url.Url), e); return(false); } }