Add WebSockets

This commit is contained in:
Stef Heyenrath
2026-02-09 21:09:58 +01:00
parent dff55e175b
commit 39b09ccb44
39 changed files with 2318 additions and 33 deletions

View File

@@ -80,6 +80,14 @@ internal partial class AspNetCoreSelfHost : IOwinSelfHost
#if NET8_0_OR_GREATER
UseCors(appBuilder);
var webSocketOptions = new WebSocketOptions();
if (_wireMockMiddlewareOptions.WebSocketSettings?.KeepAliveIntervalSeconds != null)
{
webSocketOptions.KeepAliveInterval = TimeSpan.FromSeconds(_wireMockMiddlewareOptions.WebSocketSettings.KeepAliveIntervalSeconds);
}
appBuilder.UseWebSockets(webSocketOptions);
#endif
_wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder);

View File

@@ -11,6 +11,7 @@ using WireMock.Matchers;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using WireMock.WebSockets;
using ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode;
namespace WireMock.Owin;
@@ -82,11 +83,21 @@ internal interface IWireMockMiddlewareOptions
QueryParameterMultipleValueSupport? QueryParameterMultipleValueSupport { get; set; }
public bool ProxyAll { get; set; }
bool ProxyAll { get; set; }
/// <summary>
/// Gets or sets the activity tracing options.
/// When set, System.Diagnostics.Activity objects are created for request tracing.
/// </summary>
ActivityTracingOptions? ActivityTracingOptions { get; set; }
/// <summary>
/// The WebSocket connection registries per mapping (used for broadcast).
/// </summary>
ConcurrentDictionary<Guid, WebSocketConnectionRegistry> WebSocketRegistries { get; }
/// <summary>
/// WebSocket settings.
/// </summary>
WebSocketSettings? WebSocketSettings { get; set; }
}

View File

@@ -15,6 +15,7 @@ using RandomDataGenerator.Randomizers;
using Stef.Validation;
using WireMock.Http;
using WireMock.ResponseBuilders;
using WireMock.ResponseProviders;
using WireMock.Types;
using WireMock.Util;
@@ -58,7 +59,7 @@ namespace WireMock.Owin.Mappers
/// <inheritdoc />
public async Task MapAsync(IResponseMessage? responseMessage, HttpResponse response)
{
if (responseMessage == null)
if (responseMessage == null || responseMessage is WebSocketHandledResponse)
{
return;
}

View File

@@ -25,7 +25,6 @@ namespace WireMock.Owin;
internal class WireMockMiddleware
{
private readonly object _lock = new();
private static readonly Task CompletedTask = Task.FromResult(false);
private readonly IWireMockMiddlewareOptions _options;
private readonly IOwinRequestMapper _requestMapper;
@@ -66,6 +65,9 @@ internal class WireMockMiddleware
private async Task InvokeInternalAsync(HttpContext ctx)
{
// Store options in HttpContext for providers to access (e.g., WebSocketResponseProvider)
ctx.Items[nameof(WireMockMiddlewareOptions)] = _options;
var request = await _requestMapper.MapAsync(ctx.Request, _options).ConfigureAwait(false);
var logRequest = false;
@@ -144,9 +146,7 @@ internal class WireMockMiddleware
var (theResponse, theOptionalNewMapping) = await targetMapping.ProvideResponseAsync(ctx, request).ConfigureAwait(false);
response = theResponse;
var responseBuilder = targetMapping.Provider as Response;
if (!targetMapping.IsAdminInterface && theOptionalNewMapping != null)
if (targetMapping.Provider is Response responseBuilder && !targetMapping.IsAdminInterface && theOptionalNewMapping != null)
{
if (responseBuilder?.ProxyAndRecordSettings?.SaveMapping == true || targetMapping.Settings.ProxyAndRecordSettings?.SaveMapping == true)
{
@@ -227,8 +227,6 @@ internal class WireMockMiddleware
await _responseMapper.MapAsync(notFoundResponse, ctx.Response).ConfigureAwait(false);
}
}
await CompletedTask.ConfigureAwait(false);
}
private async Task SendToWebhooksAsync(IMapping mapping, IRequestMessage request, IResponseMessage response)

View File

@@ -8,10 +8,10 @@ using Microsoft.Extensions.DependencyInjection;
using WireMock.Handlers;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Owin.ActivityTracing;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using WireMock.WebSockets;
using ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode;
namespace WireMock.Owin;
@@ -40,7 +40,6 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
public Action<IApplicationBuilder>? PostWireMockMiddlewareInit { get; set; }
//#if USE_ASPNETCORE
public Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
public CorsPolicyOptions? CorsPolicyOptions { get; set; }
@@ -49,7 +48,6 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
/// <inheritdoc />
public bool AcceptAnyClientCertificate { get; set; }
//#endif
/// <inheritdoc cref="IWireMockMiddlewareOptions.FileSystemHandler"/>
public IFileSystemHandler? FileSystemHandler { get; set; }
@@ -107,4 +105,9 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
/// <inheritdoc />
public ActivityTracingOptions? ActivityTracingOptions { get; set; }
/// <inheritdoc />
public ConcurrentDictionary<Guid, WebSocketConnectionRegistry> WebSocketRegistries { get; } = new();
public WebSocketSettings? WebSocketSettings { get; set; }
}