Skip to content

Commit 3a5921b

Browse files
committed
Re-attaching content related headers to the request content in a HttpRequestMessage
1 parent 6ba8e66 commit 3a5921b

File tree

3 files changed

+114
-7
lines changed

3 files changed

+114
-7
lines changed

PactNet.Tests/Mocks/MockHttpService/Mappers/HttpRequestMessageMapperTests.cs

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,17 @@ public void Convert_WithContentTypeAndCustomHeader_OnlyCustomHeadersIsAddedToHtt
220220
}
221221

222222
[Fact]
223-
public void Convert_WithContentLengthHeader_ContentLengthHeaderIsNotAdded()
223+
public void Convert_WithContentLengthHeader_ContentLengthHeaderIsNotAddedToHttpRequestMessage()
224224
{
225225
var request = new ProviderServiceRequest
226226
{
227227
Method = HttpVerb.Post,
228228
Path = "/events",
229229
Headers = new Dictionary<string, string>
230230
{
231-
{ "Content-Length", "100" }
232-
}
231+
{ "Content-Length", "12" }
232+
},
233+
Body = "Some content"
233234
};
234235

235236
var mapper = GetSubject();
@@ -241,6 +242,92 @@ public void Convert_WithContentLengthHeader_ContentLengthHeaderIsNotAdded()
241242
Assert.Equal(0, result.Headers.Count());
242243
}
243244

245+
[Fact]
246+
public void Convert_WithContentLengthHeader_ContentLengthHeaderIsAddedToHttpRequestMessageContentHeaders()
247+
{
248+
var request = new ProviderServiceRequest
249+
{
250+
Method = HttpVerb.Post,
251+
Path = "/events",
252+
Headers = new Dictionary<string, string>
253+
{
254+
{ "Content-Length", "12" }
255+
},
256+
Body = "Some content"
257+
};
258+
var httpBodyContent = new HttpBodyContent(request.Body, "text/plain", Encoding.UTF8);
259+
var stringContent = new StringContent(request.Body, Encoding.UTF8, "text/plain");
260+
261+
var mapper = GetSubject();
262+
263+
_mockHttpMethodMapper.Convert(HttpVerb.Post).Returns(HttpMethod.Post);
264+
_mockHttpBodyContentMapper.Convert(Arg.Any<string>(), Arg.Any<IDictionary<string, string>>()).Returns(httpBodyContent);
265+
_mockHttpContentMapper.Convert(httpBodyContent).Returns(stringContent);
266+
267+
var result = mapper.Convert(request);
268+
269+
Assert.Equal(request.Headers.Last().Key, result.Content.Headers.Last().Key);
270+
Assert.Equal(request.Headers.Last().Value, result.Content.Headers.Last().Value.First());
271+
}
272+
273+
[Fact]
274+
public void Convert_WithContentTypeSpecifiedAndAlsoBeingSetByStringContent_ContentTypeHeaderIsNotReAddedToHttpRequestMessageContentHeaders()
275+
{
276+
var request = new ProviderServiceRequest
277+
{
278+
Method = HttpVerb.Post,
279+
Path = "/events",
280+
Headers = new Dictionary<string, string>
281+
{
282+
{ "Content-Type", "text/plain" }
283+
},
284+
Body = "Some content"
285+
};
286+
var httpBodyContent = new HttpBodyContent(request.Body, "text/plain", Encoding.UTF8);
287+
var stringContent = new StringContent(request.Body, Encoding.UTF8, "text/plain");
288+
289+
var mapper = GetSubject();
290+
291+
_mockHttpMethodMapper.Convert(HttpVerb.Post).Returns(HttpMethod.Post);
292+
_mockHttpBodyContentMapper.Convert(Arg.Any<string>(), Arg.Any<IDictionary<string, string>>()).Returns(httpBodyContent);
293+
_mockHttpContentMapper.Convert(httpBodyContent).Returns(stringContent);
294+
295+
var result = mapper.Convert(request);
296+
297+
Assert.Equal(1, result.Content.Headers.Count());
298+
Assert.Equal(request.Headers.First().Key, result.Content.Headers.First().Key);
299+
Assert.Equal("text/plain; charset=utf-8", result.Content.Headers.First().Value.First());
300+
}
301+
302+
[Fact]
303+
public void Convert_WithContentTypeSpecifiedButNotBeingSetByByteArrayContent_ContentTypeHeaderIsNotReAddedToHttpRequestMessageContentHeaders()
304+
{
305+
var request = new ProviderServiceRequest
306+
{
307+
Method = HttpVerb.Post,
308+
Path = "/events",
309+
Headers = new Dictionary<string, string>
310+
{
311+
{ "Content-Type", "application/octet-stream" }
312+
},
313+
Body = Encoding.UTF8.GetBytes("Some content")
314+
};
315+
var httpBodyContent = new HttpBodyContent(request.Body, "text/plain", Encoding.UTF8);
316+
var byteArrayContent = new ByteArrayContent(request.Body as byte[]);
317+
318+
var mapper = GetSubject();
319+
320+
_mockHttpMethodMapper.Convert(HttpVerb.Post).Returns(HttpMethod.Post);
321+
_mockHttpBodyContentMapper.Convert(Arg.Any<object>(), Arg.Any<IDictionary<string, string>>()).Returns(httpBodyContent);
322+
_mockHttpContentMapper.Convert(httpBodyContent).Returns(byteArrayContent);
323+
324+
var result = mapper.Convert(request);
325+
326+
Assert.Equal(1, result.Content.Headers.Count());
327+
Assert.Equal(request.Headers.First().Key, result.Content.Headers.First().Key);
328+
Assert.Equal("application/octet-stream", result.Content.Headers.First().Value.First());
329+
}
330+
244331
[Fact]
245332
public void Convert_WithBody_HttpContentMapperIsCalled()
246333
{
@@ -279,7 +366,7 @@ public void Convert_WithTheWorks_CorrectlyMappedHttpRequestMessageIsReturned()
279366
{
280367
{ "Content-Type", contentTypeString + "; charset=" + encodingString },
281368
{ "X-Custom", "My Custom header" },
282-
{ "Content-Length", "10000" }, //This header is removed and replace with the correct value of 29
369+
{ "Content-Length", "1000" }
283370
},
284371
Body = new
285372
{
@@ -314,7 +401,7 @@ public void Convert_WithTheWorks_CorrectlyMappedHttpRequestMessageIsReturned()
314401

315402
//Content-Length header
316403
Assert.Equal(request.Headers.Last().Key, contentLengthHeader.Key);
317-
Assert.Equal("29", contentLengthHeader.Value.First());
404+
Assert.Equal(request.Headers.Last().Value, contentLengthHeader.Value.First());
318405
}
319406
}
320407
}

