public static async Task <NupkgEntry> OpenNupkgStreamAsync( HttpSource httpSource, PackageInfo package, TimeSpan cacheAgeLimit, Reports reports) { for (int retry = 0; retry != 3; ++retry) { try { using (var data = await httpSource.GetAsync( package.ContentUri, cacheKey: $"nupkg_{package.Id}.{package.Version}", cacheAgeLimit: retry == 0 ? cacheAgeLimit : TimeSpan.Zero, ensureValidContents: stream => EnsureValidPackageContents(stream, package))) { return(new NupkgEntry { TempFileName = data.CacheFileName }); } } catch (Exception ex) { var isFinalAttempt = (retry == 2); var message = ex.Message; if (ex is TaskCanceledException) { message = ErrorMessageUtils.GetFriendlyTimeoutErrorMessage(ex as TaskCanceledException, isFinalAttempt, ignoreFailure: false); } if (isFinalAttempt) { reports.Error.WriteLine( $"Error: DownloadPackageAsync: {package.ContentUri}{Environment.NewLine} {message}".Red().Bold()); throw; } else { reports.Information.WriteLine( $"Warning: DownloadPackageAsync: {package.ContentUri}{Environment.NewLine} {message}".Yellow().Bold()); } } } return(null); }
public async Task <IEnumerable <PackageInfo> > FindPackagesByIdAsyncCore(string id) { for (int retry = 0; retry != 3; ++retry) { if (_ignored) { return(new List <PackageInfo>()); } try { var uri = $"{_baseUri}FindPackagesById()?id='{id}'"; 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, cacheKey: $"list_{id}_page{page}", cacheAgeLimit: retry == 0 ? _cacheAgeLimitList : TimeSpan.Zero, ensureValidContents: stream => EnsureValidFindPackagesResponse(stream, uri))) { try { var doc = XDocument.Load(data.Stream); var result = doc.Root .Elements(_xnameEntry) .Select(x => BuildModel(id, x)); results.AddRange(result); // Example of what this looks like in the odata feed: // <link rel="next" href="{nextLink}" /> var nextUri = (from e in doc.Root.Elements(_xnameLink) let attr = e.Attribute("rel") where attr != null && string.Equals(attr.Value, "next", StringComparison.OrdinalIgnoreCase) select e.Attribute("href") into nextLink where nextLink != null select nextLink.Value).FirstOrDefault(); // Stop if there's nothing else to GET if (string.IsNullOrEmpty(nextUri)) { break; } uri = nextUri; page++; } catch (XmlException) { _reports.Information.WriteLine( $"XML file {data.CacheFileName} is corrupt".Yellow().Bold()); throw; } } } return(results); } catch (Exception ex) { var isFinalAttempt = (retry == 2); var message = ex.Message; if (ex is TaskCanceledException) { message = ErrorMessageUtils.GetFriendlyTimeoutErrorMessage( ex as TaskCanceledException, isFinalAttempt, _ignoreFailure); } if (isFinalAttempt) { // Fail silently by returning empty result list if (_ignoreFailure) { _ignored = true; _reports.Information.WriteLine( $"Warning: FindPackagesById: {id}{Environment.NewLine} {message}".Yellow().Bold()); return(new List <PackageInfo>()); } _reports.Error.WriteLine( $"Error: FindPackagesById: {id}{Environment.NewLine} {message}".Red().Bold()); throw; } else { _reports.Information.WriteLine( $"Warning: FindPackagesById: {id}{Environment.NewLine} {message}".Yellow().Bold()); } } } return(null); }
public async Task <IEnumerable <PackageInfo> > FindPackagesByIdAsyncCore(string id) { for (int retry = 0; retry != 3; ++retry) { if (_ignored) { return(new List <PackageInfo>()); } try { var uri = _baseUri + id.ToLowerInvariant() + "/index.json"; var results = new List <PackageInfo>(); using (var data = await _httpSource.GetAsync(uri, string.Format("list_{0}", id), retry == 0 ? _cacheAgeLimitList : TimeSpan.Zero, ensureValidContents: stream => EnsureValidFindPackagesResponse(stream, uri), throwNotFound: false)) { if (data.Stream == null) { return(Enumerable.Empty <PackageInfo>()); } try { JObject doc; using (var reader = new StreamReader(data.Stream)) { doc = JObject.Load(new JsonTextReader(reader)); } var result = doc["versions"] .Select(x => BuildModel(id, x.ToString())) .Where(x => x != null); results.AddRange(result); } catch { _reports.Information.WriteLine("The file {0} is corrupt", data.CacheFileName.Yellow().Bold()); throw; } } return(results); } catch (Exception ex) { var isFinalAttempt = (retry == 2); var message = ex.Message; if (ex is TaskCanceledException) { message = ErrorMessageUtils.GetFriendlyTimeoutErrorMessage( ex as TaskCanceledException, isFinalAttempt, _ignoreFailure); } if (isFinalAttempt) { // Fail silently by returning empty result list if (_ignoreFailure) { _ignored = true; _reports.Information.WriteLine( $"Warning: FindPackagesById: {id}{Environment.NewLine} {message}".Yellow().Bold()); return(new List <PackageInfo>()); } _reports.Error.WriteLine( $"Error: FindPackagesById: {id}{Environment.NewLine} {message}".Red().Bold()); throw; } else { _reports.Information.WriteLine( $"Warning: FindPackagesById: {id}{Environment.NewLine} {message}".Yellow().Bold()); } } } return(null); }