Aspire external resource stubbing #725

Closed
opened 2025-12-29 08:33:00 +01:00 by adam · 3 comments
Owner

Originally created by @weitzhandler on GitHub (Nov 12, 2025).

Hi,

I'm working on an Aspire solution with multiple projects.
I want to take control of the entire DistributedApplication cluster (I use DistributedApplicationTestingBuilder.CreateAsync to create it), so that whenever a webpage is requested from the web that falls under the configured criteria (e.g. via matchers etc.), it should return the customized response.

Is this possible with the current implementation?

Originally created by @weitzhandler on GitHub (Nov 12, 2025). Hi, I'm working on an Aspire solution with multiple projects. I want to take control of the entire `DistributedApplication` cluster (I use `DistributedApplicationTestingBuilder.CreateAsync` to create it), so that whenever a webpage is requested from the web that falls under the configured criteria (e.g. via matchers etc.), it should return the customized response. Is this possible with the current implementation?
adam added the question label 2025-12-29 08:33:00 +01:00
adam closed this issue 2025-12-29 08:33:00 +01:00
Author
Owner

@weitzhandler commented on GitHub (Nov 17, 2025):

This worked, however it only works for HTTP:

IDisposable StartWireMockDefault() =>
    StartWireMock(
        request =>
            request.WithUrl(url =>
            {
                return true;
            }),
        response =>
            response
            .WithBody(request => "Response from WireMock"));

IDisposable StartWireMock(Action<IRequestBuilder> requestBuilder, Action<IResponseBuilder> responseBuilder)
{
    var settings = new WireMockServerSettings
    {
        StartAdminInterface = true,
        UseSSL = true,
        AcceptAnyClientCertificate = true,
        ClientCertificateMode = WireMock.Types.ClientCertificateMode.AllowCertificate
    };

    var server = WireMockServer.Start(settings);

    Environment.SetEnvironmentVariable("ALL_PROXY", server.Url);
    Environment.SetEnvironmentVariable("NO_PROXY", "localhost,127.0.0.0/8,::1/128,[::1]");

    server
        .WhenRequest(requestBuilder)
        .ThenRespondWith(responseBuilder);

    return new Disposable(server);
}

private class Disposable(IDisposable server) : IDisposable
{
    public void Dispose()
    {
        Environment.SetEnvironmentVariable("ALL_PROXY", null);
        Environment.SetEnvironmentVariable("NO_PROXY", null);

        server.Dispose();
    }
}

Consumer API Program.cs:

app.MapGet("/", async (IConfiguration config, HttpClient httpClient, HttpContext context) =>
{
    var response = await httpClient.GetAsync("http://httpbin.org/get");
    var body = await response.Content.ReadAsStringAsync();

    context.Response.StatusCode = StatusCodes.Status200OK;
});

As soon as the URL is changed to HTTPS, GetAsync throws the following exception:

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.

Stack trace:

at System.Net.Http.ConnectHelper.d__2.MoveNext()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionPool.<ConnectAsync>d__53.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.HttpConnectionPool.d__81.MoveNext()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionPool.<InjectNewHttp11ConnectionAsync>d__80.MoveNext() at System.Threading.Tasks.TaskCompletionSourceWithCancellation1.d__1.MoveNext()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionWaiter1.d__6.MoveNext()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionPool.<SendWithVersionDetectionAndRetryAsync>d__52.MoveNext() at System.Net.Http.Metrics.MetricsHandler.<SendAsyncWithMetrics>d__6.MoveNext() at System.Net.Http.DiagnosticsHandler.<SendAsyncCore>d__10.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.RedirectHandler.d__4.MoveNext()
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.<g__Core|4_0>d.MoveNext()
at Microsoft.Extensions.ServiceDiscovery.Http.ResolvingHttpDelegatingHandler.d__4.MoveNext()
at Microsoft.Extensions.Http.Resilience.ResilienceHandler.<>c.<b__3_0>d.MoveNext()
at Polly.Outcome`1.ThrowIfException()
at Microsoft.Extensions.Http.Resilience.ResilienceHandler.d__3.MoveNext()
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.<g__Core|4_0>d.MoveNext()
at System.Net.Http.HttpClient.<g__Core|83_0>d.MoveNext()
at Program.<>c.<<

$>b__0_0>d.MoveNext() in D:\Users\Shimmy\Documents\Visual Studio 18\Projects\WireMockProxy\WireMockProxy.ApiService\Program.cs:line 26

Inner exception:

System.Security.Authentication.AuthenticationException: Cannot determine the frame size or a corrupted frame was received.

Stack trace:

at System.Net.Security.SslStream.GetFrameSize(ReadOnlySpan1 buffer) at System.Net.Security.SslStream.<EnsureFullTlsFrameAsync>d__1701.MoveNext()
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder1.StateMachineBox1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at System.Net.Security.SslStream.d__1601.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Security.SslStream.d__159`1.MoveNext()
at System.Net.Http.ConnectHelper.d__2.MoveNext()

