public async Task <Stream> DownloadAsync(Uri packageUri, CancellationToken cancellationToken) { _logger.LogInformation("Attempting to download package from {PackageUri}...", packageUri); Stream packageStream = null; var stopwatch = Stopwatch.StartNew(); try { // Download the package from the network to a temporary file. using (var response = await _httpClient.GetAsync(packageUri, HttpCompletionOption.ResponseHeadersRead)) { _logger.LogInformation( "Received response {StatusCode}: {ReasonPhrase} of type {ContentType} for request {PackageUri}", response.StatusCode, response.ReasonPhrase, response.Content.Headers.ContentType, packageUri); if (response.StatusCode != HttpStatusCode.OK) { throw new InvalidOperationException($"Expected status code {HttpStatusCode.OK} for package download, actual: {response.StatusCode}"); } using (var networkStream = await response.Content.ReadAsStreamAsync()) { packageStream = FileStreamUtility.GetTemporaryFile(); await networkStream.CopyToAsync(packageStream, FileStreamUtility.BufferSize, cancellationToken); } } packageStream.Position = 0; stopwatch.Stop(); _logger.LogInformation( "Downloaded {PackageSizeInBytes} bytes in {DownloadElapsedTime} seconds for request {PackageUri}", packageStream.Length, stopwatch.Elapsed.TotalSeconds, packageUri); _telemetryService.TrackPackageDownloaded(packageUri, stopwatch.Elapsed, packageStream.Length); return(packageStream); } catch (Exception e) { _logger.LogError( Error.FailedToDownloadPackage, e, "Exception thrown when trying to download package from {PackageUri}", packageUri); packageStream?.Dispose(); throw; } }
private async Task <FileDownloadResult> DownloadInternalAsync(Uri fileUri, long?expectedFileSize, CancellationToken cancellationToken) { if (fileUri == null) { throw new ArgumentNullException(nameof(fileUri)); } if (cancellationToken == null) { throw new ArgumentNullException(nameof(cancellationToken)); } _logger.LogInformation("Attempting to download file from {FileUri}...", fileUri); Stream fileStream = null; var stopwatch = Stopwatch.StartNew(); try { // Download the file from the network to a temporary file. using (var response = await _httpClient.GetAsync(fileUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken)) { _logger.LogInformation( "Received response {StatusCode}: {ReasonPhrase} of type {ContentType} for request {FileUri}", response.StatusCode, response.ReasonPhrase, response.Content?.Headers.ContentType, fileUri); if (response.StatusCode == HttpStatusCode.NotFound) { return(FileDownloadResult.NotFound()); } else if (response.StatusCode != HttpStatusCode.OK) { throw new InvalidOperationException($"Expected status code {HttpStatusCode.OK} for file download, actual: {response.StatusCode}"); } using (var networkStream = await response.Content.ReadAsStreamAsync()) using (cancellationToken.Register(() => networkStream.Close())) { fileStream = FileStreamUtility.GetTemporaryFile(); if (expectedFileSize.HasValue) { var result = await networkStream.CopyToAsync( fileStream, _configuration.BufferSize, expectedFileSize.Value, cancellationToken); if (result.BytesWritten != expectedFileSize.Value || result.PartialRead) { fileStream.Dispose(); _logger.LogError( "File has unexpected size for request {FileUri}. " + "Expected: {ExpectedFileSizeInBytes}. " + "Actual: {ActualFileSizeInBytes}", fileUri, expectedFileSize, result.PartialRead ? ">" + result.BytesWritten : result.BytesWritten.ToString()); return(FileDownloadResult.UnexpectedFileSize()); } } else { await networkStream.CopyToAsync(fileStream, _configuration.BufferSize, cancellationToken); } } } fileStream.Position = 0; stopwatch.Stop(); _logger.LogInformation( "Downloaded {FileSizeInBytes} bytes in {DownloadElapsedTime} seconds for request {FileUri}", fileStream.Length, stopwatch.Elapsed.TotalSeconds, fileUri); _telemetryService.TrackFileDownloaded(fileUri, stopwatch.Elapsed, fileStream.Length); return(FileDownloadResult.Ok(fileStream)); } catch (Exception e) { _logger.LogError( e, "Exception thrown when trying to download package from {FileUri}", fileUri); fileStream?.Dispose(); throw; } }
public DeleteOnCloseReadOnlyTempFile(string fileName) { _fileStream = FileStreamUtility.OpenTemporaryFile(fileName); }