mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 20:10:50 +08:00 
			
		
		
		
	Support adding custom plaintext headers to downstream requests (#314)
This commit is contained in:
		
				
					committed by
					
						
						Tom Pallister
					
				
			
			
				
	
			
			
			
						parent
						
							b46ef1945d
						
					
				
				
					commit
					fa09e4cf7a
				
			@@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user