check which version of .net framework before creating http handler (#412)

* #405 needto check which version of .net we are using but cannot use compiler directives

* #405 started puttig abstraction around static method to get frameworks so we can test this logic

* #405 added test for all methods and tidied up tests

* #405 made contains as ms docs are wrong, thanks to davidni for the heads up
This commit is contained in:
Tom Pallister
2018-06-20 20:44:38 +01:00
committed by GitHub
parent b5a827cf70
commit e636cefdb1
12 changed files with 366 additions and 199 deletions

View File

@ -48,6 +48,7 @@ namespace Ocelot.DependencyInjection
using ServiceDiscovery.Providers;
using Steeltoe.Common.Discovery;
using Pivotal.Discovery.Client;
using Ocelot.Request.Creator;
public class OcelotBuilder : IOcelotBuilder
{
@ -161,6 +162,8 @@ namespace Ocelot.DependencyInjection
_services.TryAddSingleton<IConsulClientFactory, ConsulClientFactory>();
_services.TryAddSingleton<IResponseAggregatorFactory, InMemoryResponseAggregatorFactory>();
_services.TryAddSingleton<IDefinedAggregatorProvider, ServiceLocatorDefinedAggregatorProvider>();
_services.TryAddSingleton<IDownstreamRequestCreator, DownstreamRequestCreator>();
_services.TryAddSingleton<IFrameworkDescription, FrameworkDescription>();
}
public IOcelotAdministrationBuilder AddAdministration(string path, string secret)

View File

@ -0,0 +1,12 @@
using System.Runtime.InteropServices;
namespace Ocelot.Infrastructure
{
public class FrameworkDescription : IFrameworkDescription
{
public string Get()
{
return RuntimeInformation.FrameworkDescription;
}
}
}

View File

@ -0,0 +1,7 @@
namespace Ocelot.Infrastructure
{
public interface IFrameworkDescription
{
string Get();
}
}

View File

@ -0,0 +1,42 @@
namespace Ocelot.Request.Creator
{
using System.Net.Http;
using Ocelot.Request.Middleware;
using System.Runtime.InteropServices;
using Ocelot.Infrastructure;
public class DownstreamRequestCreator : IDownstreamRequestCreator
{
private readonly IFrameworkDescription _framework;
private const string dotNetFramework = ".NET Framework";
public DownstreamRequestCreator(IFrameworkDescription framework)
{
_framework = framework;
}
public DownstreamRequest Create(HttpRequestMessage request)
{
/**
* According to https://tools.ietf.org/html/rfc7231
* GET,HEAD,DELETE,CONNECT,TRACE
* Can have body but server can reject the request.
* And MS HttpClient in Full Framework actually rejects it.
* see #366 issue
**/
if(_framework.Get().Contains(dotNetFramework))
{
if (request.Method == HttpMethod.Get ||
request.Method == HttpMethod.Head ||
request.Method == HttpMethod.Delete ||
request.Method == HttpMethod.Trace)
{
request.Content = null;
}
}
return new DownstreamRequest(request);
}
}
}

View File

@ -0,0 +1,10 @@
namespace Ocelot.Request.Creator
{
using System.Net.Http;
using Ocelot.Request.Middleware;
public interface IDownstreamRequestCreator
{
DownstreamRequest Create(HttpRequestMessage request);
}
}

View File

@ -48,22 +48,6 @@ namespace Ocelot.Request.Middleware
Scheme = Scheme
};
/**
* According to https://tools.ietf.org/html/rfc7231
* GET,HEAD,DELETE,CONNECT,TRACE
* Can have body but server can reject the request.
* And MS HttpClient in Full Framework actually rejects it.
* see #366 issue
**/
#if NET461 || NET462 || NET47 || NET471 || NET472
if (_request.Method == HttpMethod.Get ||
_request.Method == HttpMethod.Head ||
_request.Method == HttpMethod.Delete ||
_request.Method == HttpMethod.Trace)
{
_request.Content = null;
}
#endif
_request.RequestUri = uriBuilder.Uri;
return _request;
}

View File

@ -1,39 +1,42 @@
namespace Ocelot.Request.Middleware
{
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
public class DownstreamRequestInitialiserMiddleware : OcelotMiddleware
{
private readonly OcelotRequestDelegate _next;
private readonly Mapper.IRequestMapper _requestMapper;
public DownstreamRequestInitialiserMiddleware(OcelotRequestDelegate next,
IOcelotLoggerFactory loggerFactory,
Mapper.IRequestMapper requestMapper)
:base(loggerFactory.CreateLogger<DownstreamRequestInitialiserMiddleware>())
{
_next = next;
_requestMapper = requestMapper;
}
public async Task Invoke(DownstreamContext context)
{
var downstreamRequest = await _requestMapper.Map(context.HttpContext.Request);
if (downstreamRequest.IsError)
{
SetPipelineError(context, downstreamRequest.Errors);
return;
}
context.DownstreamRequest = new DownstreamRequest(downstreamRequest.Data);
await _next.Invoke(context);
}
}
}
namespace Ocelot.Request.Middleware
{
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
using Ocelot.Request.Creator;
public class DownstreamRequestInitialiserMiddleware : OcelotMiddleware
{
private readonly OcelotRequestDelegate _next;
private readonly Mapper.IRequestMapper _requestMapper;
private readonly IDownstreamRequestCreator _creator;
public DownstreamRequestInitialiserMiddleware(OcelotRequestDelegate next,
IOcelotLoggerFactory loggerFactory,
Mapper.IRequestMapper requestMapper,
IDownstreamRequestCreator creator)
:base(loggerFactory.CreateLogger<DownstreamRequestInitialiserMiddleware>())
{
_next = next;
_requestMapper = requestMapper;
_creator = creator;
}
public async Task Invoke(DownstreamContext context)
{
var downstreamRequest = await _requestMapper.Map(context.HttpContext.Request);
if (downstreamRequest.IsError)
{
SetPipelineError(context, downstreamRequest.Errors);
return;
}
context.DownstreamRequest = _creator.Create(downstreamRequest.Data);
await _next.Invoke(context);
}
}
}