mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-18 15:23:47 +01:00
157 lines
5.6 KiB
C#
157 lines
5.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Threading.Tasks;
|
|
using WireMock.Logging;
|
|
using WireMock.Matchers.Request;
|
|
using System.Linq;
|
|
#if !NETSTANDARD
|
|
using Microsoft.Owin;
|
|
#else
|
|
using Microsoft.AspNetCore.Http;
|
|
#endif
|
|
|
|
namespace WireMock.Owin
|
|
{
|
|
#if !NETSTANDARD
|
|
internal class WireMockMiddleware : OwinMiddleware
|
|
#else
|
|
internal class WireMockMiddleware
|
|
#endif
|
|
{
|
|
private static readonly Task CompletedTask = Task.FromResult(false);
|
|
private readonly WireMockMiddlewareOptions _options;
|
|
|
|
private readonly OwinRequestMapper _requestMapper = new OwinRequestMapper();
|
|
private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();
|
|
|
|
#if !NETSTANDARD
|
|
public WireMockMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)
|
|
{
|
|
_options = options;
|
|
}
|
|
#else
|
|
public WireMockMiddleware(RequestDelegate next, WireMockMiddlewareOptions options)
|
|
{
|
|
_options = options;
|
|
}
|
|
#endif
|
|
|
|
#if !NETSTANDARD
|
|
public override async Task Invoke(IOwinContext ctx)
|
|
#else
|
|
public async Task Invoke(HttpContext ctx)
|
|
#endif
|
|
{
|
|
var request = await _requestMapper.MapAsync(ctx.Request);
|
|
|
|
bool logRequest = false;
|
|
ResponseMessage response = null;
|
|
Mapping targetMapping = null;
|
|
RequestMatchResult requestMatchResult = null;
|
|
try
|
|
{
|
|
var mappings = _options.Mappings
|
|
.Select(m => new
|
|
{
|
|
Mapping = m,
|
|
MatchResult = m.IsRequestHandled(request)
|
|
})
|
|
.ToList();
|
|
|
|
if (_options.AllowPartialMapping)
|
|
{
|
|
var partialMappings = mappings
|
|
.Where(pm => pm.Mapping.IsAdminInterface && pm.MatchResult.IsPerfectMatch || !pm.Mapping.IsAdminInterface)
|
|
.OrderBy(m => m.MatchResult)
|
|
.ThenBy(m => m.Mapping.Priority)
|
|
.ToList();
|
|
|
|
var bestPartialMatch = partialMappings.FirstOrDefault(pm => pm.MatchResult.AverageTotalScore > 0.0);
|
|
|
|
targetMapping = bestPartialMatch?.Mapping;
|
|
requestMatchResult = bestPartialMatch?.MatchResult;
|
|
}
|
|
else
|
|
{
|
|
var perfectMatch = mappings
|
|
.OrderBy(m => m.Mapping.Priority)
|
|
.FirstOrDefault(m => m.MatchResult.IsPerfectMatch);
|
|
|
|
targetMapping = perfectMatch?.Mapping;
|
|
requestMatchResult = perfectMatch?.MatchResult;
|
|
}
|
|
|
|
if (targetMapping == null)
|
|
{
|
|
logRequest = true;
|
|
response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
|
|
return;
|
|
}
|
|
|
|
logRequest = !targetMapping.IsAdminInterface;
|
|
|
|
if (targetMapping.IsAdminInterface && _options.AuthorizationMatcher != null)
|
|
{
|
|
string authorization;
|
|
bool present = request.Headers.TryGetValue("Authorization", out authorization);
|
|
if (!present || _options.AuthorizationMatcher.IsMatch(authorization) < 1.0)
|
|
{
|
|
response = new ResponseMessage { StatusCode = 401 };
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!targetMapping.IsAdminInterface && _options.RequestProcessingDelay > TimeSpan.Zero)
|
|
{
|
|
await Task.Delay(_options.RequestProcessingDelay.Value);
|
|
}
|
|
|
|
response = await targetMapping.ResponseToAsync(request);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
response = new ResponseMessage { StatusCode = 500, Body = ex.ToString() };
|
|
}
|
|
finally
|
|
{
|
|
var log = new LogEntry
|
|
{
|
|
Guid = Guid.NewGuid(),
|
|
RequestMessage = request,
|
|
ResponseMessage = response,
|
|
MappingGuid = targetMapping?.Guid,
|
|
MappingTitle = targetMapping?.Title,
|
|
RequestMatchResult = requestMatchResult
|
|
};
|
|
|
|
LogRequest(log, logRequest);
|
|
|
|
await _responseMapper.MapAsync(response, ctx.Response);
|
|
}
|
|
|
|
await CompletedTask;
|
|
}
|
|
|
|
private void LogRequest(LogEntry entry, bool addRequest)
|
|
{
|
|
lock (((ICollection)_options.LogEntries).SyncRoot)
|
|
{
|
|
if (addRequest)
|
|
{
|
|
_options.LogEntries.Add(entry);
|
|
}
|
|
|
|
if (_options.MaxRequestLogCount != null)
|
|
{
|
|
_options.LogEntries = _options.LogEntries.Skip(_options.LogEntries.Count - _options.MaxRequestLogCount.Value).ToList();
|
|
}
|
|
|
|
if (_options.RequestLogExpirationDuration != null)
|
|
{
|
|
var checkTime = DateTime.Now.AddHours(-_options.RequestLogExpirationDuration.Value);
|
|
_options.LogEntries = _options.LogEntries.Where(le => le.RequestMessage.DateTime > checkTime).ToList();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |