-
Notifications
You must be signed in to change notification settings - Fork 36
/
RequestMatchingMiddleware.cs
113 lines (92 loc) 路 3.83 KB
/
RequestMatchingMiddleware.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
锘縰sing Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
namespace Mockaco
{
internal class RequestMatchingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestMatchingMiddleware> _logger;
public RequestMatchingMiddleware(RequestDelegate next, ILogger<RequestMatchingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(
HttpContext httpContext,
IMockacoContext mockacoContext,
IScriptContext scriptContext,
IMockProvider mockProvider,
ITemplateTransformer templateTransformer,
IEnumerable<IRequestMatcher> requestMatchers,
IMemoryCache cache,
IOptions<MockacoOptions> options
)
{
await LogHttpContext(httpContext);
await AttachRequestToScriptContext(httpContext, mockacoContext, scriptContext);
if (mockacoContext.Errors.Any())
{
return;
}
foreach (var mock in mockProvider.GetMocks())
{
if (await requestMatchers.AllAsync(_ => _.IsMatch(httpContext.Request, mock)))
{
cache.Set($"{nameof(RequestMatchingMiddleware)} {httpContext.Request.Path.Value}",new
{
Route = httpContext.Request.Path.Value,
Timestamp = $"{DateTime.Now.ToString("t")}",
Body = await httpContext.Request.ReadBodyStream()
}, DateTime.Now.AddMinutes(options.Value.MatchedRoutesCacheDuration));
_logger.LogInformation("Incoming request matched {mock}", mock);
await scriptContext.AttachRouteParameters(httpContext.Request, mock);
var template = await templateTransformer.TransformAndSetVariables(mock.RawTemplate, scriptContext);
mockacoContext.Mock = mock;
mockacoContext.TransformedTemplate = template;
await _next(httpContext);
return;
}
else
{
_logger.LogDebug("Incoming request didn't match {mock}", mock);
}
}
_logger.LogInformation("Incoming request didn't match any mock");
mockacoContext.Errors.Add(new Error("Incoming request didn't match any mock"));
}
//TODO Remove redundant code
private async Task AttachRequestToScriptContext(HttpContext httpContext, IMockacoContext mockacoContext, IScriptContext scriptContext)
{
try
{
await scriptContext.AttachRequest(httpContext.Request);
}
catch (Exception ex)
{
mockacoContext.Errors.Add(new Error("An error occurred while reading request", ex));
_logger.LogWarning(ex, "An error occurred while reading request");
return;
}
}
private async Task LogHttpContext(HttpContext httpContext)
{
_logger.LogInformation("Incoming request from {remoteIp}", httpContext.Connection.RemoteIpAddress);
_logger.LogDebug("Headers: {headers}", httpContext.Request.Headers.ToJson());
var body = await httpContext.Request.ReadBodyStream();
if (string.IsNullOrEmpty(body))
{
_logger.LogDebug("Body is not present", body);
}
else
{
_logger.LogDebug("Body: {body}", body);
}
}
}
}