// Copyright © WireMock.Net #if MIMEKIT using System; using MimeKit; using WireMock.Extensions; using WireMock.Matchers; using WireMock.Matchers.Helpers; using WireMock.Models; using WireMock.Util; namespace WireMock.Matchers; /// /// MimePartMatcher /// public class MimePartMatcher : IMatcher { private readonly Func[] _funcs; /// public string Name => nameof(MimePartMatcher); /// /// ContentType Matcher (image/png; name=image.png.) /// public IStringMatcher? ContentTypeMatcher { get; } /// /// ContentDisposition Matcher (attachment; filename=image.png) /// public IStringMatcher? ContentDispositionMatcher { get; } /// /// ContentTransferEncoding Matcher (base64) /// public IStringMatcher? ContentTransferEncodingMatcher { get; } /// /// Content Matcher /// public IMatcher? ContentMatcher { get; } /// public MatchBehaviour MatchBehaviour { get; } /// /// Initializes a new instance of the class. /// public MimePartMatcher( MatchBehaviour matchBehaviour, IStringMatcher? contentTypeMatcher, IStringMatcher? contentDispositionMatcher, IStringMatcher? contentTransferEncodingMatcher, IMatcher? contentMatcher ) { MatchBehaviour = matchBehaviour; ContentTypeMatcher = contentTypeMatcher; ContentDispositionMatcher = contentDispositionMatcher; ContentTransferEncodingMatcher = contentTransferEncodingMatcher; ContentMatcher = contentMatcher; _funcs = [ mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect, mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition.ToString().Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect, mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToString().ToLowerInvariant()) ?? MatchScores.Perfect, MatchOnContent ]; } /// /// Determines whether the specified MimePart is match. /// /// The MimePart. /// A value between 0.0 - 1.0 of the similarity. public MatchResult IsMatch(MimePart mimePart) { var score = MatchScores.Mismatch; Exception? exception = null; try { if (Array.TrueForAll(_funcs, func => func(mimePart).IsPerfect())) { score = MatchScores.Perfect; } } catch (Exception ex) { exception = ex; } return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); } /// public string GetCSharpCodeArguments() { return "NotImplemented"; } private MatchResult MatchOnContent(MimePart mimePart) { if (ContentMatcher == null) { return MatchScores.Perfect; } var bodyParserSettings = new BodyParserSettings { Stream = mimePart.Content.Open(), ContentType = GetContentTypeAsString(mimePart.ContentType), DeserializeJson = true, ContentEncoding = null, // mimePart.ContentType.CharsetEncoding.ToString(), DecompressGZipAndDeflate = true }; var bodyData = BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false).GetAwaiter().GetResult(); return BodyDataMatchScoreCalculator.CalculateMatchScore(bodyData, ContentMatcher); } private static string? GetContentTypeAsString(ContentType? contentType) { return contentType?.ToString().Replace("Content-Type: ", string.Empty); } } #endif