Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting" Version="13.1.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="HenrikJensen.SutFactory" Version="1.0.0-beta2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
<PackageVersion Include="Yarp.ReverseProxy" Version="2.3.0" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.9.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.1.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.13.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.13.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
<PackageVersion Include="HenrikJensen.SutFactory" Version="1.0.0-beta2" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.1.118" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="8.0.1" />
<PackageVersion Include="xunit.analyzers" Version="1.25.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="Yarp.ReverseProxy" Version="2.3.0" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions examples/Aspire.Website/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<body>
<h1>Website</h1>
<p><b>You should see this page when navigating to "https://example-website.local/".</b></p>
<p>This website do not use SSL. Instead, a secure HTTPS connection is provided by the reverse proxy.</p>
<p>In case "example-website.local" cannot be found then you need to map it to 127.0.0.1 and ::1 in your local hosts file.</p>
<p>This website does not use SSL. Instead, a secure HTTPS connection is provided by the reverse proxy.</p>
<p>In case "example-website.local" cannot be found then you need to map it in your local hosts file.</p>
</body>
</html>
3 changes: 3 additions & 0 deletions src/ReverseProxy.Aspire/ResourceBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
// limitations under the License.
// </copyright>

using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;

namespace Hj.ReverseProxy.Aspire;

public static class ResourceBuilderExtensions
Expand Down
5 changes: 3 additions & 2 deletions src/ReverseProxy.Aspire/ReverseProxy.Aspire.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Aspire.AppHost.Sdk/13.1.0">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
Expand All @@ -13,7 +13,7 @@
<PackageTags>testing;reverse-proxy;aspire</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>1.0.0-beta5</Version>
<Version>1.0.0-beta6</Version>
</PropertyGroup>

<ItemGroup>
Expand All @@ -31,6 +31,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting" />
<PackageReference Include="Yarp.ReverseProxy" />
</ItemGroup>

Expand Down
10 changes: 6 additions & 4 deletions src/ReverseProxy/Certificate/CertificateConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ public SelfSignedOptions GetOptions()
throw new InvalidOperationException("CA file path is not configured");
}

// Expand {REVERSEPROXY_HOME} token if present: use env var if set, otherwise use user home directory
// If token is not present, use the path as-is (physical file path)
if (selfSignedOptions.CaFilePath.Contains("{REVERSEPROXY_HOME}", StringComparison.Ordinal))
{
var reverseProxyHome = Environment.GetEnvironmentVariable("REVERSEPROXY_HOME")
?? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var reverseProxyHome = Environment.GetEnvironmentVariable("REVERSEPROXY_HOME");
if (string.IsNullOrWhiteSpace(reverseProxyHome))
{
throw new InvalidOperationException("Environment variable REVERSEPROXY_HOME is not set");
}

selfSignedOptions.CaFilePath = selfSignedOptions.CaFilePath.Replace("{REVERSEPROXY_HOME}", reverseProxyHome, StringComparison.Ordinal);
}

Expand Down
2 changes: 1 addition & 1 deletion src/ReverseProxy/ReverseProxy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageTags>testing;reverse-proxy;certificates</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>1.0.0-beta5</Version>
<Version>1.0.0-beta6</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
43 changes: 26 additions & 17 deletions test/ReverseProxy.UnitTest/Certificate/CertificateConfigTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Hj.ReverseProxy.UnitTest.Certificate;

[Collection("EnvironmentVariable")]
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Collection attribute references "EnvironmentVariable" but there is no corresponding CollectionDefinition class defined in the test project. In xUnit, when using the Collection attribute, you need to define a collection definition class with the matching name. Without the definition, this attribute has no effect and tests may run in parallel, potentially causing race conditions when manipulating environment variables.

Copilot uses AI. Check for mistakes.
public class CertificateConfigTests
{
[Fact]
Expand Down Expand Up @@ -78,34 +79,42 @@ public void GetOptions_GivenPhysicalFilePath_UsesPathAsIs()
Assert.Equal(expectedPath, result.CaFilePath);
}

[Fact]
public void GetOptions_GivenReverseProxyHomeToken_ExpandsToUserHomeWhenEnvVarNotSet()
[Theory]
[InlineData(null)]
[InlineData("")]
public void GetOptions_GivenInvalidReverseProxyHome_Throws(string? homeValue)
{
// arrange
Environment.SetEnvironmentVariable("REVERSEPROXY_HOME", null);
var expectedPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var configuration = CreateConfiguration(new()
var originalHome = Environment.GetEnvironmentVariable("REVERSEPROXY_HOME");
try
{
{ "SelfSignedCertificate:CaFilePath", "{REVERSEPROXY_HOME}" },
});
Environment.SetEnvironmentVariable("REVERSEPROXY_HOME", homeValue);

var sut = new CertificateConfig(configuration);
var configuration = CreateConfiguration(new()
{
{ "SelfSignedCertificate:CaFilePath", "{REVERSEPROXY_HOME}" },
});

// act
var result = sut.GetOptions();
var sut = new CertificateConfig(configuration);

// assert
Assert.Equal(expectedPath, result.CaFilePath);
// act & assert
Assert.ThrowsAny<InvalidOperationException>(sut.GetOptions);
}
finally
{
Environment.SetEnvironmentVariable("REVERSEPROXY_HOME", originalHome);
}
}

[Fact]
public void GetOptions_GivenReverseProxyHomeToken_ExpandsToEnvVarWhenSet()
public void GetOptions_GivenReverseProxyHome_UsesPathFromEnv()
{
// arrange
const string CustomPath = "/custom/reverseproxy/path";
var originalHome = Environment.GetEnvironmentVariable("REVERSEPROXY_HOME");
try
{
Environment.SetEnvironmentVariable("REVERSEPROXY_HOME", CustomPath);
Environment.SetEnvironmentVariable("REVERSEPROXY_HOME", "/custom");

var configuration = CreateConfiguration(new()
{
{ "SelfSignedCertificate:CaFilePath", "{REVERSEPROXY_HOME}" },
Expand All @@ -117,11 +126,11 @@ public void GetOptions_GivenReverseProxyHomeToken_ExpandsToEnvVarWhenSet()
var result = sut.GetOptions();

// assert
Assert.Equal(CustomPath, result.CaFilePath);
Assert.Equal("/custom", result.CaFilePath);
}
finally
{
Environment.SetEnvironmentVariable("REVERSEPROXY_HOME", null);
Environment.SetEnvironmentVariable("REVERSEPROXY_HOME", originalHome);
}
}

Expand Down
Loading