/// <summary>
        /// Gets metadata about a package from the <c>nuspec</c> files and other
        /// metadata such as package size, date published, download counts, etc.
        /// </summary>
        public object GetPackageInfo(string id, string version="")
        {
            var packageSpec = new PackageSpec(id, version);
            var packages = LuceneRepository
                            .LucenePackages
                            .Where(p => p.Id == packageSpec.Id)
                            .OrderBy(p => p.Version)
                            .ToList();

            var package = packageSpec.Version != null
                              ? packages.Find(p => p.Version.SemanticVersion == packageSpec.Version)
                              : packages.LastOrDefault();

            if (package == null)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Package not found.");
            }

            var versionHistory = packages.Select(pkg => new PackageVersionSummary(pkg, new Link(GetPackageInfoUrl(pkg), pkg.Version.ToString()))).ToList();

            versionHistory.Select(v => v.Link).SetRelationships(packages.IndexOf(package));

            var result = new PackageWithVersionHistory();

            package.ShallowClone(result);

            result.PackageDownloadLink = new Link(Url.Link(RouteNames.Packages.Download, new { id = result.Id, version = result.Version }), "attachment", "Download Package");
            result.VersionHistory = versionHistory.ToArray();
            result.SymbolsAvailable = SymbolSource.AreSymbolsPresentFor(package);

            return result;
        }
        public void FindPackagesDistinct()
        {
            var copyOfPackage1 = new PackageSpec(package1.Id, package1.Version.ToString());

            mirror.Setup(r => r.FindPackagesById("FuTools")).Returns(new[] { package1 }).Verifiable();
            origin.Setup(r => r.FindPackagesById("FuTools")).Returns(new[] { copyOfPackage1, package2 }).Verifiable();

            var result = repo.FindPackagesById("FuTools");

            mirror.VerifyAll();
            origin.VerifyAll();

            Assert.That(result.ToList(), Is.EqualTo(new[] {package1, package2}));
        }
        public HttpResponseMessage DownloadPackage(string id, string version="")
        {
            var packageSpec = new PackageSpec(id, version);
            var package = FindPackage(packageSpec);

            var result = EvaluateCacheHeaders(packageSpec, package);

            if (result != null)
            {
                return result;
            }

            if (Request.Headers.Range != null)
            {
                try
                {
                    HttpResponseMessage partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
                    partialResponse.Content = new ByteRangeStreamContent(package.GetStream(), Request.Headers.Range, new MediaTypeWithQualityHeaderValue("application/zip"));
                    return partialResponse;
                }
                catch (InvalidByteRangeException e)
                {
                    return Request.CreateErrorResponse(HttpStatusCode.BadRequest, e);
                }
            }

            result = Request.CreateResponse(HttpStatusCode.OK);
            if (Request.Method == HttpMethod.Get)
            {
                result.Content = new StreamContent(package.GetStream());
                TaskRunner.QueueBackgroundWorkItem(cancellationToken => LuceneRepository.IncrementDownloadCountAsync(package, cancellationToken));
            }
            else
            {
                result.Content = new StringContent(string.Empty);
            }

            result.Headers.ETag = new EntityTagHeaderValue('"' + package.PackageHash + '"');
            result.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/zip");
            result.Content.Headers.LastModified = package.LastUpdated;
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue(DispositionTypeNames.Attachment)
                {
                    FileName = string.Format("{0}.{1}{2}", package.Id, package.Version, Constants.PackageExtension),
                    Size = package.PackageSize,
                    CreationDate = package.Created,
                    ModificationDate = package.LastUpdated,
                };

            return result;
        }
        public void PackageInOriginAddedToMirror()
        {
            var addedPackage = (IPackage) null;

            mirror.Setup(r => r.FindPackage(package1.Id, package1.Version)).Returns(() => addedPackage);
            origin.Setup(r => r.FindPackage(package1.Id, package1.Version)).Returns(package1).Verifiable();
            mirror.Setup(r => r.AddPackage(package1)).Callback<IPackage>(pkg => addedPackage = new PackageSpec(pkg.Id, pkg.Version.ToString()));

            var result = repo.FindPackage(package1.Id, package1.Version);

            Assert.That(result, Is.SameAs(addedPackage));

            mirror.VerifyAll();
            origin.VerifyAll();
        }
