Skip to content

Commit

Permalink
Added X509Certificate2Filename (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed May 16, 2017
1 parent 961e8b5 commit 360a122
Show file tree
Hide file tree
Showing 17 changed files with 121 additions and 64 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w

### Frameworks
The following frameworks are supported:
- net45 and up
- net 4.5
- net 4.5.2 and up
- netstandard 1.3

## Stubbing
Expand Down
8 changes: 3 additions & 5 deletions examples/WireMock.Net.Console.Record.NETCoreApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@
using WireMock.Server;
using WireMock.Settings;

namespace WireMock.Net.Console.NETCoreApp
namespace WireMock.Net.Console.Record.NETCoreApp
{
static class Program
{
static void Main(params string[] args)
{
string url = "http://localhost:9095/";

var server = FluentMockServer.Start(new FluentMockServerSettings
{
Urls = new[] { url },
Urls = new[] { "http://localhost:9095/", "https://localhost:9096/" },
StartAdminInterface = true,
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = "http://www.bbc.com",
Url = "https://www.msn.com",
SaveMapping = true
}
});
Expand Down
8 changes: 6 additions & 2 deletions src/WireMock.Net.StandAlone.NETCoreApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ private class Options
[ValueArgument(typeof(string), "ProxyURL", Description = "The ProxyURL to use.", Optional = true)]
public string ProxyURL { get; set; }

[SwitchArgument("SaveProxyMapping", false, Description = "Save the proxied request and response mapping files in ./__admin/mappings. (default set to false).", Optional = true)]
[SwitchArgument("SaveProxyMapping", true, Description = "Save the proxied request and response mapping files in ./__admin/mappings. (default set to true).", Optional = true)]
public bool SaveMapping { get; set; }

[ValueArgument(typeof(string), "X509Certificate2", Description = "The X509Certificate2 Filename to use.", Optional = true)]
public string X509Certificate2Filename { get; set; }
}

static void Main(string[] args)
Expand Down Expand Up @@ -58,7 +61,8 @@ static void Main(string[] args)
settings.ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = options.ProxyURL,
SaveMapping = options.SaveMapping
SaveMapping = options.SaveMapping,
X509Certificate2Filename = options.X509Certificate2Filename
};
}

Expand Down
8 changes: 6 additions & 2 deletions src/WireMock.Net.StandAlone/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ private class Options
[ValueArgument(typeof(string), "ProxyURL", Description = "The ProxyURL to use.", Optional = true)]
public string ProxyURL { get; set; }

[SwitchArgument("SaveProxyMapping", false, Description = "Save the proxied request and response mapping files in ./__admin/mappings. (default set to false).", Optional = true)]
[SwitchArgument("SaveProxyMapping", true, Description = "Save the proxied request and response mapping files in ./__admin/mappings. (default set to true).", Optional = true)]
public bool SaveMapping { get; set; }

[ValueArgument(typeof(string), "X509Certificate2", Description = "The X509Certificate2 Filename to use.", Optional = true)]
public string X509Certificate2Filename { get; set; }
}

static void Main(params string[] args)
Expand Down Expand Up @@ -58,7 +61,8 @@ static void Main(params string[] args)
settings.ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = options.ProxyURL,
SaveMapping = options.SaveMapping
SaveMapping = options.SaveMapping,
X509Certificate2Filename = options.X509Certificate2Filename
};
}

Expand Down
33 changes: 31 additions & 2 deletions src/WireMock.Net/Http/HttpClientHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,39 @@ namespace WireMock.Http
{
internal static class HttpClientHelper
{
private static HttpClient client = new HttpClient();
private static HttpClient CreateHttpClient(string clientX509Certificate2Filename = null)
{
if (!string.IsNullOrEmpty(clientX509Certificate2Filename))
{
#if NETSTANDARD || NET46
var handler = new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
};

handler.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate2(clientX509Certificate2Filename));
return new HttpClient(handler);
#else
var handler = new WebRequestHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true
};

public static async Task<ResponseMessage> SendAsync(RequestMessage requestMessage, string url)
handler.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate2(clientX509Certificate2Filename));
return new HttpClient(handler);
#endif
}

return new HttpClient();
}

