Esempio n. 1
0
        public void HttpStreamValidation_ValidateNupkg_RejectsPartialNupkg()
        {
            // Arrange
            using (var zipStream = new MemoryStream())
                using (var stream = new MemoryStream())
                {
                    using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true))
                    {
                        zip.AddEntry("package.nuspec", new byte[0]);
                    }

                    zipStream.Seek(0, SeekOrigin.Begin);
                    var partialLength = (int)zipStream.Length - 1;
                    stream.Write(zipStream.ToArray(), 0, partialLength);
                    stream.Seek(0, SeekOrigin.Begin);

                    // Act & Assert
                    var actual = Assert.Throws <InvalidDataException>(() =>
                    {
                        HttpStreamValidation.ValidateNupkg(
                            Uri,
                            stream);
                    });

                    Assert.IsType <InvalidDataException>(actual.InnerException);
                }
        }
Esempio n. 2
0
        public void HttpStreamValidation_ValidateNupkg_RejectsNupkgWithBadPrefix()
        {
            // Arrange
            using (var zipStream = new MemoryStream())
                using (var stream = new MemoryStream())
                {
                    using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true))
                    {
                        zip.AddEntry("package.nuspec", new byte[0]);
                    }

                    zipStream.Seek(0, SeekOrigin.Begin);

                    var badPrefix = Encoding.ASCII.GetBytes("bad!!!");
                    stream.Write(badPrefix, 0, badPrefix.Length);
                    zipStream.CopyTo(stream);
                    stream.Seek(0, SeekOrigin.Begin);

                    // Act & Assert
                    var actual = Assert.Throws <InvalidDataException>(() =>
                    {
                        HttpStreamValidation.ValidateNupkg(
                            Uri,
                            stream);
                    });

                    Assert.IsType <InvalidDataException>(actual.InnerException);
                }
        }
Esempio n. 3
0
        private async Task <SortedDictionary <NuGetVersion, PackageInfo> > FindPackagesByIdAsync(string id, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                var baseUri = _baseUris[retry % _baseUris.Count].OriginalString;
                var uri     = baseUri + id.ToLowerInvariant() + "/index.json";

                try
                {
                    using (var result = await _httpSource.GetAsync(
                               uri,
                               $"list_{id}",
                               CreateCacheContext(retry),
                               Logger,
                               ignoreNotFounds: true,
                               ensureValidContents: stream => HttpStreamValidation.ValidateJObject(uri, stream),
                               cancellationToken: cancellationToken))
                    {
                        if (result.Status == HttpSourceResultStatus.NotFound)
                        {
                            return(new SortedDictionary <NuGetVersion, PackageInfo>());
                        }

                        try
                        {
                            return(ConsumeFlatContainerIndex(result.Stream, id, baseUri));
                        }
                        catch
                        {
                            Logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Log_FileIsCorrupt, result.CacheFileName));

                            throw;
                        }
                    }
                }
                catch (Exception ex) when(retry < 2)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_RetryingFindPackagesById, nameof(FindPackagesByIdAsync), uri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    Logger.LogMinimal(message);
                }
                catch (Exception ex) when(retry == 2)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToRetrievePackage, uri);

                    Logger.LogError(message + Environment.NewLine + ExceptionUtilities.DisplayMessage(ex));

                    throw new FatalProtocolException(message, ex);
                }
            }

            return(null);
        }
Esempio n. 4
0
        public void HttpStreamValidation_ValidateJObject_AcceptsMinimal()
        {
            // Arrange
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"
                {
                    ""foo"": 1,
                    ""bar"": 2
                }"));

            // Act & Assert
            HttpStreamValidation.ValidateJObject(Uri, stream);
        }
Esempio n. 5
0
        public void HttpStreamValidation_ValidateJObject_RejectsJsonArray()
        {
            // Arrange
            var stream = new MemoryStream(Encoding.UTF8.GetBytes("[1, 2]"));

            // Act & Assert
            var actual = Assert.Throws <InvalidDataException>(() =>
            {
                HttpStreamValidation.ValidateJObject(Uri, stream);
            });

            Assert.IsType <JsonReaderException>(actual.InnerException);
        }
