Skip to content

Commit ccefa98

Browse files
authored
Support multiple applicationUrl endpoints for the same scheme (#5481)
Fixes 5338
1 parent 0587e48 commit ccefa98

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

src/Aspire.Hosting/ProjectResourceBuilderExtensions.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,11 +402,27 @@ private static IResourceBuilder<ProjectResource> WithProjectDefaults(this IResou
402402
if (!kestrelEndpointsByScheme.Any())
403403
{
404404
var urlsFromApplicationUrl = launchProfile.ApplicationUrl?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? [];
405+
Dictionary<string, int> endpointCountByScheme = [];
405406
foreach (var url in urlsFromApplicationUrl)
406407
{
407408
var uri = new Uri(url);
408409

409-
builder.WithEndpoint(uri.Scheme, e =>
410+
// Keep track of how many endpoints we have for each scheme
411+
endpointCountByScheme.TryGetValue(uri.Scheme, out var count);
412+
endpointCountByScheme[uri.Scheme] = count + 1;
413+
414+
// If we have multiple for the same scheme, we differentiate them by appending a number.
415+
// We only do this starting with the second endpoint, so that the first stays just http/https.
416+
// This allows us to keep the same behavior as "dotnet run".
417+
// Also, note that we only do this in Run mode, as in Publish mode those extra endpoints
418+
// with generic names would not be easily usable.
419+
var endpointName = uri.Scheme;
420+
if (endpointCountByScheme[uri.Scheme] > 1)
421+
{
422+
endpointName += endpointCountByScheme[uri.Scheme];
423+
}
424+
425+
builder.WithEndpoint(endpointName, e =>
410426
{
411427
e.Port = uri.Port;
412428
e.UriScheme = uri.Scheme;

tests/Aspire.Hosting.Tests/ProjectResourceTests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,35 @@ public async Task ProjectWithLaunchProfileAddsHttpOrHttpsEndpointAddsToEnv()
410410
Assert.False(config.ContainsKey("ASPNETCORE_HTTPS_PORT"));
411411
}
412412

413+
[Fact]
414+
public async Task ProjectWithMultipleLaunchProfileAppUrlsGetsAllUrls()
415+
{
416+
var appBuilder = CreateBuilder(operation: DistributedApplicationOperation.Run);
417+
418+
var builder = appBuilder.AddProject<TestProjectWithManyAppUrlsInLaunchSettings>("projectName");
419+
420+
// Need to allocated all the endpoints we get from the launch profile applicationUrl
421+
var index = 0;
422+
foreach (var q in new[] { "http", "http2", "https", "https2", "https3" })
423+
{
424+
builder.WithEndpoint(q, e =>
425+
{
426+
e.AllocatedEndpoint = new(e, "localhost", e.Port!.Value, targetPortExpression: $"p{index++}");
427+
});
428+
}
429+
430+
using var app = appBuilder.Build();
431+
var appModel = app.Services.GetRequiredService<DistributedApplicationModel>();
432+
var projectResources = appModel.GetProjectResources();
433+
var resource = Assert.Single(projectResources);
434+
var config = await EnvironmentVariableEvaluator.GetEnvironmentVariablesAsync(resource, DistributedApplicationOperation.Run, TestServiceProvider.Instance);
435+
436+
Assert.Equal("https://localhost:p2;http://localhost:p0;http://localhost:p1;https://localhost:p3;https://localhost:p4", config["ASPNETCORE_URLS"]);
437+
438+
// The first https port is the one that should be used for ASPNETCORE_HTTPS_PORT
439+
Assert.Equal("7144", config["ASPNETCORE_HTTPS_PORT"]);
440+
}
441+
413442
[Fact]
414443
public void DisabledForwardedHeadersAddsAnnotationToProject()
415444
{
@@ -618,4 +647,25 @@ public TestProjectWithLaunchSettings()
618647
};
619648
}
620649
}
650+
651+
private sealed class TestProjectWithManyAppUrlsInLaunchSettings : BaseProjectWithProfileAndConfig
652+
{
653+
public TestProjectWithManyAppUrlsInLaunchSettings()
654+
{
655+
Profiles = new()
656+
{
657+
["https"] = new()
658+
{
659+
CommandName = "Project",
660+
CommandLineArgs = "arg1 arg2",
661+
LaunchBrowser = true,
662+
ApplicationUrl = "https://localhost:7144;http://localhost:5193;http://localhost:5194;https://localhost:7145;https://localhost:7146",
663+
EnvironmentVariables = new()
664+
{
665+
["ASPNETCORE_ENVIRONMENT"] = "Development"
666+
}
667+
}
668+
};
669+
}
670+
}
621671
}

0 commit comments

Comments
 (0)