public static async Task<ResponseMessage> SendAsync(RequestMessage requestMessage, string url, string clientX509Certificate2Filename = null)
{
var client = CreateHttpClient(clientX509Certificate2Filename);

var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);

// Overwrite the host header
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,12 @@ protected RequestMessageCompositeMatcher([NotNull] IEnumerable<IRequestMatcher>
/// </returns>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
var list = new List<double>();
if (_type == CompositeMatcherType.And)
{
foreach (var requestMatcher in RequestMatchers)
{
double score = requestMatcher.GetMatchingScore(requestMessage, requestMatchResult);
list.Add(score);
}

return list.Sum() / list.Count;
}

foreach (var requestMatcher in RequestMatchers)
{
double score = requestMatcher.GetMatchingScore(requestMessage, requestMatchResult);
list.Add(score);
return RequestMatchers.Average(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchResult));
}

return list.Max();
return RequestMatchers.Max(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchResult));
}
}
}
12 changes: 5 additions & 7 deletions src/WireMock.Net/Matchers/XPathMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Xml;
using JetBrains.Annotations;
using WireMock.Validation;
#if NET45
#if !NETSTANDARD
using Wmhelp.XPath2;
#endif

Expand Down Expand Up @@ -41,10 +41,10 @@ public double IsMatch(string input)
try
{
var nav = new XmlDocument { InnerXml = input }.CreateNavigator();
#if NET45
return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})"))));
#else
#if NETSTANDARD
return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})"))));
#else
return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})"))));
#endif
}
catch (Exception)
Expand All @@ -65,9 +65,7 @@ public string[] GetPatterns()
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>
/// Name
/// </returns>
/// <returns>Name</returns>
public string GetName()
{
return "XPathMatcher";
Expand Down
2 changes: 1 addition & 1 deletion src/WireMock.Net/Owin/AspNetCoreSelfHost.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if !NET45
#if NETSTANDARD
using System;
using System.Collections.Generic;
using System.Threading;
Expand Down
7 changes: 3 additions & 4 deletions src/WireMock.Net/Owin/OwinRequestMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#if NET45
#if !NETSTANDARD
using Microsoft.Owin;
#else
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Features;
#endif

namespace WireMock.Owin
Expand All @@ -25,14 +24,14 @@ public class OwinRequestMapper
/// <param name="request"></param>
/// <returns></returns>
public async Task<RequestMessage> MapAsync(
#if NET45
#if !NETSTANDARD
IOwinRequest request
#else
HttpRequest request
#endif
)
{
#if NET45
#if !NETSTANDARD
Uri url = request.Uri;
#else
Uri url = new Uri(request.GetEncodedUrl());
Expand Down
4 changes: 2 additions & 2 deletions src/WireMock.Net/Owin/OwinResponseMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#if NET45
#if !NETSTANDARD
using Microsoft.Owin;
#else
using Microsoft.AspNetCore.Http;
Expand All @@ -23,7 +23,7 @@ public class OwinResponseMapper
/// <param name="responseMessage"></param>
/// <param name="response"></param>
public async Task MapAsync(ResponseMessage responseMessage
#if NET45
#if !NETSTANDARD
, IOwinResponse response
#else
, HttpResponse response
Expand Down
2 changes: 1 addition & 1 deletion src/WireMock.Net/Owin/OwinSelfHost.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if NET45
#if !NETSTANDARD
using System;
using System.Collections.Generic;
using System.Threading;
Expand Down
8 changes: 4 additions & 4 deletions src/WireMock.Net/Owin/WireMockMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
using WireMock.Logging;
using WireMock.Matchers.Request;
using System.Linq;
#if NET45
#if !NETSTANDARD
using Microsoft.Owin;
#else
using Microsoft.AspNetCore.Http;
#endif

namespace WireMock.Owin
{
#if NET45
#if !NETSTANDARD
internal class WireMockMiddleware : OwinMiddleware
#else
internal class WireMockMiddleware
Expand All @@ -24,7 +24,7 @@ internal class WireMockMiddleware
private readonly OwinRequestMapper _requestMapper = new OwinRequestMapper();
private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();

#if NET45
#if !NETSTANDARD
public WireMockMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)
{
_options = options;
Expand All @@ -36,7 +36,7 @@ public WireMockMiddleware(RequestDelegate next, WireMockMiddlewareOptions option
}
#endif

#if NET45
#if !NETSTANDARD
public override async Task Invoke(IOwinContext ctx)
#else
public async Task Invoke(HttpContext ctx)
Expand Down
10 changes: 9 additions & 1 deletion src/WireMock.Net/ResponseBuilders/IProxyResponseBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ namespace WireMock.ResponseBuilders
public interface IProxyResponseBuilder : IStatusCodeResponseBuilder
{
/// <summary>
/// From Proxy URL.
/// With Proxy URL.
/// </summary>
/// <param name="proxyUrl">The proxy url.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithProxy([NotNull] string proxyUrl);

/// <summary>
/// With Proxy URL using X509Certificate2.
/// </summary>
/// <param name="proxyUrl">The proxy url.</param>
/// <param name="clientX509Certificate2Filename">The X509Certificate2 file to use for client authentication.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithProxy([NotNull] string proxyUrl, [CanBeNull] string clientX509Certificate2Filename);
}
}
30 changes: 26 additions & 4 deletions src/WireMock.Net/ResponseBuilders/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public class Response : IResponseBuilder
/// </summary>
public string ProxyUrl { get; private set; }

/// <summary>
/// The client X509Certificate2Filename to use.
/// </summary>
public string X509Certificate2Filename { get; private set; } = null;

/// <summary>
/// Gets the response message.
/// </summary>
Expand Down Expand Up @@ -190,7 +195,7 @@ public IResponseBuilder WithBodyAsJson(object body, Encoding encoding = null)
/// <param name="bodyAsbase64">The body asbase64.</param>
/// <param name="encoding">The Encoding.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithBodyAsBase64([NotNull] string bodyAsbase64, Encoding encoding = null)
public IResponseBuilder WithBodyAsBase64(string bodyAsbase64, Encoding encoding = null)
{
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));

Expand Down Expand Up @@ -237,7 +242,7 @@ public IResponseBuilder WithDelay(int milliseconds)
}

/// <summary>
/// From Proxy URL.
/// With Proxy URL.
/// </summary>
/// <param name="proxyUrl">The proxy url.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
Expand All @@ -250,6 +255,22 @@ public IResponseBuilder WithProxy(string proxyUrl)
return this;
}

