コード例 #1
0
        public virtual async Task <ActionResult> GetPackage(string id, string version)
        {
            // some security paranoia about URL hacking somehow creating e.g. open redirects
            // validate user input: explicit calls to the same validators used during Package Registrations
            // Ideally shouldn't be necessary?
            if (!PackageIdValidator.IsValidPackageId(id ?? ""))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid"));
            }

            // if version is non-null, check if it's semantically correct and normalize it.
            if (!String.IsNullOrEmpty(version))
            {
                NuGetVersion dummy;
                if (!NuGetVersion.TryParse(version, out dummy))
                {
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version"));
                }

                // Normalize the version
                version = NuGetVersionNormalizer.Normalize(version);
            }
            else
            {
                // if version is null, get the latest version from the database.
                // This ensures that on package restore scenario where version will be non null, we don't hit the database.
                try
                {
                    var package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false);
                    if (package == null)
                    {
                        return(new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
                    }
                    version = package.NormalizedVersion;
                }
                catch (SqlException e)
                {
                    QuietLog.LogHandledException(e);

                    // Database was unavailable and we don't have a version, return a 503
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion));
                }
                catch (DataException e)
                {
                    QuietLog.LogHandledException(e);

                    // Database was unavailable and we don't have a version, return a 503
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion));
                }
            }

            if (ConfigurationService.Features.TrackPackageDownloadCountInLocalDatabase)
            {
                await PackageService.IncrementDownloadCountAsync(id, version);
            }

            return(await PackageFileService.CreateDownloadPackageActionResultAsync(
                       HttpContext.Request.Url,
                       id, version));
        }
コード例 #2
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageToPush = ReadPackageFromRequest())
            {
                if (packageToPush.Metadata.MinClientVersion > new Version("3.0.0.0"))
                {
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, String.Format(
                                                                CultureInfo.CurrentCulture,
                                                                Strings.UploadPackage_MinClientVersionOutOfRange,
                                                                packageToPush.Metadata.MinClientVersion)));
                }

                // Ensure that the user can push packages for this partialId.
                var packageRegistration = PackageService.FindPackageRegistrationById(packageToPush.Metadata.Id);
                if (packageRegistration != null)
                {
                    if (!packageRegistration.IsOwner(user))
                    {
                        return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized));
                    }

                    // Check if a particular Id-Version combination already exists. We eventually need to remove this check.
                    string normalizedVersion = packageToPush.Metadata.Version.ToNormalizedString();
                    bool   packageExists     =
                        packageRegistration.Packages.Any(
                            p => String.Equals(
                                p.NormalizedVersion,
                                normalizedVersion,
                                StringComparison.OrdinalIgnoreCase));

                    if (packageExists)
                    {
                        return(new HttpStatusCodeWithBodyResult(
                                   HttpStatusCode.Conflict,
                                   String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified,
                                                 packageToPush.Metadata.Id, packageToPush.Metadata.Version.ToNormalizedStringSafe())));
                    }
                }

                var package = PackageService.CreatePackage(packageToPush, user, commitChanges: false);
                AutoCuratePackage.Execute(package, packageToPush, commitChanges: false);
                EntitiesContext.SaveChanges();

                using (Stream uploadStream = packageToPush.GetStream())
                {
                    await PackageFileService.SavePackageFileAsync(package, uploadStream);

                    IndexingService.UpdatePackage(package);
                }
            }

            return(new HttpStatusCodeResult(HttpStatusCode.Created));
        }
