Support adding custom plaintext headers to downstream requests (#314)

This commit is contained in:
Felix Boers
2018-04-14 07:41:12 +02:00
committed by Tom Pallister
parent b46ef1945d
commit fa09e4cf7a
14 changed files with 376 additions and 183 deletions

View File

@ -39,12 +39,14 @@ namespace Ocelot.Configuration.Builder
private string _key;
private List<string> _delegatingHandlers;
private List<AddHeader> _addHeadersToDownstream;
private List<AddHeader> _addHeadersToUpstream;
public DownstreamReRouteBuilder()
{
_downstreamAddresses = new List<DownstreamHostAndPort>();
_delegatingHandlers = new List<string>();
_addHeadersToDownstream = new List<AddHeader>();
_addHeadersToUpstream = new List<AddHeader>();
}
public DownstreamReRouteBuilder WithDownstreamAddresses(List<DownstreamHostAndPort> downstreamAddresses)
@ -233,6 +235,12 @@ namespace Ocelot.Configuration.Builder
return this;
}
public DownstreamReRouteBuilder WithAddHeadersToUpstream(List<AddHeader> addHeadersToUpstream)
{
_addHeadersToUpstream = addHeadersToUpstream;
return this;
}
public DownstreamReRoute Build()
{
return new DownstreamReRoute(
@ -263,7 +271,8 @@ namespace Ocelot.Configuration.Builder
new PathTemplate(_downstreamPathTemplate),
_reRouteKey,
_delegatingHandlers,
_addHeadersToDownstream);
_addHeadersToDownstream,
_addHeadersToUpstream);
}
}
}

View File

@ -214,7 +214,8 @@ namespace Ocelot.Configuration.Creator
.WithDownstreamHeaderFindAndReplace(hAndRs.Downstream)
.WithUpstreamHost(fileReRoute.UpstreamHost)
.WithDelegatingHandlers(fileReRoute.DelegatingHandlers)
.WithAddHeadersToDownstream(hAndRs.AddHeadersToDownstream)
.WithAddHeadersToDownstream(hAndRs.AddHeadersToDownstream)
.WithAddHeadersToUpstream(hAndRs.AddHeadersToUpstream)
.Build();
return reRoute;

View File

@ -22,23 +22,31 @@ namespace Ocelot.Configuration.Creator
public HeaderTransformations Create(FileReRoute fileReRoute)
{
var upstream = new List<HeaderFindAndReplace>();
var addHeadersToUpstream = new List<AddHeader>();
foreach(var input in fileReRoute.UpstreamHeaderTransform)
{
var hAndr = Map(input);
if(!hAndr.IsError)
if (input.Value.Contains(","))
{
upstream.Add(hAndr.Data);
var hAndr = Map(input);
if (!hAndr.IsError)
{
upstream.Add(hAndr.Data);
}
else
{
_logger.LogWarning($"Unable to add UpstreamHeaderTransform {input.Key}: {input.Value}");
}
}
else
{
_logger.LogWarning($"Unable to add UpstreamHeaderTransform {input.Key}: {input.Value}");
addHeadersToUpstream.Add(new AddHeader(input.Key, input.Value));
}
}
var downstream = new List<HeaderFindAndReplace>();
var addHeadersToDownstream = new List<AddHeader>();
foreach(var input in fileReRoute.DownstreamHeaderTransform)
{
if(input.Value.Contains(","))
@ -59,7 +67,7 @@ namespace Ocelot.Configuration.Creator
}
}
return new HeaderTransformations(upstream, downstream, addHeadersToDownstream);
return new HeaderTransformations(upstream, downstream, addHeadersToDownstream, addHeadersToUpstream);
}
private Response<HeaderFindAndReplace> Map(KeyValuePair<string,string> input)

View File

@ -7,9 +7,11 @@ namespace Ocelot.Configuration.Creator
public HeaderTransformations(
List<HeaderFindAndReplace> upstream,
List<HeaderFindAndReplace> downstream,
List<AddHeader> addHeader)
List<AddHeader> addHeaderToDownstream,
List<AddHeader> addHeaderToUpstream)
{
AddHeadersToDownstream = addHeader;
AddHeadersToDownstream = addHeaderToDownstream;
AddHeadersToUpstream = addHeaderToUpstream;
Upstream = upstream;
Downstream = downstream;
}
@ -19,5 +21,6 @@ namespace Ocelot.Configuration.Creator
public List<HeaderFindAndReplace> Downstream { get; }
public List<AddHeader> AddHeadersToDownstream { get; }
public List<AddHeader> AddHeadersToUpstream { get; }
}
}

