diff --git a/WireMock.Net Solution.sln.DotSettings b/WireMock.Net Solution.sln.DotSettings
index 84b8ed70..f55a13e7 100644
--- a/WireMock.Net Solution.sln.DotSettings
+++ b/WireMock.Net Solution.sln.DotSettings
@@ -9,6 +9,7 @@
WWW
XMS
XUA
+ True
True
True
True
diff --git a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
index 1c590629..a18cd321 100644
--- a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
+++ b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
@@ -97,7 +97,7 @@ namespace WireMock.Net.ConsoleApplication
.WithHeader("postmanecho", "post")
)
.RespondWith(Response.Create()
- .WithProxy(new ProxyAndRecordSettings { Url = "http://postman-echo.com/post" })
+ .WithProxy(new ProxyAndRecordSettings { Url = "http://postman-echo.com" })
);
server
diff --git a/src/WireMock.Net.Abstractions/Admin/Requests/LogRequestModel.cs b/src/WireMock.Net.Abstractions/Admin/Requests/LogRequestModel.cs
index e63eb76d..dc94df25 100644
--- a/src/WireMock.Net.Abstractions/Admin/Requests/LogRequestModel.cs
+++ b/src/WireMock.Net.Abstractions/Admin/Requests/LogRequestModel.cs
@@ -40,6 +40,11 @@ namespace WireMock.Admin.Requests
///
public string AbsoluteUrl { get; set; }
+ ///
+ /// The ProxyUrl (if a proxy is used).
+ ///
+ public string ProxyUrl { get; set; }
+
///
/// The query.
///
diff --git a/src/WireMock.Net/RequestMessage.cs b/src/WireMock.Net/RequestMessage.cs
index 10882ba6..361db0ea 100644
--- a/src/WireMock.Net/RequestMessage.cs
+++ b/src/WireMock.Net/RequestMessage.cs
@@ -32,6 +32,11 @@ namespace WireMock
///
public string AbsoluteUrl { get; }
+ ///
+ /// The ProxyUrl (if a proxy is used).
+ ///
+ public string ProxyUrl { get; set; }
+
///
/// Gets the DateTime.
///
diff --git a/src/WireMock.Net/ResponseBuilders/Response.cs b/src/WireMock.Net/ResponseBuilders/Response.cs
index e3d67985..c791969a 100644
--- a/src/WireMock.Net/ResponseBuilders/Response.cs
+++ b/src/WireMock.Net/ResponseBuilders/Response.cs
@@ -343,14 +343,22 @@ namespace WireMock.ResponseBuilders
if (ProxyUrl != null && _httpClientForProxy != null)
{
+ string RemoveFirstOccurrence(string source, string find)
+ {
+ int place = source.IndexOf(find, StringComparison.OrdinalIgnoreCase);
+ return place >= 0 ? source.Remove(place, find.Length) : source;
+ }
+
var requestUri = new Uri(requestMessage.Url);
- var proxyUri = new Uri(ProxyUrl);
- var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
+
+ // Build the proxy url and skip duplicates
+ string extra = RemoveFirstOccurrence(requestUri.LocalPath.TrimEnd('/'), new Uri(ProxyUrl).LocalPath.TrimEnd('/'));
+ requestMessage.ProxyUrl = ProxyUrl + extra + requestUri.Query;
return await HttpClientHelper.SendAsync(
- _httpClientForProxy,
+ _httpClientForProxy,
requestMessage,
- proxyUriWithRequestPathAndQuery.AbsoluteUri,
+ requestMessage.ProxyUrl,
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
);
diff --git a/src/WireMock.Net/Serialization/LogEntryMapper.cs b/src/WireMock.Net/Serialization/LogEntryMapper.cs
index 9ea871f6..46ef1085 100644
--- a/src/WireMock.Net/Serialization/LogEntryMapper.cs
+++ b/src/WireMock.Net/Serialization/LogEntryMapper.cs
@@ -20,6 +20,7 @@ namespace WireMock.Serialization
AbsolutePath = logEntry.RequestMessage.AbsolutePath,
Url = logEntry.RequestMessage.Url,
AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
+ ProxyUrl = logEntry.RequestMessage.ProxyUrl,
Query = logEntry.RequestMessage.Query,
Method = logEntry.RequestMessage.Method,
Headers = logEntry.RequestMessage.Headers,
diff --git a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithProxyTests.cs b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithProxyTests.cs
index 9219e2cd..c5eae9f6 100644
--- a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithProxyTests.cs
+++ b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithProxyTests.cs
@@ -16,6 +16,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
{
public class ResponseWithProxyTests : IDisposable
{
+ private const string ClientIp = "::1";
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
private readonly WireMockServer _server;
private readonly Guid _guid;
@@ -27,21 +28,32 @@ namespace WireMock.Net.Tests.ResponseBuilders
_server = WireMockServer.Start();
_server.Given(Request.Create().UsingPost().WithPath($"/{_guid}"))
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 42 }).WithHeader("Content-Type", "application/json"));
+ _server.Given(Request.Create().UsingPost().WithPath($"/{_guid}/append"))
+ .RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 10 }).WithHeader("Content-Type", "application/json"));
+ _server.Given(Request.Create().UsingPost().WithPath($"/prepend/{_guid}"))
+ .RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 11 }).WithHeader("Content-Type", "application/json"));
+ _server.Given(Request.Create().UsingPost().WithPath($"/prepend/{_guid}/append"))
+ .RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 12 }).WithHeader("Content-Type", "application/json"));
}
- [Fact]
- public async Task Response_WithProxy()
+ [Theory]
+ [InlineData("", "", "{\"p\":42}")]
+ [InlineData("", "/append", "{\"p\":10}")]
+ [InlineData("/prepend", "", "{\"p\":11}")]
+ [InlineData("/prepend", "/append", "{\"p\":12}")]
+ public async Task Response_WithProxy(string prepend, string append, string expectedBody)
{
// Assign
var headers = new Dictionary { { "Content-Type", new[] { "application/xml" } } };
- var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "POST", "::1", new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = new { a = 1 } }, headers);
+ var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}{prepend}/{_guid}{append}"), "POST", ClientIp, new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = new { a = 1 } }, headers);
var response = Response.Create().WithProxy(_server.Urls[0]);
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
- Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("{\"p\":42}");
+ Check.That(request.ProxyUrl).IsNotNull();
+ Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo(expectedBody);
Check.That(responseMessage.StatusCode).IsEqualTo(201);
Check.That(responseMessage.Headers["Content-Type"].ToString()).IsEqualTo("application/json");
}
@@ -63,7 +75,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
var response = Response.Create().WithProxy(settings);
// Act
- var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", "::1");
+ var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", ClientIp);
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws();
}