Esempio n. 5
0
        public HttpResponseMessage DownloadPackage(string id, string version="")
        {
            var packageSpec = new PackageSpec(id, version);
            var package = FindPackage(packageSpec);

            var result = EvaluateCacheHeaders(packageSpec, package);

            if (result != null)
            {
                return result;
            }

            result = Request.CreateResponse(HttpStatusCode.OK);

            if (Request.Method == HttpMethod.Get)
            {
                result.Content = new StreamContent(package.GetStream());
                
                TaskUtils.FireAndForget(() => LuceneRepository.IncrementDownloadCount(package), UnhandledExceptionLogger.LogException);
            }
            else
            {
                result.Content = new StringContent(string.Empty);
            }

            result.Headers.ETag = new EntityTagHeaderValue('"' + package.PackageHash + '"');
            result.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/zip");
            result.Content.Headers.LastModified = package.LastUpdated;
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue(DispositionTypeNames.Attachment)
                {
                    FileName = string.Format("{0}.{1}{2}", package.Id, package.Version, Constants.PackageExtension),
                    Size = package.PackageSize,
                    CreationDate = package.Created,
                    ModificationDate = package.LastUpdated,
                };
            
            return result;
        }
        private LucenePackage FindPackage(PackageSpec packageSpec)
        {
            if (packageSpec.Version == null)
            {
                return FindNewestReleasePackage(packageSpec.Id);
            }

            var package = MirroringRepository.FindPackage(packageSpec.Id, packageSpec.Version);
            return package != null ? LuceneRepository.Convert(package) : null;
        }
        private HttpResponseMessage EvaluateCacheHeaders(PackageSpec packageSpec, LucenePackage package)
        {
            if (package == null)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound,
                                                     string.Format("Package {0} version {1} not found.", packageSpec.Id,
                                                                   packageSpec.Version));
            }

            var etagMatch = Request.Headers.IfMatch.Any(etag => !etag.IsWeak && etag.Tag == '"' + package.PackageHash + '"');
            var notModifiedSince = Request.Headers.IfModifiedSince.HasValue &&
                                   Request.Headers.IfModifiedSince >= package.LastUpdated;

            if (etagMatch || notModifiedSince)
            {
                return Request.CreateResponse(HttpStatusCode.NotModified);
            }

            return null;
        }
        public void FindPackageInOriginHandlesExceptions()
        {
            var addedPackage = (IPackage)null;

            mirror.Setup(r => r.FindPackage(package1.Id, package1.Version)).Returns(() => addedPackage);
            origin1.Setup(r => r.FindPackage(package1.Id, package1.Version)).Throws<Exception>();
            origin2.Setup(r => r.FindPackage(package1.Id, package1.Version)).Returns(package1);
            mirror.Setup(r => r.AddPackage(package1)).Callback<IPackage>(pkg => addedPackage = new PackageSpec(pkg.Id, pkg.Version.ToString()));

            IPackage result = null;

            TestDelegate call = () => result = repo.FindPackage(package1.Id, package1.Version);

            Assert.That(call, Throws.Nothing);
            Assert.That(result, Is.SameAs(addedPackage));

            mirror.Verify();
            origin1.Verify();
            origin2.Verify();
        }
        private LucenePackage FindPackage(PackageSpec packageSpec)
        {
            LucenePackage package;

            if (packageSpec.Version != null)
            {
                package = (LucenePackage)Repository.FindPackage(packageSpec.Id, packageSpec.Version);
            }
            else
            {
                package = Repository.FindPackagesById(packageSpec.Id)
                                    .Cast<LucenePackage>()
                                    .Where(p => p.IsPrerelease == false)
                                    .OrderBy(p => p.Version).LastOrDefault();
            }
            return package;
        }