PactNet/Mocks/MockHttpService/HttpClientRequestSender.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public ProviderServiceResponse Send(ProviderServiceRequest request)
4141

4242
if (httpRequest != null)
4343
{
44-
if (httpResponse.Content != null)
44+
if (httpRequest.Content != null)
4545
{
4646
httpRequest.Content.Dispose();
4747
}

PactNet/Mocks/MockHttpService/Mappers/HttpRequestMessageMapper.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Net.Http;
45
using PactNet.Mocks.MockHttpService.Models;
@@ -40,13 +41,15 @@ public HttpRequestMessage Convert(ProviderServiceRequest from)
4041

4142
var to = new HttpRequestMessage(requestHttpMethod, requestPath);
4243

44+
var contentRelatedHeaders = new Dictionary<string, string>();
4345
if (from.Headers != null && from.Headers.Any())
4446
{
4547
foreach (var requestHeader in from.Headers)
4648
{
4749
//Strip any Content- headers as they need to be attached to Request content when using a HttpRequestMessage
4850
if (requestHeader.Key.IndexOf("Content-", StringComparison.InvariantCultureIgnoreCase) == 0)
4951
{
52+
contentRelatedHeaders.Add(requestHeader.Key, requestHeader.Value);
5053
continue;
5154
}
5255

@@ -57,7 +60,24 @@ public HttpRequestMessage Convert(ProviderServiceRequest from)
5760
if (from.Body != null)
5861
{
5962
HttpBodyContent bodyContent = _httpBodyContentMapper.Convert(from.Body, from.Headers);
60-
to.Content = _httpContentMapper.Convert(bodyContent);
63+
var httpContent = _httpContentMapper.Convert(bodyContent);
64+
65+
//Set the content related headers
66+
if (httpContent != null && contentRelatedHeaders.Any())
67+
{
68+
foreach (var contentHeader in contentRelatedHeaders)
69+
{
70+
if (contentHeader.Key.Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase) &&
71+
httpContent.Headers.Any(x => x.Key.Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase)))
72+
{
73+
continue;
74+
}
75+
76+
httpContent.Headers.Add(contentHeader.Key, contentHeader.Value);
77+
}
78+
}
79+
80+
to.Content = httpContent;
6181
}
6282

6383
return to;

0 commit comments

Comments
 (0)