コード例 #3
0
ファイル: ApiController.cs プロジェクト: ahlkjx/NuGetGallery
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageToPush = ReadPackageFromRequest())
            {
                // Ensure that the user can push packages for this partialId.
                var packageRegistration = PackageService.FindPackageRegistrationById(packageToPush.Metadata.Id);
                if (packageRegistration != null)
                {
                    if (!packageRegistration.IsOwner(user))
                    {
                        return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized));
                    }

                    // Check if a particular Id-Version combination already exists. We eventually need to remove this check.
                    string normalizedVersion = packageToPush.Metadata.Version.ToNormalizedString();
                    bool   packageExists     =
                        packageRegistration.Packages.Any(
                            p => String.Equals(
                                p.NormalizedVersion,
                                normalizedVersion,
                                StringComparison.OrdinalIgnoreCase));

                    if (packageExists)
                    {
                        return(new HttpStatusCodeWithBodyResult(
                                   HttpStatusCode.Conflict,
                                   String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified,
                                                 packageToPush.Metadata.Id, packageToPush.Metadata.Version.ToNormalizedStringSafe())));
                    }
                }

                var package = PackageService.CreatePackage(packageToPush, user, commitChanges: true);
                using (Stream uploadStream = packageToPush.GetStream())
                {
                    await PackageFileService.SavePackageFileAsync(package, uploadStream);
                }

                if (
                    packageToPush.Metadata.Id.Equals(Constants.NuGetCommandLinePackageId,
                                                     StringComparison.OrdinalIgnoreCase) && package.IsLatestStable)
                {
                    // If we're pushing a new stable version of NuGet.CommandLine, update the extracted executable.
                    await NugetExeDownloaderService.UpdateExecutableAsync(packageToPush);
                }
            }

            return(new HttpStatusCodeResult(HttpStatusCode.Created));
        }
コード例 #4
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageStream = ReadPackageFromRequest())
            {
                try
                {
                    using (var archive = new ZipArchive(packageStream, ZipArchiveMode.Read, leaveOpen: true))
                    {
                        var reference = DateTime.UtcNow.AddDays(1); // allow "some" clock skew

                        var entryInTheFuture = archive.Entries.FirstOrDefault(
                            e => e.LastWriteTime.UtcDateTime > reference);

                        if (entryInTheFuture != null)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.PackageEntryFromTheFuture,
                                                                        entryInTheFuture.Name)));
                        }
                    }

                    using (var packageToPush = new PackageArchiveReader(packageStream, leaveStreamOpen: false))
                    {
                        NuspecReader nuspec = null;
                        try
                        {
                            nuspec = packageToPush.GetNuspecReader();
                        }
                        catch (Exception ex)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.UploadPackage_InvalidNuspec,
                                                                        ex.Message)));
                        }

                        if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.UploadPackage_MinClientVersionOutOfRange,
                                                                        nuspec.GetMinClientVersion())));
                        }

                        // Ensure that the user can push packages for this partialId.
                        var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId());
                        if (packageRegistration != null)
                        {
                            if (!packageRegistration.IsOwner(user))
                            {
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden,
                                                                        Strings.ApiKeyNotAuthorized));
                            }

                            // Check if a particular Id-Version combination already exists. We eventually need to remove this check.
                            string normalizedVersion = nuspec.GetVersion().ToNormalizedString();
                            bool   packageExists     =
                                packageRegistration.Packages.Any(
                                    p => String.Equals(
                                        p.NormalizedVersion,
                                        normalizedVersion,
                                        StringComparison.OrdinalIgnoreCase));

                            if (packageExists)
                            {
                                return(new HttpStatusCodeWithBodyResult(
                                           HttpStatusCode.Conflict,
                                           String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified,
                                                         nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe())));
                            }
                        }

                        var packageStreamMetadata = new PackageStreamMetadata
                        {
                            HashAlgorithm = Constants.Sha512HashAlgorithmId,
                            Hash          = CryptographyService.GenerateHash(packageStream.AsSeekableStream()),
                            Size          = packageStream.Length,
                        };

                        var package = await PackageService.CreatePackageAsync(
                            packageToPush,
                            packageStreamMetadata,
                            user,
                            commitChanges : false);

                        await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false);

                        await EntitiesContext.SaveChangesAsync();

                        using (Stream uploadStream = packageStream)
                        {
                            uploadStream.Position = 0;
                            await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream());

                            IndexingService.UpdatePackage(package);
                        }

                        MessageService.SendPackageAddedNotice(package,
                                                              Url.Action("DisplayPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme),
                                                              Url.Action("ReportMyPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme),
                                                              Url.Action("Account", "Users", routeValues: null, protocol: Request.Url.Scheme));

                        return(new HttpStatusCodeResult(HttpStatusCode.Created));
                    }
                }
                catch (InvalidPackageException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (InvalidDataException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (EntityException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (FrameworkException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
            }
        }
コード例 #5
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageStream = ReadPackageFromRequest())
            {
                try
                {
                    using (var packageToPush = new PackageArchiveReader(packageStream, leaveStreamOpen: false))
                    {
                        NuspecReader nuspec = null;
                        try
                        {
                            nuspec = packageToPush.GetNuspecReader();
                        }
                        catch (Exception ex)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.UploadPackage_InvalidNuspec,
                                                                        ex.Message)));
                        }

                        if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.UploadPackage_MinClientVersionOutOfRange,
                                                                        nuspec.GetMinClientVersion())));
                        }

                        // Ensure that the user can push packages for this partialId.
                        var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId());
                        if (packageRegistration != null)
                        {
                            if (!packageRegistration.IsOwner(user))
                            {
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized));
                            }

                            // Check if a particular Id-Version combination already exists. We eventually need to remove this check.
                            string normalizedVersion = nuspec.GetVersion().ToNormalizedString();
                            bool   packageExists     =
                                packageRegistration.Packages.Any(
                                    p => String.Equals(
                                        p.NormalizedVersion,
                                        normalizedVersion,
                                        StringComparison.OrdinalIgnoreCase));

                            if (packageExists)
                            {
                                return(new HttpStatusCodeWithBodyResult(
                                           HttpStatusCode.Conflict,
                                           String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified,
                                                         nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe())));
                            }
                        }

                        var packageStreamMetadata = new PackageStreamMetadata
                        {
                            HashAlgorithm = Constants.Sha512HashAlgorithmId,
                            Hash          = CryptographyService.GenerateHash(packageStream.AsSeekableStream()),
                            Size          = packageStream.Length,
                        };

                        var package = await PackageService.CreatePackageAsync(packageToPush, packageStreamMetadata, user, commitChanges : false);

                        await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false);

                        await EntitiesContext.SaveChangesAsync();

                        using (Stream uploadStream = packageStream)
                        {
                            uploadStream.Position = 0;
                            await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream());

                            IndexingService.UpdatePackage(package);
                        }

                        return(new HttpStatusCodeResult(HttpStatusCode.Created));
                    }
                }
                catch (InvalidDataException ex)
                {
                    return(new HttpStatusCodeWithBodyResult(
                               HttpStatusCode.BadRequest,
                               string.Format(CultureInfo.CurrentCulture, Strings.UploadPackage_InvalidPackage, ex.Message)));
                }
            }
        }
