mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 15:30:49 +08:00 
			
		
		
		
	Changed routing to support a catch all style (#187)
* Changed routing to support a catch all style * refactoring placeholder tuff * implemented simple priority in the routing
This commit is contained in:
		@@ -2,6 +2,7 @@
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Ocelot.Configuration.Creator;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Builder
 | 
			
		||||
{
 | 
			
		||||
@@ -11,7 +12,7 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
        private string _loadBalancerKey;
 | 
			
		||||
        private string _downstreamPathTemplate;
 | 
			
		||||
        private string _upstreamTemplate;
 | 
			
		||||
        private string _upstreamTemplatePattern;
 | 
			
		||||
        private UpstreamPathTemplate _upstreamTemplatePattern;
 | 
			
		||||
        private List<HttpMethod> _upstreamHttpMethod;
 | 
			
		||||
        private bool _isAuthenticated;
 | 
			
		||||
        private List<ClaimToThing> _configHeaderExtractorProperties;
 | 
			
		||||
@@ -65,7 +66,7 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithUpstreamTemplatePattern(string input)
 | 
			
		||||
        public ReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamTemplatePattern = input;
 | 
			
		||||
            return this;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,10 @@
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
    public interface IUpstreamTemplatePatternCreator
 | 
			
		||||
    {
 | 
			
		||||
        string Create(FileReRoute reRoute);
 | 
			
		||||
        UpstreamPathTemplate Create(FileReRoute reRoute);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
@@ -11,7 +12,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
        private const string RegExForwardSlashOnly = "^/$";
 | 
			
		||||
        private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
 | 
			
		||||
 | 
			
		||||
        public string Create(FileReRoute reRoute)
 | 
			
		||||
        public UpstreamPathTemplate Create(FileReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamTemplate = reRoute.UpstreamPathTemplate;
 | 
			
		||||
 | 
			
		||||
@@ -26,9 +27,10 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                    var placeHolderName = upstreamTemplate.Substring(i, difference);
 | 
			
		||||
                    placeholders.Add(placeHolderName);
 | 
			
		||||
 | 
			
		||||
                    //hack to handle /{url} case
 | 
			
		||||
                    if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
 | 
			
		||||
                    {
 | 
			
		||||
                        return RegExForwardSlashAndOnePlaceHolder;
 | 
			
		||||
                        return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -40,7 +42,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
 | 
			
		||||
            if (upstreamTemplate == "/")
 | 
			
		||||
            {
 | 
			
		||||
                return RegExForwardSlashOnly;
 | 
			
		||||
                return new UpstreamPathTemplate(RegExForwardSlashOnly, 1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(upstreamTemplate.EndsWith("/"))
 | 
			
		||||
@@ -52,7 +54,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                ? $"^{upstreamTemplate}{RegExMatchEndString}" 
 | 
			
		||||
                : $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
 | 
			
		||||
 | 
			
		||||
            return route;
 | 
			
		||||
            return new UpstreamPathTemplate(route, 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.Configuration.Creator;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
@@ -9,7 +10,7 @@ namespace Ocelot.Configuration
 | 
			
		||||
        public ReRoute(PathTemplate downstreamPathTemplate, 
 | 
			
		||||
            PathTemplate upstreamPathTemplate, 
 | 
			
		||||
            List<HttpMethod> upstreamHttpMethod, 
 | 
			
		||||
            string upstreamTemplatePattern, 
 | 
			
		||||
            UpstreamPathTemplate upstreamTemplatePattern, 
 | 
			
		||||
            bool isAuthenticated, 
 | 
			
		||||
            AuthenticationOptions authenticationOptions, 
 | 
			
		||||
            List<ClaimToThing> claimsToHeaders, 
 | 
			
		||||
@@ -67,7 +68,7 @@ namespace Ocelot.Configuration
 | 
			
		||||
        public string ReRouteKey {get;private set;}
 | 
			
		||||
        public PathTemplate DownstreamPathTemplate { get; private set; }
 | 
			
		||||
        public PathTemplate UpstreamPathTemplate { get; private set; }
 | 
			
		||||
        public string UpstreamTemplatePattern { get; private set; }
 | 
			
		||||
        public UpstreamPathTemplate UpstreamTemplatePattern { get; private set; }
 | 
			
		||||
        public List<HttpMethod> UpstreamHttpMethod { get; private set; }
 | 
			
		||||
        public bool IsAuthenticated { get; private set; }
 | 
			
		||||
        public bool IsAuthorised { get; private set; }
 | 
			
		||||
 
 | 
			
		||||
@@ -108,7 +108,7 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            _services.TryAddSingleton<IAddQueriesToRequest, AddQueriesToRequest>();
 | 
			
		||||
            _services.TryAddSingleton<IClaimsParser, ClaimsParser>();
 | 
			
		||||
            _services.TryAddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
 | 
			
		||||
            _services.TryAddSingleton<IUrlPathPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
 | 
			
		||||
            _services.TryAddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
 | 
			
		||||
            _services.TryAddSingleton<IDownstreamPathPlaceholderReplacer, DownstreamTemplatePathPlaceholderReplacer>();
 | 
			
		||||
            _services.TryAddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder.Finder.DownstreamRouteFinder>();
 | 
			
		||||
            _services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>();
 | 
			
		||||
 
 | 
			
		||||
@@ -6,12 +6,12 @@ namespace Ocelot.DownstreamRouteFinder
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamRoute
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamRoute(List<UrlPathPlaceholderNameAndValue> templatePlaceholderNameAndValues, ReRoute reRoute)
 | 
			
		||||
        public DownstreamRoute(List<PlaceholderNameAndValue> templatePlaceholderNameAndValues, ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            TemplatePlaceholderNameAndValues = templatePlaceholderNameAndValues;
 | 
			
		||||
            ReRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
        public List<UrlPathPlaceholderNameAndValue> TemplatePlaceholderNameAndValues { get; private set; }
 | 
			
		||||
        public List<PlaceholderNameAndValue> TemplatePlaceholderNameAndValues { get; private set; }
 | 
			
		||||
        public ReRoute ReRoute { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -13,34 +13,30 @@ namespace Ocelot.DownstreamRouteFinder.Finder
 | 
			
		||||
    public class DownstreamRouteFinder : IDownstreamRouteFinder
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
 | 
			
		||||
        private readonly IUrlPathPlaceholderNameAndValueFinder _urlPathPlaceholderNameAndValueFinder;
 | 
			
		||||
        private readonly IPlaceholderNameAndValueFinder __placeholderNameAndValueFinder;
 | 
			
		||||
 | 
			
		||||
        public DownstreamRouteFinder(IUrlPathToUrlTemplateMatcher urlMatcher, IUrlPathPlaceholderNameAndValueFinder urlPathPlaceholderNameAndValueFinder)
 | 
			
		||||
        public DownstreamRouteFinder(IUrlPathToUrlTemplateMatcher urlMatcher, IPlaceholderNameAndValueFinder urlPathPlaceholderNameAndValueFinder)
 | 
			
		||||
        {
 | 
			
		||||
            _urlMatcher = urlMatcher;
 | 
			
		||||
            _urlPathPlaceholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
 | 
			
		||||
            __placeholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod, IOcelotConfiguration configuration)
 | 
			
		||||
        public Response<DownstreamRoute> FindDownstreamRoute(string path, string httpMethod, IOcelotConfiguration configuration)
 | 
			
		||||
        {
 | 
			
		||||
            var applicableReRoutes = configuration.ReRoutes.Where(r => r.UpstreamHttpMethod.Count == 0 || r.UpstreamHttpMethod.Select(x => x.Method.ToLower()).Contains(upstreamHttpMethod.ToLower()));
 | 
			
		||||
            var applicableReRoutes = configuration.ReRoutes.Where(r => r.UpstreamHttpMethod.Count == 0 || r.UpstreamHttpMethod.Select(x => x.Method.ToLower()).Contains(httpMethod.ToLower())).OrderByDescending(x => x.UpstreamTemplatePattern.Priority);
 | 
			
		||||
 | 
			
		||||
            foreach (var reRoute in applicableReRoutes)
 | 
			
		||||
            {
 | 
			
		||||
                if (upstreamUrlPath == reRoute.UpstreamTemplatePattern)
 | 
			
		||||
                if (path == reRoute.UpstreamTemplatePattern.Template)
 | 
			
		||||
                {
 | 
			
		||||
                    var templateVariableNameAndValues = _urlPathPlaceholderNameAndValueFinder.Find(upstreamUrlPath, reRoute.UpstreamPathTemplate.Value);
 | 
			
		||||
 | 
			
		||||
                    return new OkResponse<DownstreamRoute>(new DownstreamRoute(templateVariableNameAndValues.Data, reRoute));
 | 
			
		||||
                    return GetPlaceholderNamesAndValues(path, reRoute);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var urlMatch = _urlMatcher.Match(upstreamUrlPath, reRoute.UpstreamTemplatePattern);
 | 
			
		||||
                var urlMatch = _urlMatcher.Match(path, reRoute.UpstreamTemplatePattern.Template);
 | 
			
		||||
 | 
			
		||||
                if (urlMatch.Data.Match)
 | 
			
		||||
                {
 | 
			
		||||
                    var templateVariableNameAndValues = _urlPathPlaceholderNameAndValueFinder.Find(upstreamUrlPath, reRoute.UpstreamPathTemplate.Value);
 | 
			
		||||
 | 
			
		||||
                    return new OkResponse<DownstreamRoute>(new DownstreamRoute(templateVariableNameAndValues.Data, reRoute));
 | 
			
		||||
                    return GetPlaceholderNamesAndValues(path, reRoute);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        
 | 
			
		||||
@@ -49,5 +45,12 @@ namespace Ocelot.DownstreamRouteFinder.Finder
 | 
			
		||||
                new UnableToFindDownstreamRouteError()
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private OkResponse<DownstreamRoute> GetPlaceholderNamesAndValues(string path, ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            var templatePlaceholderNameAndValues = __placeholderNameAndValueFinder.Find(path, reRoute.UpstreamPathTemplate.Value);
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<DownstreamRoute>(new DownstreamRoute(templatePlaceholderNameAndValues.Data, reRoute));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,8 +3,8 @@ using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
{
 | 
			
		||||
    public interface IUrlPathPlaceholderNameAndValueFinder
 | 
			
		||||
    public interface IPlaceholderNameAndValueFinder
 | 
			
		||||
    {
 | 
			
		||||
        Response<List<UrlPathPlaceholderNameAndValue>> Find(string upstreamUrlPath, string upstreamUrlPathTemplate);
 | 
			
		||||
        Response<List<PlaceholderNameAndValue>> Find(string path, string pathTemplate);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
namespace Ocelot.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
{
 | 
			
		||||
    public class UrlPathPlaceholderNameAndValue
 | 
			
		||||
    public class PlaceholderNameAndValue
 | 
			
		||||
    {
 | 
			
		||||
        public UrlPathPlaceholderNameAndValue(string templateVariableName, string templateVariableValue)
 | 
			
		||||
        public PlaceholderNameAndValue(string name, string value)
 | 
			
		||||
        {
 | 
			
		||||
            TemplateVariableName = templateVariableName;
 | 
			
		||||
            TemplateVariableValue = templateVariableValue;
 | 
			
		||||
            Name = name;
 | 
			
		||||
            Value = value;
 | 
			
		||||
        }
 | 
			
		||||
        public string TemplateVariableName {get;private set;}
 | 
			
		||||
        public string TemplateVariableValue {get;private set;}
 | 
			
		||||
        public string Name {get;private set;}
 | 
			
		||||
        public string Value {get;private set;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,44 +3,72 @@ using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
{
 | 
			
		||||
    public class UrlPathPlaceholderNameAndValueFinder : IUrlPathPlaceholderNameAndValueFinder
 | 
			
		||||
    public class UrlPathPlaceholderNameAndValueFinder : IPlaceholderNameAndValueFinder
 | 
			
		||||
    {
 | 
			
		||||
        public Response<List<UrlPathPlaceholderNameAndValue>> Find(string upstreamUrlPath, string upstreamUrlPathTemplate)
 | 
			
		||||
        public Response<List<PlaceholderNameAndValue>> Find(string path, string pathTemplate)
 | 
			
		||||
        {
 | 
			
		||||
            var templateKeysAndValues = new List<UrlPathPlaceholderNameAndValue>();
 | 
			
		||||
            var placeHolderNameAndValues = new List<PlaceholderNameAndValue>();
 | 
			
		||||
 | 
			
		||||
            int counterForUrl = 0;
 | 
			
		||||
            int counterForPath = 0;
 | 
			
		||||
         
 | 
			
		||||
            for (int counterForTemplate = 0; counterForTemplate < upstreamUrlPathTemplate.Length; counterForTemplate++)
 | 
			
		||||
            for (int counterForTemplate = 0; counterForTemplate < pathTemplate.Length; counterForTemplate++)
 | 
			
		||||
            {
 | 
			
		||||
                if ((upstreamUrlPath.Length > counterForUrl) && CharactersDontMatch(upstreamUrlPathTemplate[counterForTemplate], upstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,upstreamUrlPath.Length))
 | 
			
		||||
                if ((path.Length > counterForPath) && CharactersDontMatch(pathTemplate[counterForTemplate], path[counterForPath]) && ContinueScanningUrl(counterForPath,path.Length))
 | 
			
		||||
                {
 | 
			
		||||
                    if (IsPlaceholder(upstreamUrlPathTemplate[counterForTemplate]))
 | 
			
		||||
                    if (IsPlaceholder(pathTemplate[counterForTemplate]))
 | 
			
		||||
                    {
 | 
			
		||||
                        var variableName = GetPlaceholderVariableName(upstreamUrlPathTemplate, counterForTemplate);
 | 
			
		||||
                        var placeholderName = GetPlaceholderName(pathTemplate, counterForTemplate);
 | 
			
		||||
 | 
			
		||||
                        var variableValue = GetPlaceholderVariableValue(upstreamUrlPathTemplate, variableName, upstreamUrlPath, counterForUrl);
 | 
			
		||||
                        var placeholderValue = GetPlaceholderValue(pathTemplate, placeholderName, path, counterForPath);
 | 
			
		||||
 | 
			
		||||
                        var templateVariableNameAndValue = new UrlPathPlaceholderNameAndValue(variableName, variableValue);
 | 
			
		||||
                        placeHolderNameAndValues.Add(new PlaceholderNameAndValue(placeholderName, placeholderValue));
 | 
			
		||||
 | 
			
		||||
                        templateKeysAndValues.Add(templateVariableNameAndValue);
 | 
			
		||||
                        counterForTemplate = GetNextCounterPosition(pathTemplate, counterForTemplate, '}');
 | 
			
		||||
 | 
			
		||||
                        counterForTemplate = GetNextCounterPosition(upstreamUrlPathTemplate, counterForTemplate, '}');
 | 
			
		||||
 | 
			
		||||
                        counterForUrl = GetNextCounterPosition(upstreamUrlPath, counterForUrl, '/');
 | 
			
		||||
                        counterForPath = GetNextCounterPosition(path, counterForPath, '/');
 | 
			
		||||
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return new OkResponse<List<UrlPathPlaceholderNameAndValue>>(templateKeysAndValues);
 | 
			
		||||
                    return new OkResponse<List<PlaceholderNameAndValue>>(placeHolderNameAndValues);
 | 
			
		||||
                }
 | 
			
		||||
                counterForUrl++;
 | 
			
		||||
                else if(IsCatchAll(path, counterForPath, pathTemplate))
 | 
			
		||||
                {
 | 
			
		||||
                    var endOfPlaceholder = GetNextCounterPosition(pathTemplate, counterForTemplate, '}');
 | 
			
		||||
 | 
			
		||||
                    var placeholderName = GetPlaceholderName(pathTemplate, 1);
 | 
			
		||||
 | 
			
		||||
                    if(NothingAfterFirstForwardSlash(path))
 | 
			
		||||
                    {
 | 
			
		||||
                        placeHolderNameAndValues.Add(new PlaceholderNameAndValue(placeholderName, ""));
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        var placeholderValue = GetPlaceholderValue(pathTemplate, placeholderName, path, counterForPath + 1);
 | 
			
		||||
                        placeHolderNameAndValues.Add(new PlaceholderNameAndValue(placeholderName, placeholderValue));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    counterForTemplate = endOfPlaceholder;
 | 
			
		||||
                }
 | 
			
		||||
                counterForPath++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<List<UrlPathPlaceholderNameAndValue>>(templateKeysAndValues);
 | 
			
		||||
            return new OkResponse<List<PlaceholderNameAndValue>>(placeHolderNameAndValues);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string GetPlaceholderVariableValue(string urlPathTemplate, string variableName, string urlPath, int counterForUrl)
 | 
			
		||||
        private bool IsCatchAll(string path, int counterForPath, string pathTemplate)
 | 
			
		||||
        {
 | 
			
		||||
            return string.IsNullOrEmpty(path) || (path.Length > counterForPath && path[counterForPath] == '/') && pathTemplate.Length > 1 
 | 
			
		||||
                     && pathTemplate.Substring(0, 2) == "/{" 
 | 
			
		||||
                     && pathTemplate.IndexOf('}') == pathTemplate.Length - 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool NothingAfterFirstForwardSlash(string path)
 | 
			
		||||
        {
 | 
			
		||||
            return path.Length == 1 || path.Length == 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string GetPlaceholderValue(string urlPathTemplate, string variableName, string urlPath, int counterForUrl)
 | 
			
		||||
        {
 | 
			
		||||
            var positionOfNextSlash = urlPath.IndexOf('/', counterForUrl);
 | 
			
		||||
 | 
			
		||||
@@ -54,7 +82,7 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
            return variableValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string GetPlaceholderVariableName(string urlPathTemplate, int counterForTemplate)
 | 
			
		||||
        private string GetPlaceholderName(string urlPathTemplate, int counterForTemplate)
 | 
			
		||||
        {
 | 
			
		||||
            var postitionOfPlaceHolderClosingBracket = urlPathTemplate.IndexOf('}', counterForTemplate) + 1;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
 | 
			
		||||
    {
 | 
			
		||||
        public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
 | 
			
		||||
        public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamPath = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
@@ -16,7 +16,7 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
 | 
			
		||||
            foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
 | 
			
		||||
            {
 | 
			
		||||
                downstreamPath.Replace(placeholderVariableAndValue.TemplateVariableName, placeholderVariableAndValue.TemplateVariableValue);
 | 
			
		||||
                downstreamPath.Replace(placeholderVariableAndValue.Name, placeholderVariableAndValue.Value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString()));
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,6 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
{
 | 
			
		||||
    public interface IDownstreamPathPlaceholderReplacer
 | 
			
		||||
    {
 | 
			
		||||
        Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues);   
 | 
			
		||||
        Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues);   
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/Ocelot/Values/UpstreamPathTemplate.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/Ocelot/Values/UpstreamPathTemplate.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
namespace Ocelot.Values
 | 
			
		||||
{
 | 
			
		||||
    public class UpstreamPathTemplate
 | 
			
		||||
    {
 | 
			
		||||
        public UpstreamPathTemplate(string template, int priority)
 | 
			
		||||
        {
 | 
			
		||||
            Template = template;
 | 
			
		||||
            Priority = priority;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Template {get;}
 | 
			
		||||
        public int Priority {get;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user