View File

@ -34,7 +34,8 @@ namespace Ocelot.Configuration
PathTemplate downstreamPathTemplate,
string reRouteKey,
List<string> delegatingHandlers,
List<AddHeader> addHeadersToDownstream)
List<AddHeader> addHeadersToDownstream,
List<AddHeader> addHeadersToUpstream)
{
AddHeadersToDownstream = addHeadersToDownstream;
DelegatingHandlers = delegatingHandlers;
@ -64,6 +65,7 @@ namespace Ocelot.Configuration
AuthenticationOptions = authenticationOptions;
DownstreamPathTemplate = downstreamPathTemplate;
ReRouteKey = reRouteKey;
AddHeadersToUpstream = addHeadersToUpstream;
}
public string Key { get; private set; }
@ -94,5 +96,6 @@ namespace Ocelot.Configuration
public string ReRouteKey { get; private set; }
public List<string> DelegatingHandlers {get;private set;}
public List<AddHeader> AddHeadersToDownstream {get;private set;}
public List<AddHeader> AddHeadersToUpstream { get; private set; }
}
}

View File

@ -4,6 +4,7 @@ using Ocelot.Configuration;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.Responses;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.Creator;
using Ocelot.Request.Middleware;
@ -41,5 +42,19 @@ namespace Ocelot.Headers
return new OkResponse();
}
public void SetHeadersOnDownstreamRequest(IEnumerable<AddHeader> headers, HttpContext context)
{
var requestHeader = context.Request.Headers;
foreach (var header in headers)
{
if (requestHeader.ContainsKey(header.Key))
{
requestHeader.Remove(header.Key);
}
requestHeader.Add(header.Key, header.Value);
}
}
}
}
}

View File

@ -1,4 +1,6 @@
namespace Ocelot.Headers
using Microsoft.AspNetCore.Http;
namespace Ocelot.Headers
{
using System.Collections.Generic;
using System.Net.Http;
@ -12,5 +14,6 @@
public interface IAddHeadersToRequest
{
Response SetHeadersOnDownstreamRequest(List<ClaimToThing> claimsToThings, IEnumerable<System.Security.Claims.Claim> claims, DownstreamRequest downstreamRequest);
void SetHeadersOnDownstreamRequest(IEnumerable<AddHeader> headers, HttpContext context);
}
}

View File

@ -9,16 +9,19 @@ namespace Ocelot.Headers.Middleware
private readonly OcelotRequestDelegate _next;
private readonly IHttpContextRequestHeaderReplacer _preReplacer;
private readonly IHttpResponseHeaderReplacer _postReplacer;
private readonly IAddHeadersToResponse _addHeaders;
private readonly IAddHeadersToResponse _addHeadersToResponse;
private readonly IAddHeadersToRequest _addHeadersToRequest;
public HttpHeadersTransformationMiddleware(OcelotRequestDelegate next,
IOcelotLoggerFactory loggerFactory,
IHttpContextRequestHeaderReplacer preReplacer,
IHttpResponseHeaderReplacer postReplacer,
IAddHeadersToResponse addHeaders)
IAddHeadersToResponse addHeadersToResponse,
IAddHeadersToRequest addHeadersToRequest)
:base(loggerFactory.CreateLogger<HttpHeadersTransformationMiddleware>())
{
_addHeaders = addHeaders;
_addHeadersToResponse = addHeadersToResponse;
_addHeadersToRequest = addHeadersToRequest;
_next = next;
_postReplacer = postReplacer;
_preReplacer = preReplacer;
@ -31,13 +34,15 @@ namespace Ocelot.Headers.Middleware
//todo - this should be on httprequestmessage not httpcontext?
_preReplacer.Replace(context.HttpContext, preFAndRs);
_addHeadersToRequest.SetHeadersOnDownstreamRequest(context.DownstreamReRoute.AddHeadersToUpstream, context.HttpContext);
await _next.Invoke(context);
var postFAndRs = context.DownstreamReRoute.DownstreamHeadersFindAndReplace;
_postReplacer.Replace(context.DownstreamResponse, postFAndRs, context.DownstreamRequest);
_addHeaders.Add(context.DownstreamReRoute.AddHeadersToDownstream, context.DownstreamResponse);
_addHeadersToResponse.Add(context.DownstreamReRoute.AddHeadersToDownstream, context.DownstreamResponse);
}
}
}