コード例 #6
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageStream = ReadPackageFromRequest())
            {
                try
                {
                    using (var archive = new ZipArchive(packageStream, ZipArchiveMode.Read, leaveOpen: true))
                    {
                        var reference = DateTime.UtcNow.AddDays(1); // allow "some" clock skew

                        var entryInTheFuture = archive.Entries.FirstOrDefault(
                            e => e.LastWriteTime.UtcDateTime > reference);

                        if (entryInTheFuture != null)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.PackageEntryFromTheFuture,
                                                                        entryInTheFuture.Name)));
                        }
                    }

                    using (var packageToPush = new PackageArchiveReader(packageStream, leaveStreamOpen: false))
                    {
                        try
                        {
                            PackageService.EnsureValid(packageToPush);
                        }
                        catch (Exception ex)
                        {
                            ex.Log();

                            var message = Strings.FailedToReadUploadFile;
                            if (ex is InvalidPackageException || ex is InvalidDataException || ex is EntityException)
                            {
                                message = ex.Message;
                            }

                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, message));
                        }

                        NuspecReader nuspec;
                        var          errors = ManifestValidator.Validate(packageToPush.GetNuspec(), out nuspec).ToArray();
                        if (errors.Length > 0)
                        {
                            var errorsString = string.Join("', '", errors.Select(error => error.ErrorMessage));
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        errors.Length > 1 ? Strings.UploadPackage_InvalidNuspecMultiple : Strings.UploadPackage_InvalidNuspec,
                                                                        errorsString)));
                        }

                        if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.UploadPackage_MinClientVersionOutOfRange,
                                                                        nuspec.GetMinClientVersion())));
                        }

                        // Ensure that the user can push packages for this partialId.
                        var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId());
                        if (packageRegistration == null)
                        {
                            // Check if API key allows pushing a new package id
                            if (!ApiKeyScopeAllows(
                                    subject: nuspec.GetId(),
                                    requestedActions: NuGetScopes.PackagePush))
                            {
                                // User cannot push a new package ID as the API key scope does not allow it
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Unauthorized, Strings.ApiKeyNotAuthorized));
                            }
                        }
                        else
                        {
                            // Is the user allowed to push this Id?
                            if (!packageRegistration.IsOwner(user))
                            {
                                // Audit that a non-owner tried to push the package
                                await AuditingService.SaveAuditRecord(
                                    new FailedAuthenticatedOperationAuditRecord(
                                        user.Username,
                                        AuditedAuthenticatedOperationAction.PackagePushAttemptByNonOwner,
                                        attemptedPackage : new AuditedPackageIdentifier(
                                            nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe())));

                                // User cannot push a package to an ID owned by another user.
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Conflict,
                                                                        string.Format(CultureInfo.CurrentCulture, Strings.PackageIdNotAvailable,
                                                                                      nuspec.GetId())));
                            }

                            // Check if API key allows pushing the current package id
                            if (!ApiKeyScopeAllows(
                                    packageRegistration.Id,
                                    NuGetScopes.PackagePushVersion, NuGetScopes.PackagePush))
                            {
                                // User cannot push a package as the API key scope does not allow it
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Unauthorized, Strings.ApiKeyNotAuthorized));
                            }

                            // Check if a particular Id-Version combination already exists. We eventually need to remove this check.
                            string normalizedVersion = nuspec.GetVersion().ToNormalizedString();
                            bool   packageExists     =
                                packageRegistration.Packages.Any(
                                    p => string.Equals(
                                        p.NormalizedVersion,
                                        normalizedVersion,
                                        StringComparison.OrdinalIgnoreCase));

                            if (packageExists)
                            {
                                return(new HttpStatusCodeWithBodyResult(
                                           HttpStatusCode.Conflict,
                                           string.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified,
                                                         nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe())));
                            }
                        }

                        var packageStreamMetadata = new PackageStreamMetadata
                        {
                            HashAlgorithm = Constants.Sha512HashAlgorithmId,
                            Hash          = CryptographyService.GenerateHash(packageStream.AsSeekableStream()),
                            Size          = packageStream.Length
                        };

                        var package = await PackageService.CreatePackageAsync(
                            packageToPush,
                            packageStreamMetadata,
                            user,
                            commitChanges : false);

                        await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false);

                        using (Stream uploadStream = packageStream)
                        {
                            uploadStream.Position = 0;

                            try
                            {
                                await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream());
                            }
                            catch (InvalidOperationException ex)
                            {
                                ex.Log();

                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Conflict, Strings.UploadPackage_IdVersionConflict));
                            }
                        }

                        try
                        {
                            await EntitiesContext.SaveChangesAsync();
                        }
                        catch
                        {
                            // If saving to the DB fails for any reason, we need to delete the package we just saved.
                            await PackageFileService.DeletePackageFileAsync(nuspec.GetId(), nuspec.GetVersion().ToNormalizedString());

                            throw;
                        }

                        IndexingService.UpdatePackage(package);

                        // Write an audit record
                        await AuditingService.SaveAuditRecord(
                            new PackageAuditRecord(package, AuditedPackageAction.Create, PackageCreatedVia.Api));

                        // Notify user of push
                        MessageService.SendPackageAddedNotice(package,
                                                              Url.Action("DisplayPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme),
                                                              Url.Action("ReportMyPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme),
                                                              Url.Action("Account", "Users", routeValues: null, protocol: Request.Url.Scheme));

                        return(new HttpStatusCodeResult(HttpStatusCode.Created));
                    }
                }
                catch (InvalidPackageException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (InvalidDataException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (EntityException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (FrameworkException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
            }
        }
コード例 #7
0
        public virtual async Task <ActionResult> GetPackage(string id, string version)
        {
            // some security paranoia about URL hacking somehow creating e.g. open redirects
            // validate user input: explicit calls to the same validators used during Package Registrations
            // Ideally shouldn't be necessary?
            if (!PackageIdValidator.IsValidPackageId(id ?? ""))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid"));
            }

            if (!String.IsNullOrEmpty(version))
            {
                SemanticVersion dummy;
                if (!SemanticVersion.TryParse(version, out dummy))
                {
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version"));
                }
            }

            // Normalize the version
            version = SemanticVersionExtensions.Normalize(version);

            // if the version is null, the user is asking for the latest version. Presumably they don't want includePrerelease release versions.
            // The allow prerelease flag is ignored if both partialId and version are specified.
            // In general we want to try to add download statistics for any package regardless of whether a version was specified.

            Package package = null;

            try
            {
                package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false);
                if (package == null)
                {
                    return(new HttpStatusCodeWithBodyResult(
                               HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
                }

                try
                {
                    var stats = new PackageStatistics
                    {
                        // IMPORTANT: Timestamp is managed by the database.
                        IPAddress        = Request.UserHostAddress,
                        UserAgent        = Request.UserAgent,
                        Package          = package,
                        Operation        = Request.Headers["NuGet-Operation"],
                        DependentPackage = Request.Headers["NuGet-DependentPackage"],
                        ProjectGuids     = Request.Headers["NuGet-ProjectGuids"],
                    };

                    PackageService.AddDownloadStatistics(stats);
                }
                catch (ReadOnlyModeException)
                {
                    // *gulp* Swallowed. It's OK not to add statistics and ok to not log errors in read only mode.
                }
                catch (SqlException e)
                {
                    // Log the error and continue
                    QuietLog.LogHandledException(e);
                }
                catch (DataException e)
                {
                    // Log the error and continue
                    QuietLog.LogHandledException(e);
                }
            }
            catch (SqlException e)
            {
                QuietLog.LogHandledException(e);
            }
            catch (DataException e)
            {
                QuietLog.LogHandledException(e);
            }

            // Fall back to constructing the URL based on the package version and ID.
            if (String.IsNullOrEmpty(version) && package == null)
            {
                // Database was unavailable and we don't have a version, return a 503
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion));
            }
            return(await PackageFileService.CreateDownloadPackageActionResultAsync(
                       HttpContext.Request.Url,
                       id,
                       String.IsNullOrEmpty(version)?package.NormalizedVersion : version));
        }
