public async Task <Package> ReflowAsync(string id, string version)
        {
            var package = _packageService.FindPackageByIdAndVersionStrict(id, version);

            if (package == null)
            {
                return(null);
            }

            EntitiesConfiguration.SuspendExecutionStrategy = true;
            using (var transaction = _entitiesContext.GetDatabase().BeginTransaction())
            {
                // 1) Download package binary to memory
                using (var packageStream = await _packageFileService.DownloadPackageFileAsync(package))
                {
                    using (var packageArchive = new PackageArchiveReader(packageStream, leaveStreamOpen: false))
                    {
                        // 2) Determine package metadata from binary
                        var packageStreamMetadata = new PackageStreamMetadata
                        {
                            HashAlgorithm = Constants.Sha512HashAlgorithmId,
                            Hash          = CryptographyService.GenerateHash(packageStream.AsSeekableStream()),
                            Size          = packageStream.Length,
                        };

                        var packageMetadata = PackageMetadata.FromNuspecReader(packageArchive.GetNuspecReader());

                        // 3) Clear referenced objects that will be reflowed
                        ClearSupportedFrameworks(package);
                        ClearAuthors(package);
                        ClearDependencies(package);

                        // 4) Reflow the package
                        var listed = package.Listed;

                        package = _packageService.EnrichPackageFromNuGetPackage(
                            package,
                            packageArchive,
                            packageMetadata,
                            packageStreamMetadata,
                            package.User);

                        package.LastEdited = DateTime.UtcNow;
                        package.Listed     = listed;

                        // 5) Update IsLatest so that reflow can correct concurrent updates (see Gallery #2514)
                        await _packageService.UpdateIsLatestAsync(package.PackageRegistration, commitChanges : false);

                        // 6) Save and profit
                        await _entitiesContext.SaveChangesAsync();
                    }
                }

                // Commit transaction
                transaction.Commit();
            }
            EntitiesConfiguration.SuspendExecutionStrategy = false;

            return(package);
        }
Example #2
0
 private async Task BackupPackageBinaries(IEnumerable <Package> packages)
 {
     // Backup the package binaries and remove from main storage
     foreach (var package in packages)
     {
         using (var packageStream = await _packageFileService.DownloadPackageFileAsync(package))
         {
             if (packageStream != null)
             {
                 await _packageFileService.StorePackageFileInBackupLocationAsync(package, packageStream);
             }
         }
         await _packageFileService.DeletePackageFileAsync(package.PackageRegistration.Id,
                                                          string.IsNullOrEmpty(package.NormalizedVersion)
                                                          ?NuGetVersion.Parse(package.Version).ToNormalizedString()
                                                              : package.NormalizedVersion);
     }
 }
Example #3
0
        /// <summary>
        /// Look for the INupkg instance in the cache first. If it's in the cache, return it.
        /// Otherwise, download the package from the storage service and store it into the cache.
        /// </summary>
        public static async Task<INupkg> GetPackageFromCacheOrDownloadIt(
            Package package,
            IPackageCacheService cacheService,
            IPackageFileService packageFileService)
        {
            Debug.Assert(package != null);
            Debug.Assert(cacheService != null);
            Debug.Assert(packageFileService != null);

            string cacheKey = CreateCacheKey(package.PackageRegistration.Id, package.Version);
            byte[] buffer = cacheService.GetBytes(cacheKey);
            if (buffer == null)
            {
                // In the past, some very old packages can specify an external package binary not hosted at nuget.org.
                // We no longer allow that today.
                if (!String.IsNullOrEmpty(package.ExternalPackageUrl))
                {
                    var httpClient = new HttpClient();
                    using (var responseStream = await httpClient.GetStreamAsync(package.ExternalPackageUrl))
                    {
                        buffer = responseStream.ReadAllBytes();
                    }
                }
                else
                {
                    using (Stream stream = await packageFileService.DownloadPackageFileAsync(package))
                    {
                        if (stream == null)
                        {
                            throw new InvalidOperationException("Couldn't download the package from the storage.");
                        }

                        buffer = stream.ReadAllBytes();
                    }
                }

                cacheService.SetBytes(cacheKey, buffer);
            }

            return new Nupkg(new MemoryStream(buffer), leaveOpen: false);
        }
Example #4
0
        private async Task EnsureNuGetExe()
        {
            if (await _fileStorageService.FileExistsAsync(Constants.DownloadsFolderName, "nuget.exe"))
            {
                // Ensure the file exists on blob storage.
                return;
            }

            var package = _packageService.FindPackageByIdAndVersion("NuGet.CommandLine", version: null, allowPrerelease: false);

            if (package == null)
            {
                throw new InvalidOperationException("Unable to find NuGet.CommandLine.");
            }

            using (Stream packageStream = await _packageFileService.DownloadPackageFileAsync(package))
            {
                var nupkg = new Nupkg(packageStream, leaveOpen: true);
                await ExtractNuGetExe(nupkg);
            }
        }
Example #5
0
        private async Task BackupPackageBinaries(IEnumerable <Package> packages)
        {
            // Backup the package binaries and remove from main storage
            foreach (var package in packages)
            {
                // Backup the package from the "validating" container.
                using (var packageStream = await _packageFileService.DownloadValidationPackageFileAsync(package))
                {
                    if (packageStream != null)
                    {
                        await _packageFileService.StorePackageFileInBackupLocationAsync(package, packageStream);
                    }
                }

                // Backup the package from the "packages" container.
                using (var packageStream = await _packageFileService.DownloadPackageFileAsync(package))
                {
                    if (packageStream != null)
                    {
                        await _packageFileService.StorePackageFileInBackupLocationAsync(package, packageStream);
                    }
                }

                var id      = package.PackageRegistration.Id;
                var version = string.IsNullOrEmpty(package.NormalizedVersion)
                            ? NuGetVersion.Parse(package.Version).ToNormalizedString()
                            : package.NormalizedVersion;

                await _packageFileService.DeletePackageFileAsync(id, version);

                await _packageFileService.DeleteValidationPackageFileAsync(id, version);

                // Delete any active or pending readme files for this package.
                await TryDeleteReadMeMdFile(package, false);
                await TryDeleteReadMeMdFile(package, true);
            }
        }