Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating (#62)

* feat: Add the Host, Protocol Port and Origin to the Request message

- Add new fields during request message creation, derived from the Uri object
- Allow the new fields to be accessed in the templating engine
- Add tests for the new fields

* source code file reformat

* appveyor
This commit is contained in:
Alastair Crabtree
2017-11-18 11:03:13 +00:00
committed by Stef Heyenrath
parent cb1117fdaa
commit 6c38400827
3 changed files with 189 additions and 146 deletions

View File

@@ -39,6 +39,6 @@ test_script:
- nuget.exe install coveralls.net -ExcludeVersion - nuget.exe install coveralls.net -ExcludeVersion
- pip install codecov - pip install codecov
- cmd: '"OpenCover\tools\OpenCover.Console.exe" -register:user -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -returntargetcode -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -output:coverage.xml -oldstyle -searchdirs:".\test\WireMock.Net.Tests\bin\%CONFIGURATION%\net452"' - cmd: '"OpenCover\tools\OpenCover.Console.exe" -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -output:coverage.xml -returntargetcode -register:user -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -nodefaultfilters -returntargetcode -oldstyle'
- codecov -f "coverage.xml" - codecov -f "coverage.xml"
- coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml - coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml

View File

@@ -1,146 +1,170 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using WireMock.Util; using WireMock.Util;
using WireMock.Validation; using WireMock.Validation;
using System.Text; using System.Text;
namespace WireMock namespace WireMock
{ {
/// <summary> /// <summary>
/// The request. /// The request.
/// </summary> /// </summary>
public class RequestMessage public class RequestMessage
{ {
/// <summary> /// <summary>
/// Gets the Client IP Address. /// Gets the Client IP Address.
/// </summary> /// </summary>
public string ClientIP { get; } public string ClientIP { get; }
/// <summary> /// <summary>
/// Gets the url. /// Gets the url.
/// </summary> /// </summary>
public string Url { get; } public string Url { get; }
/// <summary> /// <summary>
/// Gets the DateTime. /// Gets the DateTime.
/// </summary> /// </summary>
public DateTime DateTime { get; set; } public DateTime DateTime { get; set; }
/// <summary> /// <summary>
/// Gets the path. /// Gets the path.
/// </summary> /// </summary>
public string Path { get; } public string Path { get; }
/// <summary> /// <summary>
/// Gets the method. /// Gets the method.
/// </summary> /// </summary>
public string Method { get; } public string Method { get; }
/// <summary> /// <summary>
/// Gets the headers. /// Gets the headers.
/// </summary> /// </summary>
public IDictionary<string, WireMockList<string>> Headers { get; } public IDictionary<string, WireMockList<string>> Headers { get; }
/// <summary> /// <summary>
/// Gets the cookies. /// Gets the cookies.
/// </summary> /// </summary>
public IDictionary<string, string> Cookies { get; } public IDictionary<string, string> Cookies { get; }
/// <summary> /// <summary>
/// Gets the query. /// Gets the query.
/// </summary> /// </summary>
public IDictionary<string, WireMockList<string>> Query { get; } public IDictionary<string, WireMockList<string>> Query { get; }
/// <summary> /// <summary>
/// Gets the bodyAsBytes. /// Gets the bodyAsBytes.
/// </summary> /// </summary>
public byte[] BodyAsBytes { get; } public byte[] BodyAsBytes { get; }
/// <summary> /// <summary>
/// Gets the body. /// Gets the body.
/// </summary> /// </summary>
public string Body { get; } public string Body { get; }
/// <summary> /// <summary>
/// Gets the body encoding. /// Gets the Host
/// </summary> /// </summary>
public Encoding BodyEncoding { get; } public string Host { get; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RequestMessage"/> class. /// Gets the protocol
/// </summary> /// </summary>
/// <param name="url">The original url.</param> public string Protocol { get; }
/// <param name="method">The HTTP method.</param>
/// <param name="clientIP">The client IP Address.</param> /// <summary>
/// <param name="bodyAsBytes">The bodyAsBytes byte[].</param> /// Gets the port
/// <param name="body">The body string.</param> /// </summary>
/// <param name="bodyEncoding">The body encoding</param> public int Port { get; }
/// <param name="headers">The headers.</param>
/// <param name="cookies">The cookies.</param> /// <summary>
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] bodyAsBytes = null, [CanBeNull] string body = null, [CanBeNull] Encoding bodyEncoding = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null) /// Gets the origin
{ /// </summary>
Check.NotNull(url, nameof(url)); public string Origin { get; }
Check.NotNull(method, nameof(method));
Check.NotNull(clientIP, nameof(clientIP)); /// <summary>
/// Gets the body encoding.
Url = url.ToString(); /// </summary>
Path = url.AbsolutePath; public Encoding BodyEncoding { get; }
Method = method.ToLower();
ClientIP = clientIP; /// <summary>
BodyAsBytes = bodyAsBytes; /// Initializes a new instance of the <see cref="RequestMessage"/> class.
Body = body; /// </summary>
BodyEncoding = bodyEncoding; /// <param name="url">The original url.</param>
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value)); /// <param name="method">The HTTP method.</param>
Cookies = cookies; /// <param name="clientIP">The client IP Address.</param>
Query = ParseQuery(url.Query); /// <param name="bodyAsBytes">The bodyAsBytes byte[].</param>
} /// <param name="body">The body string.</param>
/// <param name="bodyEncoding">The body encoding</param>
private IDictionary<string, WireMockList<string>> ParseQuery(string queryString) /// <param name="headers">The headers.</param>
{ /// <param name="cookies">The cookies.</param>
if (string.IsNullOrEmpty(queryString)) public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] bodyAsBytes = null, [CanBeNull] string body = null, [CanBeNull] Encoding bodyEncoding = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
{ {
return null; Check.NotNull(url, nameof(url));
} Check.NotNull(method, nameof(method));
Check.NotNull(clientIP, nameof(clientIP));
if (queryString.StartsWith("?"))
{ Url = url.ToString();
queryString = queryString.Substring(1); Protocol = url.Scheme;
} Host = url.Host;
Port = url.Port;
return queryString.Split('&').Aggregate(new Dictionary<string, WireMockList<string>>(), Origin = $"{url.Scheme}://{url.Host}:{url.Port}";
(dict, term) => Path = url.AbsolutePath;
{ Method = method.ToLower();
var parts = term.Split('='); ClientIP = clientIP;
string key = parts[0]; BodyAsBytes = bodyAsBytes;
if (!dict.ContainsKey(key)) Body = body;
{ BodyEncoding = bodyEncoding;
dict.Add(key, new WireMockList<string>()); Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
} Cookies = cookies;
Query = ParseQuery(url.Query);
if (parts.Length == 2) }
{
dict[key].Add(parts[1]); private IDictionary<string, WireMockList<string>> ParseQuery(string queryString)
} {
if (string.IsNullOrEmpty(queryString))
return dict; {
}); return null;
} }
/// <summary> if (queryString.StartsWith("?"))
/// The get a query parameter. {
/// </summary> queryString = queryString.Substring(1);
/// <param name="key">The key.</param> }
/// <returns>The query parameter.</returns>
public List<string> GetParameter(string key) return queryString.Split('&').Aggregate(new Dictionary<string, WireMockList<string>>(),
{ (dict, term) =>
if (Query == null) {
{ var parts = term.Split('=');
return null; string key = parts[0];
} if (!dict.ContainsKey(key))
{
return Query.ContainsKey(key) ? Query[key] : null; dict.Add(key, new WireMockList<string>());
} }
}
if (parts.Length == 2)
{
dict[key].Add(parts[1]);
}
return dict;
});
}
/// <summary>
/// The get a query parameter.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>The query parameter.</returns>
public List<string> GetParameter(string key)
{
if (Query == null)
{
return null;
}
return Query.ContainsKey(key) ? Query[key] : null;
}
}
} }

View File

@@ -86,5 +86,24 @@ namespace WireMock.Net.Tests
Check.That(responseMessage.Headers["x"]).Contains("text/plain"); Check.That(responseMessage.Headers["x"]).Contains("text/plain");
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo"); Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
} }
[Fact]
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost:1234"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var response = Response.Create()
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")
.WithTransformer();
// act
var responseMessage = await response.ProvideResponseAsync(request);
// then
Check.That(responseMessage.Body).Equals("test http://localhost:1234 1234 http localhost");
}
} }
} }