コード例 #8
0
        public virtual async Task <ActionResult> GetPackage(string id, string version)
        {
            // some security paranoia about URL hacking somehow creating e.g. open redirects
            // validate user input: explicit calls to the same validators used during Package Registrations
            // Ideally shouldn't be necessary?
            if (!PackageIdValidator.IsValidPackageId(id ?? ""))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid"));
            }

            // if version is non-null, check if it's semantically correct and normalize it.
            if (!String.IsNullOrEmpty(version))
            {
                NuGetVersion dummy;
                if (!NuGetVersion.TryParse(version, out dummy))
                {
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version"));
                }
                // Normalize the version
                version = NuGetVersionNormalizer.Normalize(version);
            }
            else
            {
                // if version is null, get the latest version from the database.
                // This ensures that on package restore scenario where version will be non null, we don't hit the database.
                try
                {
                    var package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false);
                    if (package == null)
                    {
                        return(new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
                    }
                    version = package.NormalizedVersion;
                }
                catch (SqlException e)
                {
                    QuietLog.LogHandledException(e);

                    // Database was unavailable and we don't have a version, return a 503
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion));
                }
                catch (DataException e)
                {
                    QuietLog.LogHandledException(e);

                    // Database was unavailable and we don't have a version, return a 503
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion));
                }
            }

            // If metrics service is specified we post the data to it asynchronously. Else we skip stats.
            if (_config != null && _config.MetricsServiceUri != null)
            {
                try
                {
                    var userHostAddress  = Request.UserHostAddress;
                    var userAgent        = Request.UserAgent;
                    var operation        = Request.Headers["NuGet-Operation"];
                    var dependentPackage = Request.Headers["NuGet-DependentPackage"];
                    var projectGuids     = Request.Headers["NuGet-ProjectGuids"];

                    HostingEnvironment.QueueBackgroundWorkItem(cancellationToken => PostDownloadStatistics(id, version, userHostAddress, userAgent, operation, dependentPackage, projectGuids, cancellationToken));
                }
                catch (Exception ex)
                {
                    QuietLog.LogHandledException(ex);
                }
            }

            return(await PackageFileService.CreateDownloadPackageActionResultAsync(
                       HttpContext.Request.Url,
                       id, version));
        }