Esempio n. 6
0
 public void HttpStreamValidation_ValidateXml_AcceptsMinimal()
 {
     // Arrange
     using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(@"<?xml version=""1.0"" encoding=""utf-8""?>
         <entry>
         </entry>
         ")))
     {
         // Act & Assert
         HttpStreamValidation.ValidateXml(
             Uri,
             stream);
     }
 }
Esempio n. 7
0
        public void HttpStreamValidation_ValidateNupkg_RejectsCompletelyInvalidZipNupkg()
        {
            // Arrange
            using (var stream = new MemoryStream(Encoding.ASCII.GetBytes("not a zip!")))
            {
                // Act & Assert
                var actual = Assert.Throws <InvalidDataException>(() =>
                {
                    HttpStreamValidation.ValidateNupkg(
                        Uri,
                        stream);
                });

                Assert.IsType <InvalidDataException>(actual.InnerException);
            }
        }
Esempio n. 8
0
        public void HttpStreamValidation_ValidateJObject_RejectsIncompleteJsonObjects()
        {
            // Arrange
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"
                {
                    ""foo"": 1,
                    ""bar"": 2"));

            // Act & Assert
            var actual = Assert.Throws <InvalidDataException>(() =>
            {
                HttpStreamValidation.ValidateJObject(Uri, stream);
            });

            Assert.IsType <JsonReaderException>(actual.InnerException);
        }
        private async Task <NupkgEntry> OpenNupkgStreamAsyncCore(PackageInfo package, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                try
                {
                    using (var data = await _httpSource.GetAsync(
                               package.ContentUri,
                               "nupkg_" + package.Id + "." + package.Version,
                               CreateCacheContext(retry),
                               Logger,
                               ignoreNotFounds: false,
                               ensureValidContents: stream => HttpStreamValidation.ValidateNupkg(package.ContentUri, stream),
                               cancellationToken: cancellationToken))
                    {
                        return(new NupkgEntry
                        {
                            TempFileName = data.CacheFileName
                        });
                    }
                }
                catch (TaskCanceledException) when(retry < 2)
                {
                    // Requests can get cancelled if we got the data from elsewhere, no reason to warn.
                    string message = string.Format(CultureInfo.CurrentCulture, Strings.Log_CanceledNupkgDownload, package.ContentUri);

                    Logger.LogMinimal(message);
                }
                catch (Exception ex)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToDownloadPackage, package.ContentUri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);
                    if (retry == 2)
                    {
                        Logger.LogError(message);
                    }
                    else
                    {
                        Logger.LogMinimal(message);
                    }
                }
            }

            return(null);
        }
Esempio n. 10
0
        public void HttpStreamValidation_ValidateXml_RejectsIncompleteBroken()
        {
            // Arrange
            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"<?xml version=""1.0"" encoding=""utf-8""?>
                <entry>
                <another>
                ")))
            {
                // Act & Assert
                var actual = Assert.Throws <InvalidDataException>(() =>
                {
                    HttpStreamValidation.ValidateXml(
                        Uri,
                        stream);
                });

                Assert.IsType <XmlException>(actual.InnerException);
            }
        }
