public async Task <NuGetDownloadResult> DownloadNuGetInternalAsync( NuGetDownloadSettings nuGetDownloadSettings, [NotNull] ILogger logger, HttpClient?httpClient = null, CancellationToken cancellationToken = default) { if (!nuGetDownloadSettings.NugetDownloadEnabled) { return(NuGetDownloadResult.Disabled); } if (nuGetDownloadSettings.NugetDownloadUriFormat is null) { return(NuGetDownloadResult.MissingNuGetDownloadUriFormat); } if (string.IsNullOrWhiteSpace(nuGetDownloadSettings.NugetExeVersion)) { return(NuGetDownloadResult.MissingNuGetExeVersion); } bool ownsClient = httpClient is null; httpClient ??= new HttpClient(); try { string downloadDirectoryPath = nuGetDownloadSettings.DownloadDirectory.WithDefault( Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Arbor.Tooler", "tools", "nuget", nuGetDownloadSettings.NugetExeVersion)) !; var downloadDirectory = new DirectoryInfo(downloadDirectoryPath); try { if (!downloadDirectory.Exists) { downloadDirectory.Create(); } } catch (Exception ex) { return(NuGetDownloadResult.FromException(ex)); } var targetFile = new FileInfo(Path.Combine(downloadDirectory.FullName, "nuget.exe")); string targetFileTempPath = Path.Combine(downloadDirectory.FullName, $"nuget.exe-{DateTime.UtcNow.Ticks}.tmp"); if (targetFile.Exists && !nuGetDownloadSettings.Force) { logger.Debug("Found existing nuget.exe at {FilePath}, skipping download", targetFile); if (nuGetDownloadSettings.UpdateEnabled) { NuGetDownloadResult?nuGetDownloadResult = await EnsureLatestAsync(targetFile, targetFileTempPath, logger, httpClient, cancellationToken).ConfigureAwait(false); if (nuGetDownloadResult?.Succeeded == true) { return(nuGetDownloadResult); } } return(NuGetDownloadResult.Success(targetFile.FullName)); } string downloadUriFormat = nuGetDownloadSettings.NugetDownloadUriFormat.WithDefault(NuGetDownloadSettings .DefaultNuGetExeDownloadUriFormat) !; string downloadUri = downloadUriFormat.Contains("{0}", StringComparison.OrdinalIgnoreCase) ? string.Format(downloadUriFormat, nuGetDownloadSettings.NugetExeVersion) : downloadUriFormat; if (!Uri.TryCreate(downloadUri, UriKind.Absolute, out Uri? nugetExeUri) || !nugetExeUri.IsHttpOrHttps()) { return(NuGetDownloadResult.InvalidDownloadUri(downloadUri)); } NuGetDownloadResult result = await DownloadAsync(logger, nugetExeUri, targetFile, targetFileTempPath, httpClient, cancellationToken).ConfigureAwait(false); if (result.Succeeded && nuGetDownloadSettings.UpdateEnabled) { NuGetDownloadResult?nuGetDownloadResult = await EnsureLatestAsync(targetFile, targetFileTempPath, logger, httpClient, cancellationToken).ConfigureAwait(false); if (nuGetDownloadResult?.Succeeded == true) { return(nuGetDownloadResult); } } return(result); } finally { if (ownsClient) { httpClient.Dispose(); } } }
private static async Task <NuGetDownloadResult> DownloadAsync( ILogger logger, Uri nugetExeUri, FileInfo targetFile, string targetFileTempPath, HttpClient?httpClient, CancellationToken cancellationToken) { logger.Debug("Downloading {Uri} to {TempFile}", nugetExeUri, targetFileTempPath); using (var request = new HttpRequestMessage()) { request.RequestUri = nugetExeUri; bool owsClient = httpClient is null; httpClient ??= new HttpClient(); try { using HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false); await using (var nugetExeFileStream = new FileStream(targetFileTempPath, FileMode.OpenOrCreate, FileAccess.Write)) { if (!httpResponseMessage.IsSuccessStatusCode) { return(NuGetDownloadResult.DownloadFailed(httpResponseMessage.StatusCode)); } await using Stream downloadStream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false); const int defaultBufferSize = 8192; await downloadStream.CopyToAsync(nugetExeFileStream, defaultBufferSize, cancellationToken) .ConfigureAwait(false); await nugetExeFileStream.FlushAsync(cancellationToken).ConfigureAwait(false); logger.Debug("Successfully downloaded {TempFile}", targetFileTempPath); } var fileInfo = new FileInfo(targetFileTempPath); if (fileInfo.Length < 1024 * 1024) { return(NuGetDownloadResult.DownloadFailed("Downloaded file is not complete")); } } finally { if (owsClient) { httpClient.Dispose(); } } } if (File.Exists(targetFile.FullName)) { await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken).ConfigureAwait(false); } logger.Debug("Copying temp file {TempFile} to target file {TargetFile}", targetFileTempPath, targetFile.FullName); File.Copy(targetFileTempPath, targetFile.FullName, true); if (File.Exists(targetFileTempPath)) { File.Delete(targetFileTempPath); logger.Debug("Deleted temp file {TempFile}", targetFileTempPath); } logger.Debug("NuGet client now exists at {TargetFile}", targetFile.FullName); return(NuGetDownloadResult.Success(targetFile.FullName)); }