// Copyright © WireMock.Net using System.Linq; using System.Net.Http; using Stef.Validation; using WireMock.Http; using WireMock.Matchers; using WireMock.Serialization; using WireMock.Settings; using WireMock.Util; namespace WireMock.Proxy; internal class ProxyHelper(WireMockServerSettings settings) { private readonly WireMockServerSettings _settings = Guard.NotNull(settings); private readonly ProxyMappingConverter _proxyMappingConverter = new(settings, new GuidUtils(), new DateTimeUtils()); public async Task<(IResponseMessage Message, IMapping? Mapping)> SendAsync( IMapping? mapping, ProxyAndRecordSettings proxyAndRecordSettings, HttpClient client, IRequestMessage requestMessage, string url) { Guard.NotNull(client); Guard.NotNull(requestMessage); Guard.NotNull(url); var originalUri = new Uri(requestMessage.Url); var requiredUri = new Uri(url); // Create HttpRequestMessage var proxyUrl = proxyAndRecordSettings.ReplaceSettings != null ? ProxyUrlTransformer.Transform(_settings, proxyAndRecordSettings.ReplaceSettings, url) : url; var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, proxyUrl); // Call the URL var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false); // Create ResponseMessage bool deserializeJson = !_settings.DisableJsonBodyParsing.GetValueOrDefault(false); bool decompressGzipAndDeflate = !_settings.DisableRequestBodyDecompressing.GetValueOrDefault(false); bool deserializeFormUrlEncoded = !_settings.DisableDeserializeFormUrlEncoded.GetValueOrDefault(false); var responseMessage = await HttpResponseMessageHelper.CreateAsync( httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate, deserializeFormUrlEncoded, _settings.DefaultJsonSerializer ).ConfigureAwait(false); IMapping? newMapping = null; var saveMappingSettings = proxyAndRecordSettings.SaveMappingSettings; bool save = true; if (saveMappingSettings != null) { save &= Check(saveMappingSettings.StatusCodePattern, () => saveMappingSettings.StatusCodePattern != null && HttpStatusRangeParser.IsMatch(saveMappingSettings.StatusCodePattern, responseMessage.StatusCode) ); save &= Check(saveMappingSettings.HttpMethods, () => saveMappingSettings.HttpMethods != null && saveMappingSettings.HttpMethods.Value.Contains(requestMessage.Method, StringComparer.OrdinalIgnoreCase) ); } if (save && (proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile)) { newMapping = _proxyMappingConverter.ToMapping(mapping, proxyAndRecordSettings, requestMessage, responseMessage); } return (responseMessage, newMapping); } private static bool Check(ProxySaveMappingSetting? saveMappingSetting, Func action) where T : notnull { var isMatch = saveMappingSetting is null || action(); var matchBehaviour = saveMappingSetting?.MatchBehaviour ?? MatchBehaviour.AcceptOnMatch; return isMatch == (matchBehaviour == MatchBehaviour.AcceptOnMatch); } }