mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-18 07:13:46 +01:00
merge netstandard into main (#26)
* #23 * #23 "Newtonsoft.Json" Version="10.0.2" * owin * AspNetCore * Fix appveyor build * fix start/stop in untitests
This commit is contained in:
46
src/WireMock.Net.Logic/WireMock.Net.Logic.csproj
Normal file
46
src/WireMock.Net.Logic/WireMock.Net.Logic.csproj
Normal file
@@ -0,0 +1,46 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>WireMock.Net.Logic</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net45;netstandard1.3</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.Logic</AssemblyName>
|
||||
<DebugType>full</DebugType>
|
||||
<ApplicationIcon>../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<Version>1.0.2.0</Version>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<DefineConstants>NETSTANDARD</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="10.4.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.3" />
|
||||
<PackageReference Include="Handlebars.Net" Version="1.8.0" />
|
||||
<PackageReference Include="XPath2" Version="1.0.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="1.1.1" />
|
||||
<!--<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="1.1.1" />-->
|
||||
<PackageReference Include="Handlebars.NetStandard" Version="1.8.1" />
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Tasks" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Thread">
|
||||
<Version>4.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
49
src/WireMock.Net.Middleware/FluentMockServerSettings.cs
Normal file
49
src/WireMock.Net.Middleware/FluentMockServerSettings.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
namespace WireMock.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// WireMockSettings
|
||||
/// </summary>
|
||||
public class WireMockSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the port.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The port.
|
||||
/// </value>
|
||||
public int? Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the use SSL.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The use SSL.
|
||||
/// </value>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public bool? UseSSL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start admin interface.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The start admin interface.
|
||||
/// </value>
|
||||
public bool? StartAdminInterface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the read static mappings.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The read static mappings.
|
||||
/// </value>
|
||||
public bool? ReadStaticMappings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the urls.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The urls.
|
||||
/// </value>
|
||||
public string[] Urls { get; set; }
|
||||
}
|
||||
}
|
||||
60
src/WireMock.Net.Middleware/WireMock.Net.Middleware.csproj
Normal file
60
src/WireMock.Net.Middleware/WireMock.Net.Middleware.csproj
Normal file
@@ -0,0 +1,60 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>WireMock.Net Owin Middleware.</Description>
|
||||
<Version>1.0.0.0</Version>
|
||||
<AssemblyTitle>WireMock.Net</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net45;netstandard1.3</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.Middleware</AssemblyName>
|
||||
<PackageId>WireMock.Net.Middleware</PackageId>
|
||||
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
|
||||
<PackageReleaseNotes>Initial version</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/StefH/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/StefH/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://raw.githubusercontent.com/StefH/WireMock.Net/master/LICENSE</PackageLicenseUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/StefH/WireMock.Net</RepositoryUrl>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<DebugType>full</DebugType>
|
||||
<ApplicationIcon>../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<DefineConstants>NETSTANDARD</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="10.4.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
<!--<PackageReference Include="SimMetrics.Net" Version="1.0.3" />-->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.3" />
|
||||
<PackageReference Include="Handlebars.Net" Version="1.8.0" />
|
||||
<PackageReference Include="XPath2" Version="1.0.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="1.1.1" />
|
||||
<!--<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="1.1.1" />-->
|
||||
<PackageReference Include="Handlebars.NetStandard" Version="1.8.1" />
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Tasks" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Thread">
|
||||
<Version>4.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
144
src/WireMock.Net.Middleware/WireMockMiddleware.cs
Normal file
144
src/WireMock.Net.Middleware/WireMockMiddleware.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers.Request;
|
||||
using System.Linq;
|
||||
#if NETSTANDARD
|
||||
using Microsoft.AspNetCore.Http;
|
||||
#else
|
||||
using Microsoft.Owin;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
#if NETSTANDARD
|
||||
internal class WireMockMiddleware
|
||||
#else
|
||||
internal class WireMockMiddleware : OwinMiddleware
|
||||
#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(RequestDelegate next, WireMockMiddlewareOptions options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
#else
|
||||
public WireMockMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NETSTANDARD
|
||||
public async Task Invoke(HttpContext ctx)
|
||||
#else
|
||||
public override async Task Invoke(IOwinContext ctx)
|
||||
#endif
|
||||
{
|
||||
if (_options.RequestProcessingDelay > TimeSpan.Zero)
|
||||
{
|
||||
await Task.Delay(_options.RequestProcessingDelay.Value);
|
||||
// Thread.Sleep(_options.RequestProcessingDelay.Value);
|
||||
}
|
||||
|
||||
var request = await _requestMapper.MapAsync(ctx.Request);
|
||||
|
||||
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)
|
||||
{
|
||||
response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
response = await targetMapping.ResponseTo(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);
|
||||
|
||||
await _responseMapper.MapAsync(response, ctx.Response);
|
||||
}
|
||||
|
||||
await CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The log request.
|
||||
/// </summary>
|
||||
/// <param name="entry">The request.</param>
|
||||
private void LogRequest(LogEntry entry)
|
||||
{
|
||||
lock (((ICollection)_options.LogEntries).SyncRoot)
|
||||
{
|
||||
_options.LogEntries.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/WireMock.Net.StandAlone.NETCoreApp/Program.cs
Normal file
66
src/WireMock.Net.StandAlone.NETCoreApp/Program.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CommandLineParser.Arguments;
|
||||
using CommandLineParser.Exceptions;
|
||||
using WireMock.Server;
|
||||
|
||||
namespace WireMock.Net.StandAlone.NETCoreApp
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private class Options
|
||||
{
|
||||
[ValueArgument(typeof(string), 'u', "Urls", Description = "URL(s) to listen on.", Optional = true, AllowMultiple = true)]
|
||||
public List<string> Urls { get; set; }
|
||||
|
||||
[SwitchArgument('p', "AllowPartialMapping", true, Description = "Allow Partial Mapping (default set to true).", Optional = true)]
|
||||
public bool AllowPartialMapping { get; set; }
|
||||
|
||||
[SwitchArgument('s', "StartAdminInterface", true, Description = "Start the AdminInterface (default set to true).", Optional = true)]
|
||||
public bool StartAdminInterface { get; set; }
|
||||
|
||||
[SwitchArgument('r', "ReadStaticMappings", true, Description = "Read StaticMappings from ./__admin/mappings (default set to true).", Optional = true)]
|
||||
public bool ReadStaticMappings { get; set; }
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var options = new Options();
|
||||
var parser = new CommandLineParser.CommandLineParser();
|
||||
parser.ExtractArgumentAttributes(options);
|
||||
|
||||
try
|
||||
{
|
||||
parser.ParseCommandLine(args);
|
||||
|
||||
if (!options.Urls.Any())
|
||||
{
|
||||
options.Urls.Add("http://localhost:9090/");
|
||||
}
|
||||
|
||||
var server = FluentMockServer.Start(new FluentMockServerSettings
|
||||
{
|
||||
Urls = options.Urls.ToArray(),
|
||||
StartAdminInterface = options.StartAdminInterface,
|
||||
ReadStaticMappings = options.ReadStaticMappings
|
||||
});
|
||||
|
||||
if (options.AllowPartialMapping)
|
||||
{
|
||||
server.AllowPartialMapping();
|
||||
}
|
||||
|
||||
Console.WriteLine("WireMock.Net server listening at {0}", string.Join(" and ", server.Urls));
|
||||
}
|
||||
catch (CommandLineException e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
parser.ShowUsage();
|
||||
}
|
||||
|
||||
Console.WriteLine("Press any key to stop the server");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineArgumentsParser" Version="3.0.9" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -36,8 +36,11 @@
|
||||
<ApplicationIcon>..\..\WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CommandLineArgumentsParser, Version=3.0.7.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\CommandLineArgumentsParser.3.0.7\lib\net45\CommandLineArgumentsParser.dll</HintPath>
|
||||
<Reference Include="CommandLineArgumentsParser, Version=3.0.9.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\CommandLineArgumentsParser.3.0.9\lib\net45\CommandLineArgumentsParser.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="CommandLineArgumentsParser" version="3.0.7" targetFramework="net452" />
|
||||
<package id="CommandLineArgumentsParser" version="3.0.9" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@@ -1,63 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
|
||||
namespace WireMock.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictionary Extensions
|
||||
/// </summary>
|
||||
public static class DictionaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts IDictionary to an ExpandObject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="dictionary">The dictionary.</param>
|
||||
/// <returns></returns>
|
||||
public static dynamic ToExpandoObject<T>(this IDictionary<string, T> dictionary)
|
||||
{
|
||||
dynamic expando = new ExpandoObject();
|
||||
var expandoDic = (IDictionary<string, object>)expando;
|
||||
|
||||
// go through the items in the dictionary and copy over the key value pairs)
|
||||
foreach (var kvp in dictionary)
|
||||
{
|
||||
// if the value can also be turned into an ExpandoObject, then do it!
|
||||
var value = kvp.Value as IDictionary<string, object>;
|
||||
if (value != null)
|
||||
{
|
||||
var expandoValue = value.ToExpandoObject();
|
||||
expandoDic.Add(kvp.Key, expandoValue);
|
||||
}
|
||||
else if (kvp.Value is ICollection)
|
||||
{
|
||||
// iterate through the collection and convert any strin-object dictionaries
|
||||
// along the way into expando objects
|
||||
var itemList = new List<object>();
|
||||
foreach (var item in (ICollection)kvp.Value)
|
||||
{
|
||||
var objects = item as IDictionary<string, object>;
|
||||
if (objects != null)
|
||||
{
|
||||
var expandoItem = objects.ToExpandoObject();
|
||||
itemList.Add(expandoItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemList.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
expandoDic.Add(kvp.Key, itemList);
|
||||
}
|
||||
else
|
||||
{
|
||||
expandoDic.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return expando;
|
||||
}
|
||||
}
|
||||
}
|
||||
65
src/WireMock.Net/Http/HttpListenerRequestMapper.cs
Normal file
65
src/WireMock.Net/Http/HttpListenerRequestMapper.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.IO;
|
||||
//using System.Linq;
|
||||
//using System.Net;
|
||||
//using System.Text;
|
||||
//#if NET45
|
||||
|
||||
//#else
|
||||
//using System.Net.Http;
|
||||
//#endif
|
||||
|
||||
//namespace WireMock.Http
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// The http listener request mapper.
|
||||
// /// </summary>
|
||||
// public class HttpListenerRequestMapperOld
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// The map.
|
||||
// /// </summary>
|
||||
// /// <param name="listenerRequest">The listener request.</param>
|
||||
// /// <returns>The <see cref="RequestMessage"/>.</returns>
|
||||
// public RequestMessage MapAsync(HttpListenerRequest listenerRequest)
|
||||
// {
|
||||
// Uri url = listenerRequest.Url;
|
||||
// string verb = listenerRequest.HttpMethod;
|
||||
// byte[] body = GetRequestBody(listenerRequest);
|
||||
// Encoding bodyEncoding = body != null ? listenerRequest.ContentEncoding : null;
|
||||
// string bodyAsString = bodyEncoding?.GetString(body);
|
||||
// var listenerHeaders = listenerRequest.Headers;
|
||||
// var headers = listenerHeaders.AllKeys.ToDictionary(k => k, k => listenerHeaders[k]);
|
||||
// var cookies = new Dictionary<string, string>();
|
||||
|
||||
// foreach (Cookie cookie in listenerRequest.Cookies)
|
||||
// cookies.Add(cookie.Name, cookie.Value);
|
||||
|
||||
// return new RequestMessage(url, verb, body, bodyAsString, bodyEncoding, headers, cookies) { DateTime = DateTime.Now };
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// The get request body.
|
||||
// /// </summary>
|
||||
// /// <param name="request">The request.</param>
|
||||
// /// <returns>The <see cref="string"/>.</returns>
|
||||
// private byte[] GetRequestBody(HttpListenerRequest request)
|
||||
// {
|
||||
// if (!request.HasEntityBody)
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// using (var bodyStream = request.InputStream)
|
||||
// {
|
||||
// using (var memoryStream = new MemoryStream())
|
||||
// {
|
||||
// bodyStream.CopyTo(memoryStream);
|
||||
|
||||
// return memoryStream.ToArray();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
44
src/WireMock.Net/Http/HttpListenerResponseMapper.cs
Normal file
44
src/WireMock.Net/Http/HttpListenerResponseMapper.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
//using System.Linq;
|
||||
//using System.Net;
|
||||
//using System.Text;
|
||||
//#if NET45
|
||||
|
||||
//#else
|
||||
//using System.Net.Http;
|
||||
//#endif
|
||||
|
||||
//namespace WireMock.Http
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// The http listener response mapper.
|
||||
// /// </summary>
|
||||
// public class HttpListenerResponseMapperOld
|
||||
// {
|
||||
// private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
||||
|
||||
// /// <summary>
|
||||
// /// The map.
|
||||
// /// </summary>
|
||||
// /// <param name="responseMessage">
|
||||
// /// The response.
|
||||
// /// </param>
|
||||
// /// <param name="listenerResponse">The listenerResponse.</param>
|
||||
// public void MapAsync(ResponseMessage responseMessage, HttpListenerResponse listenerResponse)
|
||||
// {
|
||||
// listenerResponse.StatusCode = responseMessage.StatusCode;
|
||||
|
||||
// responseMessage.Headers.ToList().ForEach(pair => listenerResponse.AddHeader(pair.Key, pair.Value));
|
||||
|
||||
// if (responseMessage.Body == null)
|
||||
// return;
|
||||
|
||||
// var encoding = responseMessage.BodyEncoding ?? _utf8NoBom;
|
||||
// byte[] buffer = encoding.GetBytes(responseMessage.Body);
|
||||
|
||||
// listenerResponse.ContentEncoding = encoding;
|
||||
// listenerResponse.ContentLength64 = buffer.Length;
|
||||
// listenerResponse.OutputStream.Write(buffer, 0, buffer.Length);
|
||||
// listenerResponse.OutputStream.Flush();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,113 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//#if NET45
|
||||
//using System.Net;
|
||||
//#else
|
||||
//using System.Net.Http;
|
||||
//#endif
|
||||
//using System.Threading;
|
||||
//using System.Threading.Tasks;
|
||||
//using JetBrains.Annotations;
|
||||
//using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// The tiny http server.
|
||||
/// </summary>
|
||||
public class TinyHttpServer
|
||||
{
|
||||
private readonly Action<HttpListenerContext, CancellationToken> _httpHandler;
|
||||
//namespace WireMock.Http
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// The tiny http server.
|
||||
// /// </summary>
|
||||
// public class TinyHttpServerOld
|
||||
// {
|
||||
// private readonly Action<HttpListenerContext, CancellationToken> _httpHandler;
|
||||
|
||||
private readonly HttpListener _listener;
|
||||
// private readonly HttpListener _listener;
|
||||
|
||||
private readonly CancellationTokenSource _cts;
|
||||
// private readonly CancellationTokenSource _cts;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this server is started.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this server is started; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsStarted { get; private set; }
|
||||
// /// <summary>
|
||||
// /// Gets a value indicating whether this server is started.
|
||||
// /// </summary>
|
||||
// /// <value>
|
||||
// /// <c>true</c> if this server is started; otherwise, <c>false</c>.
|
||||
// /// </value>
|
||||
// public bool IsStarted { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The urls.
|
||||
/// </value>
|
||||
[PublicAPI]
|
||||
public List<Uri> Urls { get; } = new List<Uri>();
|
||||
// /// <summary>
|
||||
// /// Gets the url.
|
||||
// /// </summary>
|
||||
// /// <value>
|
||||
// /// The urls.
|
||||
// /// </value>
|
||||
// [PublicAPI]
|
||||
// public List<Uri> Urls { get; } = new List<Uri>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ports.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The ports.
|
||||
/// </value>
|
||||
[PublicAPI]
|
||||
public List<int> Ports { get; } = new List<int>();
|
||||
// /// <summary>
|
||||
// /// Gets the ports.
|
||||
// /// </summary>
|
||||
// /// <value>
|
||||
// /// The ports.
|
||||
// /// </value>
|
||||
// [PublicAPI]
|
||||
// public List<int> Ports { get; } = new List<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TinyHttpServer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="uriPrefixes">The uriPrefixes.</param>
|
||||
/// <param name="httpHandler">The http handler.</param>
|
||||
public TinyHttpServer([NotNull] Action<HttpListenerContext, CancellationToken> httpHandler, [NotNull] params string[] uriPrefixes)
|
||||
{
|
||||
Check.NotNull(httpHandler, nameof(httpHandler));
|
||||
Check.NotEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||
// /// <summary>
|
||||
// /// Initializes a new instance of the <see cref="TinyHttpServer"/> class.
|
||||
// /// </summary>
|
||||
// /// <param name="uriPrefixes">The uriPrefixes.</param>
|
||||
// /// <param name="httpHandler">The http handler.</param>
|
||||
// public TinyHttpServerOld([NotNull] Action<HttpListenerContext, CancellationToken> httpHandler, [NotNull] params string[] uriPrefixes)
|
||||
// {
|
||||
// Check.NotNull(httpHandler, nameof(httpHandler));
|
||||
// Check.NotEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||
|
||||
_cts = new CancellationTokenSource();
|
||||
// _cts = new CancellationTokenSource();
|
||||
|
||||
_httpHandler = httpHandler;
|
||||
// _httpHandler = httpHandler;
|
||||
|
||||
// Create a listener.
|
||||
_listener = new HttpListener();
|
||||
foreach (string uriPrefix in uriPrefixes)
|
||||
{
|
||||
var uri = new Uri(uriPrefix);
|
||||
Urls.Add(uri);
|
||||
Ports.Add(uri.Port);
|
||||
// // Create a listener.
|
||||
// _listener = new HttpListener();
|
||||
// foreach (string uriPrefix in uriPrefixes)
|
||||
// {
|
||||
// var uri = new Uri(uriPrefix);
|
||||
// Urls.Add(uri);
|
||||
// Ports.Add(uri.Port);
|
||||
|
||||
_listener.Prefixes.Add(uriPrefix);
|
||||
}
|
||||
}
|
||||
// _listener.Prefixes.Add(uriPrefix);
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Start the server.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public void Start()
|
||||
{
|
||||
_listener.Start();
|
||||
// /// <summary>
|
||||
// /// Start the server.
|
||||
// /// </summary>
|
||||
// [PublicAPI]
|
||||
// public void Start()
|
||||
// {
|
||||
// _listener.Start();
|
||||
|
||||
IsStarted = true;
|
||||
// IsStarted = true;
|
||||
|
||||
Task.Run(
|
||||
async () =>
|
||||
{
|
||||
//using (_listener)
|
||||
{
|
||||
while (!_cts.Token.IsCancellationRequested)
|
||||
{
|
||||
HttpListenerContext context = await _listener.GetContextAsync();
|
||||
_httpHandler(context, _cts.Token);
|
||||
}
|
||||
// Task.Run(
|
||||
// async () =>
|
||||
// {
|
||||
// //using (_listener)
|
||||
// {
|
||||
// while (!_cts.Token.IsCancellationRequested)
|
||||
// {
|
||||
// HttpListenerContext context = await _listener.GetContextAsync();
|
||||
// _httpHandler(context, _cts.Token);
|
||||
// }
|
||||
|
||||
_listener.Stop();
|
||||
IsStarted = false;
|
||||
}
|
||||
},
|
||||
_cts.Token);
|
||||
}
|
||||
// _listener.Stop();
|
||||
// IsStarted = false;
|
||||
// }
|
||||
// },
|
||||
// _cts.Token);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Stop the server.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public void Stop()
|
||||
{
|
||||
_listener?.Stop();
|
||||
// /// <summary>
|
||||
// /// Stop the server.
|
||||
// /// </summary>
|
||||
// [PublicAPI]
|
||||
// public void Stop()
|
||||
// {
|
||||
// _listener?.Stop();
|
||||
|
||||
_cts.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
// _cts.Cancel();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace WireMock
|
||||
{
|
||||
/// <summary>
|
||||
/// The http listener request mapper.
|
||||
/// </summary>
|
||||
public class HttpListenerRequestMapper
|
||||
{
|
||||
/// <summary>
|
||||
/// The map.
|
||||
/// </summary>
|
||||
/// <param name="listenerRequest">The listener request.</param>
|
||||
/// <returns>The <see cref="RequestMessage"/>.</returns>
|
||||
public RequestMessage Map(HttpListenerRequest listenerRequest)
|
||||
{
|
||||
Uri url = listenerRequest.Url;
|
||||
string verb = listenerRequest.HttpMethod;
|
||||
byte[] body = GetRequestBody(listenerRequest);
|
||||
Encoding bodyEncoding = body != null ? listenerRequest.ContentEncoding : null;
|
||||
string bodyAsString = bodyEncoding?.GetString(body);
|
||||
var listenerHeaders = listenerRequest.Headers;
|
||||
var headers = listenerHeaders.AllKeys.ToDictionary(k => k, k => listenerHeaders[k]);
|
||||
var cookies = new Dictionary<string, string>();
|
||||
|
||||
foreach (Cookie cookie in listenerRequest.Cookies)
|
||||
cookies.Add(cookie.Name, cookie.Value);
|
||||
|
||||
return new RequestMessage(url, verb, body, bodyAsString, bodyEncoding, headers, cookies) { DateTime = DateTime.Now };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The get request body.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>The <see cref="string"/>.</returns>
|
||||
private byte[] GetRequestBody(HttpListenerRequest request)
|
||||
{
|
||||
if (!request.HasEntityBody)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var bodyStream = request.InputStream)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
bodyStream.CopyTo(memoryStream);
|
||||
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace WireMock
|
||||
{
|
||||
/// <summary>
|
||||
/// The http listener response mapper.
|
||||
/// </summary>
|
||||
public class HttpListenerResponseMapper
|
||||
{
|
||||
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
||||
|
||||
/// <summary>
|
||||
/// The map.
|
||||
/// </summary>
|
||||
/// <param name="responseMessage">
|
||||
/// The response.
|
||||
/// </param>
|
||||
/// <param name="listenerResponse">The listenerResponse.</param>
|
||||
public void Map(ResponseMessage responseMessage, HttpListenerResponse listenerResponse)
|
||||
{
|
||||
listenerResponse.StatusCode = responseMessage.StatusCode;
|
||||
|
||||
responseMessage.Headers.ToList().ForEach(pair => listenerResponse.AddHeader(pair.Key, pair.Value));
|
||||
|
||||
if (responseMessage.Body == null)
|
||||
return;
|
||||
|
||||
var encoding = responseMessage.BodyEncoding ?? _utf8NoBom;
|
||||
byte[] buffer = encoding.GetBytes(responseMessage.Body);
|
||||
|
||||
listenerResponse.ContentEncoding = encoding;
|
||||
listenerResponse.ContentLength64 = buffer.Length;
|
||||
listenerResponse.OutputStream.Write(buffer, 0, buffer.Length);
|
||||
listenerResponse.OutputStream.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ using System.Linq;
|
||||
using System.Xml;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
#if NET45
|
||||
using Wmhelp.XPath2;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Matchers
|
||||
{
|
||||
@@ -39,8 +41,11 @@ namespace WireMock.Matchers
|
||||
try
|
||||
{
|
||||
var nav = new XmlDocument { InnerXml = input }.CreateNavigator();
|
||||
|
||||
#if NET45
|
||||
return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})"))));
|
||||
#else
|
||||
return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})"))));
|
||||
#endif
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
100
src/WireMock.Net/Owin/AspNetCoreSelfHost.cs
Normal file
100
src/WireMock.Net/Owin/AspNetCoreSelfHost.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
#if !NET45
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal class AspNetCoreSelfHost : IOwinSelfHost
|
||||
{
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private readonly WireMockMiddlewareOptions _options;
|
||||
private readonly string[] _uriPrefixes;
|
||||
|
||||
public bool IsStarted { get; private set; }
|
||||
|
||||
public List<Uri> Urls { get; } = new List<Uri>();
|
||||
|
||||
public List<int> Ports { get; } = new List<int>();
|
||||
|
||||
public AspNetCoreSelfHost([NotNull] WireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
||||
{
|
||||
Check.NotNull(options, nameof(options));
|
||||
Check.NotEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||
|
||||
foreach (string uriPrefix in uriPrefixes)
|
||||
{
|
||||
var uri = new Uri(uriPrefix);
|
||||
Urls.Add(uri);
|
||||
Ports.Add(uri.Port);
|
||||
}
|
||||
|
||||
_options = options;
|
||||
_uriPrefixes = uriPrefixes;
|
||||
}
|
||||
|
||||
public Task StartAsync()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.ConfigureLogging(factory => factory.AddConsole(LogLevel.None))
|
||||
.Configure(appBuilder =>
|
||||
{
|
||||
// appBuilder.UseExceptionHandler(builder => )
|
||||
appBuilder.UseMiddleware<WireMockMiddleware>(_options);
|
||||
})
|
||||
.UseKestrel()
|
||||
.UseUrls(_uriPrefixes)
|
||||
.Build();
|
||||
|
||||
host.Run(_cts.Token);
|
||||
|
||||
IsStarted = true;
|
||||
}, _cts.Token);
|
||||
}
|
||||
|
||||
public Task StopAsync()
|
||||
{
|
||||
_cts.Cancel();
|
||||
|
||||
IsStarted = false;
|
||||
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Startup
|
||||
{
|
||||
public Startup(IHostingEnvironment env)
|
||||
{
|
||||
//var builder = new ConfigurationBuilder()
|
||||
// .SetBasePath(env.ContentRootPath)
|
||||
// .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||
// .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
||||
// .AddEnvironmentVariables();
|
||||
//Configuration = builder.Build();
|
||||
}
|
||||
|
||||
// public IConfigurationRoot Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
app.UseMiddleware<WireMockMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
37
src/WireMock.Net/Owin/IOwinSelfHost.cs
Normal file
37
src/WireMock.Net/Owin/IOwinSelfHost.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
interface IOwinSelfHost
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this server is started.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this server is started; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsStarted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The urls.
|
||||
/// </value>
|
||||
List<Uri> Urls { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ports.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The ports.
|
||||
/// </value>
|
||||
List<int> Ports { get; }
|
||||
|
||||
Task StartAsync();
|
||||
|
||||
Task StopAsync();
|
||||
}
|
||||
}
|
||||
70
src/WireMock.Net/Owin/OwinRequestMapper.cs
Normal file
70
src/WireMock.Net/Owin/OwinRequestMapper.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
#if NET45
|
||||
using Microsoft.Owin;
|
||||
#else
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
/// <summary>
|
||||
/// OwinRequestMapper
|
||||
/// </summary>
|
||||
public class OwinRequestMapper
|
||||
{
|
||||
/// <summary>
|
||||
/// MapAsync IOwinRequest to RequestMessage
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<RequestMessage> MapAsync(
|
||||
#if NET45
|
||||
IOwinRequest request
|
||||
#else
|
||||
HttpRequest request
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if NET45
|
||||
Uri url = request.Uri;
|
||||
#else
|
||||
Uri url = new Uri(request.GetEncodedUrl());
|
||||
#endif
|
||||
string verb = request.Method;
|
||||
|
||||
string bodyAsString = null;
|
||||
byte[] body = null;
|
||||
Encoding bodyEncoding = null;
|
||||
if (request.Body != null)
|
||||
{
|
||||
using (var streamReader = new StreamReader(request.Body))
|
||||
{
|
||||
bodyAsString = await streamReader.ReadToEndAsync();
|
||||
bodyEncoding = streamReader.CurrentEncoding;
|
||||
}
|
||||
|
||||
body = bodyEncoding.GetBytes(bodyAsString);
|
||||
}
|
||||
|
||||
var listenerHeaders = request.Headers;
|
||||
|
||||
var headers = new Dictionary<string, string>();
|
||||
foreach (var header in listenerHeaders)
|
||||
headers.Add(header.Key, header.Value.FirstOrDefault());
|
||||
|
||||
var cookies = new Dictionary<string, string>();
|
||||
|
||||
foreach (var cookie in request.Cookies)
|
||||
cookies.Add(cookie.Key, cookie.Value);
|
||||
|
||||
return new RequestMessage(url, verb, body, bodyAsString, bodyEncoding, headers, cookies) { DateTime = DateTime.Now };
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/WireMock.Net/Owin/OwinResponseMapper.cs
Normal file
47
src/WireMock.Net/Owin/OwinResponseMapper.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
#if NET45
|
||||
using Microsoft.Owin;
|
||||
#else
|
||||
using Microsoft.AspNetCore.Http;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
/// <summary>
|
||||
/// OwinResponseMapper
|
||||
/// </summary>
|
||||
public class OwinResponseMapper
|
||||
{
|
||||
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
|
||||
|
||||
/// <summary>
|
||||
/// MapAsync ResponseMessage to OwinResponse
|
||||
/// </summary>
|
||||
/// <param name="responseMessage"></param>
|
||||
/// <param name="response"></param>
|
||||
public async Task MapAsync(ResponseMessage responseMessage
|
||||
#if NET45
|
||||
, IOwinResponse response
|
||||
#else
|
||||
, HttpResponse response
|
||||
#endif
|
||||
)
|
||||
{
|
||||
response.StatusCode = responseMessage.StatusCode;
|
||||
|
||||
responseMessage.Headers.ToList().ForEach(pair => response.Headers.Append(pair.Key, pair.Value));
|
||||
|
||||
if (responseMessage.Body == null)
|
||||
return;
|
||||
|
||||
Encoding encoding = responseMessage.BodyEncoding ?? _utf8NoBom;
|
||||
using (var writer = new StreamWriter(response.Body, encoding))
|
||||
{
|
||||
await writer.WriteAsync(responseMessage.Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
src/WireMock.Net/Owin/OwinSelfHost.cs
Normal file
116
src/WireMock.Net/Owin/OwinSelfHost.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
#if NET45
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
using Owin;
|
||||
using Microsoft.Owin.Hosting;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal class OwinSelfHost : IOwinSelfHost
|
||||
{
|
||||
private readonly WireMockMiddlewareOptions _options;
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private System.Threading.Thread _internalThread;
|
||||
|
||||
public OwinSelfHost([NotNull] WireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
||||
{
|
||||
Check.NotNull(options, nameof(options));
|
||||
Check.NotEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||
|
||||
foreach (string uriPrefix in uriPrefixes)
|
||||
{
|
||||
var uri = new Uri(uriPrefix);
|
||||
Urls.Add(uri);
|
||||
Ports.Add(uri.Port);
|
||||
}
|
||||
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public bool IsStarted { get; private set; }
|
||||
|
||||
public List<Uri> Urls { get; } = new List<Uri>();
|
||||
|
||||
public List<int> Ports { get; } = new List<int>();
|
||||
|
||||
[PublicAPI]
|
||||
public Task StartAsync()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
StartServers();
|
||||
}, _cts.Token);
|
||||
|
||||
//if (_internalThread != null)
|
||||
// throw new InvalidOperationException("Cannot start a multiple threads.");
|
||||
|
||||
//_internalThread = new Thread(ThreadWorkInternal);
|
||||
//_internalThread.Start();
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public Task StopAsync()
|
||||
{
|
||||
_cts.Cancel();
|
||||
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
var timer = new System.Timers.Timer(999);
|
||||
timer.Elapsed += (sender, e) =>
|
||||
{
|
||||
if (_internalThread == null)
|
||||
{
|
||||
timer.Stop();
|
||||
tcs.SetResult(true);
|
||||
}
|
||||
};
|
||||
timer.Start();
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private void ThreadWorkInternal()
|
||||
{
|
||||
try
|
||||
{
|
||||
StartServers();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_internalThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void StartServers()
|
||||
{
|
||||
Action<IAppBuilder> startup = app =>
|
||||
{
|
||||
app.Use<WireMockMiddleware>(_options);
|
||||
};
|
||||
|
||||
var servers = new List<IDisposable>();
|
||||
foreach (var url in Urls)
|
||||
{
|
||||
servers.Add(WebApp.Start(url.ToString(), startup));
|
||||
}
|
||||
|
||||
IsStarted = true;
|
||||
|
||||
while (!_cts.IsCancellationRequested)
|
||||
Thread.Sleep(1000);
|
||||
|
||||
IsStarted = false;
|
||||
|
||||
foreach (var server in servers)
|
||||
server.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
144
src/WireMock.Net/Owin/WireMockMiddleware.cs
Normal file
144
src/WireMock.Net/Owin/WireMockMiddleware.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers.Request;
|
||||
using System.Linq;
|
||||
#if NET45
|
||||
using Microsoft.Owin;
|
||||
#else
|
||||
using Microsoft.AspNetCore.Http;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
#if NET45
|
||||
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 NET45
|
||||
public WireMockMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
#else
|
||||
public WireMockMiddleware(RequestDelegate next, WireMockMiddlewareOptions options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NET45
|
||||
public override async Task Invoke(IOwinContext ctx)
|
||||
#else
|
||||
public async Task Invoke(HttpContext ctx)
|
||||
#endif
|
||||
{
|
||||
if (_options.RequestProcessingDelay > TimeSpan.Zero)
|
||||
{
|
||||
await Task.Delay(_options.RequestProcessingDelay.Value);
|
||||
// Thread.Sleep(_options.RequestProcessingDelay.Value);
|
||||
}
|
||||
|
||||
var request = await _requestMapper.MapAsync(ctx.Request);
|
||||
|
||||
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)
|
||||
{
|
||||
response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
response = await targetMapping.ResponseTo(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);
|
||||
|
||||
await _responseMapper.MapAsync(response, ctx.Response);
|
||||
}
|
||||
|
||||
await CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The log request.
|
||||
/// </summary>
|
||||
/// <param name="entry">The request.</param>
|
||||
private void LogRequest(LogEntry entry)
|
||||
{
|
||||
lock (((ICollection)_options.LogEntries).SyncRoot)
|
||||
{
|
||||
_options.LogEntries.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
Normal file
26
src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal class WireMockMiddlewareOptions
|
||||
{
|
||||
public TimeSpan? RequestProcessingDelay { get; set; }
|
||||
|
||||
public IMatcher AuthorizationMatcher { get; set; }
|
||||
|
||||
public bool AllowPartialMapping { get; set; }
|
||||
|
||||
public IList<Mapping> Mappings { get; set; }
|
||||
|
||||
public IList<LogEntry> LogEntries { get; set; }
|
||||
|
||||
public WireMockMiddlewareOptions()
|
||||
{
|
||||
Mappings = new List<Mapping>();
|
||||
LogEntries = new List<LogEntry>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace WireMock
|
||||
/// <summary>
|
||||
/// Gets the url.
|
||||
/// </summary>
|
||||
public string Url { get; private set; }
|
||||
public string Url { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DateTime.
|
||||
|
||||
@@ -122,8 +122,8 @@ namespace WireMock.Server
|
||||
{
|
||||
var model = new SettingsModel
|
||||
{
|
||||
AllowPartialMapping = _allowPartialMapping,
|
||||
GlobalProcessingDelay = _requestProcessingDelay?.Milliseconds
|
||||
AllowPartialMapping = _options.AllowPartialMapping,
|
||||
GlobalProcessingDelay = _options.RequestProcessingDelay?.Milliseconds
|
||||
};
|
||||
|
||||
return ToJson(model);
|
||||
@@ -134,10 +134,10 @@ namespace WireMock.Server
|
||||
var settings = JsonConvert.DeserializeObject<SettingsModel>(requestMessage.Body);
|
||||
|
||||
if (settings.AllowPartialMapping != null)
|
||||
_allowPartialMapping = settings.AllowPartialMapping.Value;
|
||||
_options.AllowPartialMapping = settings.AllowPartialMapping.Value;
|
||||
|
||||
if (settings.GlobalProcessingDelay != null)
|
||||
_requestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
|
||||
_options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
|
||||
|
||||
return new ResponseMessage { Body = "Settings updated" };
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Http;
|
||||
@@ -13,7 +13,7 @@ using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.Validation;
|
||||
using System.Threading;
|
||||
using WireMock.Owin;
|
||||
|
||||
namespace WireMock.Server
|
||||
{
|
||||
@@ -22,23 +22,11 @@ namespace WireMock.Server
|
||||
/// </summary>
|
||||
public partial class FluentMockServer : IDisposable
|
||||
{
|
||||
private readonly TinyHttpServer _httpServer;
|
||||
|
||||
private IList<Mapping> _mappings = new List<Mapping>();
|
||||
|
||||
private readonly IList<LogEntry> _logEntries = new List<LogEntry>();
|
||||
|
||||
private readonly HttpListenerRequestMapper _requestMapper = new HttpListenerRequestMapper();
|
||||
|
||||
private readonly HttpListenerResponseMapper _responseMapper = new HttpListenerResponseMapper();
|
||||
private readonly IOwinSelfHost _httpServer;
|
||||
|
||||
private readonly object _syncRoot = new object();
|
||||
|
||||
private TimeSpan? _requestProcessingDelay;
|
||||
|
||||
private bool _allowPartialMapping;
|
||||
|
||||
private IMatcher _authorizationMatcher;
|
||||
private readonly WireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ports.
|
||||
@@ -63,9 +51,9 @@ namespace WireMock.Server
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (((ICollection)_logEntries).SyncRoot)
|
||||
lock (((ICollection)_options.LogEntries).SyncRoot)
|
||||
{
|
||||
return new ReadOnlyCollection<LogEntry>(_logEntries);
|
||||
return new ReadOnlyCollection<LogEntry>(_options.LogEntries);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,11 +66,11 @@ namespace WireMock.Server
|
||||
[PublicAPI]
|
||||
public IEnumerable<LogEntry> FindLogEntries([NotNull] params IRequestMatcher[] matchers)
|
||||
{
|
||||
lock (((ICollection)_logEntries).SyncRoot)
|
||||
lock (((ICollection)_options.LogEntries).SyncRoot)
|
||||
{
|
||||
var results = new Dictionary<LogEntry, RequestMatchResult>();
|
||||
|
||||
foreach (var log in _logEntries)
|
||||
foreach (var log in _options.LogEntries)
|
||||
{
|
||||
var requestMatchResult = new RequestMatchResult();
|
||||
foreach (var matcher in matchers)
|
||||
@@ -106,9 +94,9 @@ namespace WireMock.Server
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (((ICollection)_mappings).SyncRoot)
|
||||
lock (((ICollection)_options.Mappings).SyncRoot)
|
||||
{
|
||||
return new ReadOnlyCollection<Mapping>(_mappings);
|
||||
return new ReadOnlyCollection<Mapping>(_options.Mappings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,10 +210,14 @@ namespace WireMock.Server
|
||||
Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
|
||||
}
|
||||
|
||||
_httpServer = new TinyHttpServer(HandleRequestAsync, Urls);
|
||||
#if NET45
|
||||
_httpServer = new OwinSelfHost(_options, Urls);
|
||||
#else
|
||||
_httpServer = new AspNetCoreSelfHost(_options, Urls);
|
||||
#endif
|
||||
Ports = _httpServer.Ports;
|
||||
|
||||
_httpServer.Start();
|
||||
_httpServer.StartAsync();
|
||||
|
||||
if (settings.StartAdminInterface == true)
|
||||
{
|
||||
@@ -256,7 +248,7 @@ namespace WireMock.Server
|
||||
[PublicAPI]
|
||||
public void Stop()
|
||||
{
|
||||
_httpServer?.Stop();
|
||||
_httpServer?.StopAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -266,7 +258,7 @@ namespace WireMock.Server
|
||||
{
|
||||
if (_httpServer != null && _httpServer.IsStarted)
|
||||
{
|
||||
_httpServer.Stop();
|
||||
_httpServer.StopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,9 +279,9 @@ namespace WireMock.Server
|
||||
[PublicAPI]
|
||||
public void ResetLogEntries()
|
||||
{
|
||||
lock (((ICollection)_logEntries).SyncRoot)
|
||||
lock (((ICollection)_options.LogEntries).SyncRoot)
|
||||
{
|
||||
_logEntries.Clear();
|
||||
_options.LogEntries.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,13 +292,13 @@ namespace WireMock.Server
|
||||
[PublicAPI]
|
||||
public bool DeleteLogEntry(Guid guid)
|
||||
{
|
||||
lock (((ICollection)_logEntries).SyncRoot)
|
||||
lock (((ICollection)_options.LogEntries).SyncRoot)
|
||||
{
|
||||
// Check a logentry exists with the same GUID, if so, remove it.
|
||||
var existing = _logEntries.FirstOrDefault(m => m.Guid == guid);
|
||||
var existing = _options.LogEntries.FirstOrDefault(m => m.Guid == guid);
|
||||
if (existing != null)
|
||||
{
|
||||
_logEntries.Remove(existing);
|
||||
_options.LogEntries.Remove(existing);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -320,9 +312,9 @@ namespace WireMock.Server
|
||||
[PublicAPI]
|
||||
public void ResetMappings()
|
||||
{
|
||||
lock (((ICollection)_mappings).SyncRoot)
|
||||
lock (((ICollection)_options.Mappings).SyncRoot)
|
||||
{
|
||||
_mappings = _mappings.Where(m => m.Provider is DynamicResponseProvider).ToList();
|
||||
_options.Mappings = _options.Mappings.Where(m => m.Provider is DynamicResponseProvider).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,13 +325,13 @@ namespace WireMock.Server
|
||||
[PublicAPI]
|
||||
public bool DeleteMapping(Guid guid)
|
||||
{
|
||||
lock (((ICollection)_mappings).SyncRoot)
|
||||
lock (((ICollection)_options.Mappings).SyncRoot)
|
||||
{
|
||||
// Check a mapping exists with the same GUID, if so, remove it.
|
||||
var existingMapping = _mappings.FirstOrDefault(m => m.Guid == guid);
|
||||
var existingMapping = _options.Mappings.FirstOrDefault(m => m.Guid == guid);
|
||||
if (existingMapping != null)
|
||||
{
|
||||
_mappings.Remove(existingMapping);
|
||||
_options.Mappings.Remove(existingMapping);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -358,7 +350,7 @@ namespace WireMock.Server
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_requestProcessingDelay = delay;
|
||||
_options.RequestProcessingDelay = delay;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,7 +362,7 @@ namespace WireMock.Server
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_allowPartialMapping = true;
|
||||
_options.AllowPartialMapping = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +378,7 @@ namespace WireMock.Server
|
||||
Check.NotNull(password, nameof(password));
|
||||
|
||||
string authorization = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
|
||||
_authorizationMatcher = new RegexMatcher("^(?i)BASIC " + authorization + "$");
|
||||
_options.AuthorizationMatcher = new RegexMatcher("^(?i)BASIC " + authorization + "$");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -408,119 +400,99 @@ namespace WireMock.Server
|
||||
/// </param>
|
||||
private void RegisterMapping(Mapping mapping)
|
||||
{
|
||||
lock (((ICollection)_mappings).SyncRoot)
|
||||
lock (((ICollection)_options.Mappings).SyncRoot)
|
||||
{
|
||||
// Check a mapping exists with the same GUID, if so, remove it first.
|
||||
DeleteMapping(mapping.Guid);
|
||||
|
||||
_mappings.Add(mapping);
|
||||
_options.Mappings.Add(mapping);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The log request.
|
||||
/// </summary>
|
||||
/// <param name="entry">The request.</param>
|
||||
private void LogRequest(LogEntry entry)
|
||||
{
|
||||
lock (((ICollection)_logEntries).SyncRoot)
|
||||
{
|
||||
_logEntries.Add(entry);
|
||||
}
|
||||
}
|
||||
//private async void HandleRequestOld(IOwinContext ctx)
|
||||
//{
|
||||
// if (_requestProcessingDelay > TimeSpan.Zero)
|
||||
// {
|
||||
// lock (_syncRoot)
|
||||
// {
|
||||
// Task.Delay(_requestProcessingDelay.Value).Wait();
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// The handle request.
|
||||
/// </summary>
|
||||
/// <param name="ctx">The HttpListenerContext.</param>
|
||||
/// <param name="cancel">The CancellationToken.</param>
|
||||
private async void HandleRequestAsync(HttpListenerContext ctx, CancellationToken cancel)
|
||||
{
|
||||
if (cancel.IsCancellationRequested)
|
||||
return;
|
||||
// var request = _requestMapper.MapAsync(ctx.Request);
|
||||
|
||||
if (_requestProcessingDelay > TimeSpan.Zero)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
Task.Delay(_requestProcessingDelay.Value, cancel).Wait(cancel);
|
||||
}
|
||||
}
|
||||
// ResponseMessage response = null;
|
||||
// Mapping targetMapping = null;
|
||||
// RequestMatchResult requestMatchResult = null;
|
||||
// try
|
||||
// {
|
||||
// var mappings = _mappings
|
||||
// .Select(m => new { Mapping = m, MatchResult = m.IsRequestHandled(request) })
|
||||
// .ToList();
|
||||
|
||||
var request = _requestMapper.Map(ctx.Request);
|
||||
// if (_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();
|
||||
|
||||
ResponseMessage response = null;
|
||||
Mapping targetMapping = null;
|
||||
RequestMatchResult requestMatchResult = null;
|
||||
try
|
||||
{
|
||||
var mappings = _mappings
|
||||
.Select(m => new { Mapping = m, MatchResult = m.IsRequestHandled(request) })
|
||||
.ToList();
|
||||
// var bestPartialMatch = partialMappings.FirstOrDefault(pm => pm.MatchResult.AverageTotalScore > 0.0);
|
||||
|
||||
if (_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();
|
||||
// targetMapping = bestPartialMatch?.Mapping;
|
||||
// requestMatchResult = bestPartialMatch?.MatchResult;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var perfectMatch = mappings
|
||||
// .OrderBy(m => m.Mapping.Priority)
|
||||
// .FirstOrDefault(m => m.MatchResult.IsPerfectMatch);
|
||||
|
||||
var bestPartialMatch = partialMappings.FirstOrDefault(pm => pm.MatchResult.AverageTotalScore > 0.0);
|
||||
// targetMapping = perfectMatch?.Mapping;
|
||||
// requestMatchResult = perfectMatch?.MatchResult;
|
||||
// }
|
||||
|
||||
targetMapping = bestPartialMatch?.Mapping;
|
||||
requestMatchResult = bestPartialMatch?.MatchResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
var perfectMatch = mappings
|
||||
.OrderBy(m => m.Mapping.Priority)
|
||||
.FirstOrDefault(m => m.MatchResult.IsPerfectMatch);
|
||||
// if (targetMapping == null)
|
||||
// {
|
||||
// response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
|
||||
// return;
|
||||
// }
|
||||
|
||||
targetMapping = perfectMatch?.Mapping;
|
||||
requestMatchResult = perfectMatch?.MatchResult;
|
||||
}
|
||||
// if (targetMapping.IsAdminInterface && _authorizationMatcher != null)
|
||||
// {
|
||||
// string authorization;
|
||||
// bool present = request.Headers.TryGetValue("Authorization", out authorization);
|
||||
// if (!present || _authorizationMatcher.IsMatch(authorization) < 1.0)
|
||||
// {
|
||||
// response = new ResponseMessage { StatusCode = 401 };
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (targetMapping == null)
|
||||
{
|
||||
response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
|
||||
return;
|
||||
}
|
||||
// response = await targetMapping.ResponseTo(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
|
||||
// };
|
||||
|
||||
if (targetMapping.IsAdminInterface && _authorizationMatcher != null)
|
||||
{
|
||||
string authorization;
|
||||
bool present = request.Headers.TryGetValue("Authorization", out authorization);
|
||||
if (!present || _authorizationMatcher.IsMatch(authorization) < 1.0)
|
||||
{
|
||||
response = new ResponseMessage { StatusCode = 401 };
|
||||
return;
|
||||
}
|
||||
}
|
||||
// LogRequest(log);
|
||||
|
||||
response = await targetMapping.ResponseTo(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);
|
||||
|
||||
_responseMapper.Map(response, ctx.Response);
|
||||
ctx.Response.Close();
|
||||
}
|
||||
}
|
||||
// _responseMapper.MapAsync(response, ctx.Response);
|
||||
// ctx.Response.Close();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
/// <value>
|
||||
/// The use SSL.
|
||||
/// </value>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public bool? UseSSL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -44,5 +45,10 @@
|
||||
/// The urls.
|
||||
/// </value>
|
||||
public string[] Urls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StartTimeout
|
||||
/// </summary>
|
||||
public int StartTimeout { get; set; } = 10000;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using JetBrains.Annotations;
|
||||
@@ -12,7 +11,7 @@ using JetBrains.Annotations;
|
||||
// Copied from https://github.com/aspnet/EntityFramework/blob/dev/src/Shared/Check.cs
|
||||
namespace WireMock.Validation
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
// [ExcludeFromCodeCoverage]
|
||||
[DebuggerStepThrough]
|
||||
internal static class Check
|
||||
{
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
// copied from https://github.com/aspnet/EntityFramework/blob/dev/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.resx
|
||||
namespace WireMock.Validation
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
// [ExcludeFromCodeCoverage]
|
||||
internal static class CoreStrings
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB |
@@ -3,14 +3,14 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
|
||||
<AssemblyTitle>WireMock.Net</AssemblyTitle>
|
||||
<VersionPrefix>1.0.1.5</VersionPrefix>
|
||||
<Version>1.0.2.0</Version>
|
||||
<Authors>Alexandre Victoor;Stef Heyenrath</Authors>
|
||||
<TargetFramework>net45</TargetFramework>
|
||||
<TargetFrameworks>net45;netstandard1.3</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net</AssemblyName>
|
||||
<PackageId>WireMock.Net</PackageId>
|
||||
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
|
||||
<PackageReleaseNotes>Fix StartAndStop from listener.</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>Support for NETStandard by replacing HttpListener by Owin</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/StefH/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/StefH/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://raw.githubusercontent.com/StefH/WireMock.Net/master/LICENSE</PackageLicenseUrl>
|
||||
@@ -18,23 +18,40 @@
|
||||
<RepositoryUrl>https://github.com/StefH/WireMock.Net</RepositoryUrl>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<DebugType>full</DebugType>
|
||||
<ApplicationIcon>WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<Version>1.0.2.0</Version>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<DefineConstants>NETSTANDARD</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="10.4.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Handlebars.Net" Version="1.8.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="6.0.8" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.3" />
|
||||
<PackageReference Include="XPath2" Version="1.0.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.3" />
|
||||
<PackageReference Include="Handlebars.Net" Version="1.8.0" />
|
||||
<PackageReference Include="XPath2" Version="1.0.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
|
||||
<PackageReference Include="System.Threading.Tasks" Version="4.3.0" />
|
||||
<PackageReference Include="Handlebars.Net" Version="1.8.0" />
|
||||
<PackageReference Include="XPath2" Version="1.0.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
|
||||
<PackageReference Include="Handlebars.NetStandard" Version="1.8.1" />
|
||||
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,15 +0,0 @@
|
||||
,
|
||||
"netstandard1.3": {
|
||||
"buildOptions": { "define": [ "NETSTANDARD" ] },
|
||||
"imports": [
|
||||
"dotnet5.4"
|
||||
],
|
||||
"dependencies": {
|
||||
"System.Collections.Concurrent": "4.3.0",
|
||||
"System.Diagnostics.Tools": "4.3.0",
|
||||
"System.Linq": "4.3.0",
|
||||
"System.Net.Http": "4.3.0",
|
||||
"System.Net.Sockets": "4.3.0",
|
||||
"System.Threading.Tasks": "4.3.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user