@weitzhandler commented on GitHub (Nov 17, 2025): This worked, however it only works for HTTP: ```csharp IDisposable StartWireMockDefault() => StartWireMock( request => request.WithUrl(url => { return true; }), response => response .WithBody(request => "Response from WireMock")); IDisposable StartWireMock(Action<IRequestBuilder> requestBuilder, Action<IResponseBuilder> responseBuilder) { var settings = new WireMockServerSettings { StartAdminInterface = true, UseSSL = true, AcceptAnyClientCertificate = true, ClientCertificateMode = WireMock.Types.ClientCertificateMode.AllowCertificate }; var server = WireMockServer.Start(settings); Environment.SetEnvironmentVariable("ALL_PROXY", server.Url); Environment.SetEnvironmentVariable("NO_PROXY", "localhost,127.0.0.0/8,::1/128,[::1]"); server .WhenRequest(requestBuilder) .ThenRespondWith(responseBuilder); return new Disposable(server); } private class Disposable(IDisposable server) : IDisposable { public void Dispose() { Environment.SetEnvironmentVariable("ALL_PROXY", null); Environment.SetEnvironmentVariable("NO_PROXY", null); server.Dispose(); } } ``` Consumer API _Program.cs_: ``` app.MapGet("/", async (IConfiguration config, HttpClient httpClient, HttpContext context) => { var response = await httpClient.GetAsync("http://httpbin.org/get"); var body = await response.Content.ReadAsStringAsync(); context.Response.StatusCode = StatusCodes.Status200OK; }); ``` As soon as the URL is changed to HTTPS, `GetAsync` throws the following exception: System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. Stack trace: > at System.Net.Http.ConnectHelper.<EstablishSslConnectionAsync>d__2.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionPool.<ConnectAsync>d__53.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionPool.<CreateHttp11ConnectionAsync>d__81.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionPool.<InjectNewHttp11ConnectionAsync>d__80.MoveNext() at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.<WaitWithCancellationAsync>d__1.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionWaiter`1.<WaitForConnectionWithTelemetryAsync>d__6.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.HttpConnectionPool.<SendWithVersionDetectionAndRetryAsync>d__52.MoveNext() at System.Net.Http.Metrics.MetricsHandler.<SendAsyncWithMetrics>d__6.MoveNext() at System.Net.Http.DiagnosticsHandler.<SendAsyncCore>d__10.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext() at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.<<SendCoreAsync>g__Core|4_0>d.MoveNext() at Microsoft.Extensions.ServiceDiscovery.Http.ResolvingHttpDelegatingHandler.<SendAsync>d__4.MoveNext() at Microsoft.Extensions.Http.Resilience.ResilienceHandler.<>c.<<SendAsync>b__3_0>d.MoveNext() at Polly.Outcome`1.ThrowIfException() at Microsoft.Extensions.Http.Resilience.ResilienceHandler.<SendAsync>d__3.MoveNext() at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.<<SendCoreAsync>g__Core|4_0>d.MoveNext() at System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext() at Program.<>c.<<<Main>$>b__0_0>d.MoveNext() in D:\Users\Shimmy\Documents\Visual Studio 18\Projects\WireMockProxy\WireMockProxy.ApiService\Program.cs:line 26 Inner exception: System.Security.Authentication.AuthenticationException: Cannot determine the frame size or a corrupted frame was received. Stack trace: > at System.Net.Security.SslStream.GetFrameSize(ReadOnlySpan`1 buffer) at System.Net.Security.SslStream.<EnsureFullTlsFrameAsync>d__170`1.MoveNext() at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token) at System.Net.Security.SslStream.<ReceiveHandshakeFrameAsync>d__160`1.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at System.Net.Security.SslStream.<ForceAuthenticationAsync>d__159`1.MoveNext() at System.Net.Http.ConnectHelper.<EstablishSslConnectionAsync>d__2.MoveNext()
Author
Owner

@weitzhandler commented on GitHub (Nov 18, 2025):

What I ended up doing is I added a delegating handler in the client side (only if environment is development) that changes the URL scheme to http and changes port to non-secure if needed.

@weitzhandler commented on GitHub (Nov 18, 2025): What I ended up doing is I added a delegating handler in the client side (only if environment is development) that changes the URL scheme to `http` and changes port to non-secure if needed.
Author
Owner

@weitzhandler commented on GitHub (Nov 19, 2025):

@StefH
Any ways to use WM with HTTPS?

@weitzhandler commented on GitHub (Nov 19, 2025): @StefH Any ways to use WM with HTTPS?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net#725