Esempio n. 11
0
        public void HttpStreamValidation_ValidateNupkg_AcceptsMinimalNupkg()
        {
            // Arrange
            using (var stream = new MemoryStream())
            {
                using (var zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
                {
                    zip.AddEntry("package.nuspec", @"<?xml version=""1.0"" encoding=""utf-8""?>
<package>
</package>");
                }

                stream.Seek(0, SeekOrigin.Begin);

                // Act & Assert
                HttpStreamValidation.ValidateNupkg(
                    Uri,
                    stream);
            }
        }
        private async Task <NupkgEntry> OpenNupkgStreamAsyncCore(RemoteSourceDependencyInfo package, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                try
                {
                    using (var data = await _httpSource.GetAsync(
                               package.ContentUri,
                               "nupkg_" + package.Identity.Id + "." + package.Identity.Version.ToNormalizedString(),
                               CreateCacheContext(retry),
                               Logger,
                               ignoreNotFounds: false,
                               ensureValidContents: stream => HttpStreamValidation.ValidateNupkg(package.ContentUri, stream),
                               cancellationToken: cancellationToken))
                    {
                        return(new NupkgEntry
                        {
                            TempFileName = data.CacheFileName
                        });
                    }
                }
                catch (Exception ex) when(retry < 2)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToDownloadPackage, package.ContentUri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    Logger.LogMinimal(message);
                }
                catch (Exception ex) when(retry == 2)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToDownloadPackage, package.ContentUri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    Logger.LogError(message);
                }
            }

            return(null);
        }
Esempio n. 13
0
        public void HttpStreamValidation_ValidateNupkg_RejectsBrokenNuspec()
        {
            // Arrange
            using (var stream = new MemoryStream())
            {
                using (var zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
                {
                    zip.AddEntry("package.nuspec", new byte[0]);
                }

                stream.Seek(0, SeekOrigin.Begin);

                // Act & Assert
                var actual = Assert.Throws <InvalidDataException>(() =>
                {
                    HttpStreamValidation.ValidateNupkg(
                        Uri,
                        stream);
                });

                Assert.IsType <XmlException>(actual.InnerException);
            }
        }
        private async Task <IEnumerable <PackageInfo> > FindPackagesByIdAsyncCore(string id, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                var uri = _baseUri + "FindPackagesById()?id='" + id + "'";

                try
                {
                    var results = new List <PackageInfo>();
                    var page    = 1;
                    while (true)
                    {
                        // TODO: Pages for a package Id are cached separately.
                        // So we will get inaccurate data when a page shrinks.
                        // However, (1) In most cases the pages grow rather than shrink;
                        // (2) cache for pages is valid for only 30 min.
                        // So we decide to leave current logic and observe.
                        using (var data = await _httpSource.GetAsync(
                                   uri,
                                   new[] { new MediaTypeWithQualityHeaderValue("application/atom+xml"), new MediaTypeWithQualityHeaderValue("application/xml") },
                                   $"list_{id}_page{page}",
                                   CreateCacheContext(retry),
                                   Logger,
                                   ignoreNotFounds: false,
                                   ensureValidContents: stream => HttpStreamValidation.ValidateXml(uri, stream),
                                   cancellationToken: cancellationToken))
                        {
                            if (data.Status == HttpSourceResultStatus.NoContent)
                            {
                                // Team city returns 204 when no versions of the package exist
                                // This should result in an empty list and we should not try to
                                // read the stream as xml.
                                break;
                            }

                            var doc = V2FeedParser.LoadXml(data.Stream);

                            var result = doc.Root
                                         .Elements(_xnameEntry)
                                         .Select(x => BuildModel(id, x))
                                         .Where(x => x != null);

                            results.AddRange(result);

                            // Find the next url for continuation
                            var nextUri = V2FeedParser.GetNextUrl(doc);

                            // Stop if there's nothing else to GET
                            if (string.IsNullOrEmpty(nextUri))
                            {
                                break;
                            }

                            uri = nextUri;
                            page++;
                        }
                    }

                    return(results);
                }
                catch (Exception ex) when(retry < 2)
                {
                    string message = string.Format(CultureInfo.CurrentCulture, Strings.Log_RetryingFindPackagesById, nameof(FindPackagesByIdAsyncCore), uri)
                                     + Environment.NewLine
                                     + ExceptionUtilities.DisplayMessage(ex);

                    Logger.LogMinimal(message);
                }
                catch (Exception ex) when(retry == 2)
                {
                    // Fail silently by returning empty result list
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToRetrievePackage, uri);

                    Logger.LogError(message + Environment.NewLine + ex.Message);

                    throw new FatalProtocolException(message, ex);
                }
            }

            return(null);
        }