diff --git a/src/Ocelot.Library/Infrastructure/Requester/HttpClientHttpRequester.cs b/src/Ocelot.Library/Infrastructure/Requester/HttpClientHttpRequester.cs index a43f4f8b..977526fb 100644 --- a/src/Ocelot.Library/Infrastructure/Requester/HttpClientHttpRequester.cs +++ b/src/Ocelot.Library/Infrastructure/Requester/HttpClientHttpRequester.cs @@ -1,5 +1,6 @@ using System.IO; using System.Net.Http; +using System.Net.Http.Headers; using System.Threading.Tasks; using Flurl; using Flurl.Http; @@ -15,17 +16,30 @@ namespace Ocelot.Library.Infrastructure.Requester Stream content, IHeaderDictionary headers, IRequestCookieCollection cookies, - IQueryCollection queryString) + IQueryCollection queryString, + string contentType) { var method = new HttpMethod(httpMethod); var streamContent = new StreamContent(content); + if (!string.IsNullOrEmpty(contentType)) + { + var splitCt = contentType.Split(';'); + var cT = splitCt[0]; + streamContent.Headers.ContentType = new MediaTypeHeaderValue(cT); + } + + if (headers != null) + { + headers.Remove("Content-Type"); + } + if (content.Length > 0) { return await downstreamUrl .SetQueryParams(queryString) .WithCookies(cookies) - .WithHeaders(streamContent.Headers) + .WithHeaders(headers) .SendAsync(method, streamContent); } diff --git a/src/Ocelot.Library/Infrastructure/Requester/IHttpRequester.cs b/src/Ocelot.Library/Infrastructure/Requester/IHttpRequester.cs index 90ff384a..eaacbc54 100644 --- a/src/Ocelot.Library/Infrastructure/Requester/IHttpRequester.cs +++ b/src/Ocelot.Library/Infrastructure/Requester/IHttpRequester.cs @@ -14,6 +14,7 @@ namespace Ocelot.Library.Infrastructure.Requester Stream content, IHeaderDictionary headers, IRequestCookieCollection cookies, - IQueryCollection queryString); + IQueryCollection queryString, + string contentType); } } diff --git a/src/Ocelot.Library/Middleware/ProxyMiddleware.cs b/src/Ocelot.Library/Middleware/ProxyMiddleware.cs index 8749ac29..4540b25b 100644 --- a/src/Ocelot.Library/Middleware/ProxyMiddleware.cs +++ b/src/Ocelot.Library/Middleware/ProxyMiddleware.cs @@ -49,7 +49,7 @@ namespace Ocelot.Library.Middleware var response = await _requester .GetResponse(context.Request.Method, downstreamUrl, context.Request.Body, - context.Request.Headers, context.Request.Cookies, context.Request.Query); + context.Request.Headers, context.Request.Cookies, context.Request.Query, context.Request.ContentType); await _responder.CreateResponse(context, response); diff --git a/test/Ocelot.AcceptanceTests/OcelotTests.cs b/test/Ocelot.AcceptanceTests/OcelotTests.cs index 427dab0e..2d2a348b 100644 --- a/test/Ocelot.AcceptanceTests/OcelotTests.cs +++ b/test/Ocelot.AcceptanceTests/OcelotTests.cs @@ -1,19 +1,19 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Http; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.TestHost; +using Ocelot.AcceptanceTests.Fake; +using Ocelot.Library.Infrastructure.Configuration; +using Shouldly; +using TestStack.BDDfy; +using Xunit; +using YamlDotNet.Serialization; + namespace Ocelot.AcceptanceTests { - using System; - using System.Net.Http; - using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.TestHost; - using Xunit; - using Ocelot.AcceptanceTests.Fake; - using Shouldly; - using System.Collections.Generic; - using System.IO; - using System.Net; - using Library.Infrastructure.Configuration; - using TestStack.BDDfy; - using YamlDotNet.Serialization; - public class OcelotTests : IDisposable { private readonly FakeService _fakeService; @@ -21,7 +21,7 @@ namespace Ocelot.AcceptanceTests private HttpClient _client; private HttpResponseMessage _response; private readonly string _configurationPath; - private string _postContent; + private StringContent _postContent; public OcelotTests() { @@ -82,10 +82,9 @@ namespace Ocelot.AcceptanceTests .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.Created)) .BDDfy(); } - private void GivenThePostHasContent(string postcontent) { - _postContent = postcontent; + _postContent = new StringContent(postcontent); } /// @@ -126,8 +125,7 @@ namespace Ocelot.AcceptanceTests private void WhenIPostUrlOnTheApiGateway(string url) { - var content = new StringContent(_postContent); - _response = _client.PostAsync(url, content).Result; + _response = _client.PostAsync(url, _postContent).Result; } private void ThenTheStatusCodeShouldBe(HttpStatusCode expectedHttpStatusCode) diff --git a/test/Ocelot.UnitTests/Requester/RequesterTests.cs b/test/Ocelot.UnitTests/Requester/RequesterTests.cs index 64785665..9e3b4f61 100644 --- a/test/Ocelot.UnitTests/Requester/RequesterTests.cs +++ b/test/Ocelot.UnitTests/Requester/RequesterTests.cs @@ -27,6 +27,7 @@ namespace Ocelot.UnitTests.Requester private IHeaderDictionary _headers; private IRequestCookieCollection _cookies; private IQueryCollection _query; + private string _contentType; public RequesterTests() { @@ -65,6 +66,7 @@ namespace Ocelot.UnitTests.Requester this.Given(x => x.GivenIHaveHttpMethod("POST")) .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) + .And(x => x.GivenTheContentTypeIs("application/json")) .And(x => x.GivenTheDownstreamServerReturns(HttpStatusCode.Created)) .When(x => x.WhenIMakeARequest()) .Then(x => x.ThenTheFollowingIsReturned(HttpStatusCode.Created)) @@ -79,29 +81,18 @@ namespace Ocelot.UnitTests.Requester { this.Given(x => x.GivenIHaveHttpMethod("POST")) .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) - .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom") - { - Headers = - { - {"Boom", "TickTick"} - } - })) + .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) + .And(x => x.GivenTheContentTypeIs("application/json")) .And(x => x.GivenTheDownstreamServerReturns(HttpStatusCode.Created)) .When(x => x.WhenIMakeARequest()) .Then(x => x.ThenTheFollowingIsReturned(HttpStatusCode.Created)) .And(x => x.ThenTheDownstreamServerIsCalledCorrectly()) .And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post)) - .And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom") - { - Headers = - { - { "Boom", "TickTick" } - } - })) + .And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom"))) .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary { { - "Boom", "TickTick" + "Content-Type", "application/json" } })) .BDDfy(); @@ -165,6 +156,11 @@ namespace Ocelot.UnitTests.Requester .BDDfy(); } + private void GivenTheContentTypeIs(string contentType) + { + _contentType = contentType; + } + private void ThenTheCorrectQueryStringIsUsed(string expected) { _httpTest.CallLog[0].Request.RequestUri.Query.ShouldBe(expected); @@ -211,7 +207,7 @@ namespace Ocelot.UnitTests.Requester foreach (var expectedHeader in expectedHeaders) { _httpTest.CallLog[0].Request.Content.Headers.ShouldContain(x => x.Key == expectedHeader.Key - //&& x.Value.First() == expectedHeader.Value[0] + && x.Value.First() == expectedHeader.Value[0] ); } } @@ -246,7 +242,7 @@ namespace Ocelot.UnitTests.Requester _result = _httpRequester .GetResponse(_httpMethod, _downstreamUrl, _content != null ? _content.ReadAsStreamAsync().Result : Stream.Null, - _headers, _cookies, _query).Result; + _headers, _cookies, _query, _contentType).Result; } private void ThenTheFollowingIsReturned(HttpStatusCode expected)