/// <summary>
/// With Proxy URL.
/// </summary>
/// <param name="proxyUrl">The proxy url.</param>
/// <param name="clientX509Certificate2Filename">The X509Certificate2 file to use for client authentication.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2Filename)
{
Check.NotEmpty(proxyUrl, nameof(proxyUrl));
Check.NotEmpty(clientX509Certificate2Filename, nameof(clientX509Certificate2Filename));

ProxyUrl = proxyUrl;
X509Certificate2Filename = clientX509Certificate2Filename;
return this;
}

/// <summary>
/// The provide response.
/// </summary>
Expand All @@ -264,9 +285,10 @@ public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMe

if (ProxyUrl != null)
{
return await HttpClientHelper.SendAsync(requestMessage, ProxyUrl);
return await HttpClientHelper.SendAsync(requestMessage, ProxyUrl, X509Certificate2Filename);
}
else if (UseTransformer)

if (UseTransformer)
{
return ResponseMessageTransformer.Transform(requestMessage, ResponseMessage);
}
Expand Down
6 changes: 3 additions & 3 deletions src/WireMock.Net/Server/FluentMockServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ private FluentMockServer(FluentMockServerSettings settings)
Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
}

#if NET45
_httpServer = new OwinSelfHost(_options, Urls);
#else
#if NETSTANDARD
_httpServer = new AspNetCoreSelfHost(_options, Urls);
#else
_httpServer = new OwinSelfHost(_options, Urls);
#endif
Ports = _httpServer.Ports;

Expand Down
5 changes: 5 additions & 0 deletions src/WireMock.Net/Settings/ProxyAndRecordSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,10 @@ public class ProxyAndRecordSettings
/// Save the mapping for each request/response.
/// </summary>
public bool SaveMapping { get; set; } = true;

/// <summary>
/// The clientCertificateFilename to use. Example : "C:\certificates\cert.pfx"
/// </summary>
public string X509Certificate2Filename { get; set; }
}
}
Loading

0 comments on commit 360a122

Please sign in to comment.