Skip to content

Commit e91693f

Browse files
committed
C#: Only include feeds that we can connect to.
1 parent 46ebf88 commit e91693f

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -138,20 +138,18 @@ public HashSet<AssemblyLookupLocation> Restore()
138138
compilationInfoContainer.CompilationInfos.Add(("Inherited NuGet feed count", inheritedFeeds.Count.ToString()));
139139
}
140140

141-
if (!CheckSpecifiedFeeds(explicitFeeds))
141+
if (!CheckSpecifiedFeeds(explicitFeeds, out var reachableFeeds))
142142
{
143+
// If we experience a timeout, we use this fallback.
143144
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
144145
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
145146
return unresponsiveMissingPackageLocation is null
146147
? []
147148
: [unresponsiveMissingPackageLocation];
148149
}
149150

150-
// All explicit feeds can be considered reachable
151-
HashSet<string> reachableFeeds = [];
152-
reachableFeeds.UnionWith(explicitFeeds);
153151
// Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific).
154-
reachableFeeds.UnionWith(GetReachableNuGetFeeds(inheritedFeeds, isFallback: false, allowNonTimeoutExceptions: false));
152+
reachableFeeds.UnionWith(GetReachableNuGetFeeds(inheritedFeeds, isFallback: false, out var _));
155153

156154
// If feed responsiveness is being checked, we only want to use the feeds that are reachable (note this set includes private
157155
// registry feeds if they are reachable).
@@ -234,16 +232,22 @@ public HashSet<AssemblyLookupLocation> Restore()
234232
/// </summary>
235233
/// <param name="feedsToCheck">The feeds to check.</param>
236234
/// <param name="isFallback">Whether the feeds are fallback feeds or not.</param>
237-
/// <param name="allowNonTimeoutExceptions">Whether to allow non-timeout exceptions.</param>
235+
/// <param name="isTimeout">Whether a timeout occurred while checking the feeds.</param>
238236
/// <returns>The list of feeds that could be reached.</returns>
239-
private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool isFallback, bool allowNonTimeoutExceptions)
237+
private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool isFallback, out bool isTimeout)
240238
{
241239
var fallbackStr = isFallback ? "fallback " : "";
242240
logger.LogInfo($"Checking {fallbackStr}NuGet feed reachability on feeds: {string.Join(", ", feedsToCheck.OrderBy(f => f))}");
243241

244242
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback);
243+
var timeout = false;
245244
var reachableFeeds = feedsToCheck
246-
.Where(feed => IsFeedReachable(feed, initialTimeout, tryCount, allowNonTimeoutExceptions))
245+
.Where(feed =>
246+
{
247+
var reachable = IsFeedReachable(feed, initialTimeout, tryCount, out var feedTimeout);
248+
timeout |= feedTimeout;
249+
return reachable;
250+
})
247251
.ToList();
248252

249253
if (reachableFeeds.Count == 0)
@@ -255,13 +259,14 @@ private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool i
255259
logger.LogInfo($"Reachable {fallbackStr}NuGet feeds: {string.Join(", ", reachableFeeds.OrderBy(f => f))}");
256260
}
257261

262+
isTimeout = timeout;
258263
return reachableFeeds;
259264
}
260265

261266
private bool IsDefaultFeedReachable()
262267
{
263268
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
264-
return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount, allowNonTimeoutExceptions: false);
269+
return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount, out var _);
265270
}
266271

267272
private List<string> GetReachableFallbackNugetFeeds(HashSet<string>? feedsFromNugetConfigs)
@@ -284,7 +289,7 @@ private List<string> GetReachableFallbackNugetFeeds(HashSet<string>? feedsFromNu
284289
}
285290
}
286291

287-
var reachableFallbackFeeds = GetReachableNuGetFeeds(fallbackFeeds, isFallback: true, allowNonTimeoutExceptions: false);
292+
var reachableFallbackFeeds = GetReachableNuGetFeeds(fallbackFeeds, isFallback: true, out var _);
288293

289294
compilationInfoContainer.CompilationInfos.Add(("Reachable fallback NuGet feed count", reachableFallbackFeeds.Count.ToString()));
290295

@@ -685,7 +690,7 @@ private static async Task<HttpResponseMessage> ExecuteGetRequest(string address,
685690
return await httpClient.GetAsync(address, cancellationToken);
686691
}
687692

688-
private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, bool allowNonTimeoutExceptions)
693+
private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, out bool isTimeout)
689694
{
690695
logger.LogInfo($"Checking if NuGet feed '{feed}' is reachable...");
691696

@@ -718,6 +723,8 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount,
718723

719724
using HttpClient client = new(httpClientHandler);
720725

726+
isTimeout = false;
727+
721728
for (var i = 0; i < tryCount; i++)
722729
{
723730
using var cts = new CancellationTokenSource();
@@ -741,16 +748,13 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount,
741748
continue;
742749
}
743750

744-
// Adjust the message based on whether non-timeout exceptions are allowed.
745-
var useMessage = allowNonTimeoutExceptions
746-
? "Considering the feed for use despite of the failure as it wasn't a timeout."
747-
: "Not considering the feed for use.";
748-
logger.LogInfo($"Querying NuGet feed '{feed}' failed. {useMessage} The reason for the failure: {exc.Message}");
749-
return allowNonTimeoutExceptions;
751+
logger.LogInfo($"Querying NuGet feed '{feed}' failed. The reason for the failure: {exc.Message}");
752+
return false;
750753
}
751754
}
752755

753756
logger.LogWarning($"Didn't receive answer from NuGet feed '{feed}'. Tried it {tryCount} times.");
757+
isTimeout = true;
754758
return false;
755759
}
756760

@@ -793,10 +797,12 @@ private HashSet<string> GetExcludedFeeds()
793797
/// Checks that we can connect to the specified NuGet feeds.
794798
/// </summary>
795799
/// <param name="feeds">The set of package feeds to check.</param>
800+
/// <param name="reachableFeeds">The list of feeds that were reachable.</param>
796801
/// <returns>
797-
/// True if all feeds are reachable (excluding any feeds that are configured to be excluded from the check) or false otherwise.
802+
/// True if there is no timeout when trying to reach the feeds (excluding any feeds that are configured
803+
/// to be excluded from the check) or false otherwise.
798804
/// </returns>
799-
private bool CheckSpecifiedFeeds(HashSet<string> feeds)
805+
private bool CheckSpecifiedFeeds(HashSet<string> feeds, out HashSet<string> reachableFeeds)
800806
{
801807
// Exclude any feeds from the feed check that are configured by the corresponding environment variable.
802808
// These feeds are always assumed to be reachable.
@@ -812,12 +818,11 @@ private bool CheckSpecifiedFeeds(HashSet<string> feeds)
812818
return true;
813819
}).ToHashSet();
814820

815-
var reachableFeeds = GetReachableNuGetFeeds(feedsToCheck, isFallback: false, allowNonTimeoutExceptions: true);
816-
var allFeedsReachable = reachableFeeds.Count == feedsToCheck.Count;
817-
818-
EmitUnreachableFeedsDiagnostics(allFeedsReachable);
821+
reachableFeeds = GetReachableNuGetFeeds(feedsToCheck, isFallback: false, out var isTimeout).ToHashSet();
819822

820-
return allFeedsReachable;
823+
var noTimeout = !isTimeout;
824+
EmitUnreachableFeedsDiagnostics(noTimeout);
825+
return noTimeout;
821826
}
822827

823828
/// <summary>

0 commit comments

Comments
 (0)