mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 20:10:50 +08:00 
			
		
		
		
	split DownstreamTemplate into DownstreamPathTemplate, DownstreamScheme, DownstreamHost and DownstreamPort in order to prepare for service discovery
This commit is contained in:
		@@ -1,11 +1,12 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Builder
 | 
			
		||||
{
 | 
			
		||||
    public class ReRouteBuilder
 | 
			
		||||
    {
 | 
			
		||||
        private string _downstreamTemplate;
 | 
			
		||||
        private string _downstreamPathTemplate;
 | 
			
		||||
        private string _upstreamTemplate;
 | 
			
		||||
        private string _upstreamTemplatePattern;
 | 
			
		||||
        private string _upstreamHttpMethod;
 | 
			
		||||
@@ -30,6 +31,7 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
        private string _serviceDiscoveryAddress;
 | 
			
		||||
        private string _downstreamScheme;
 | 
			
		||||
        private string _downstreamHost;
 | 
			
		||||
        private int _dsPort;
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder()
 | 
			
		||||
        {
 | 
			
		||||
@@ -72,9 +74,9 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithDownstreamTemplate(string input)
 | 
			
		||||
        public ReRouteBuilder WithDownstreamPathTemplate(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamTemplate = input;
 | 
			
		||||
            _downstreamPathTemplate = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -184,11 +186,17 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithDownstreamPort(int port)
 | 
			
		||||
        {
 | 
			
		||||
            _dsPort = port;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRoute Build()
 | 
			
		||||
        {
 | 
			
		||||
            Func<string> downstreamHostFunc = () => { return _downstreamHost; };
 | 
			
		||||
            Func<HostAndPort> downstreamHostFunc = () => new HostAndPort(_downstreamHost, _dsPort);
 | 
			
		||||
 | 
			
		||||
            return new ReRoute(_downstreamTemplate, _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, 
 | 
			
		||||
            return new ReRoute(new DownstreamPathTemplate(_downstreamPathTemplate), _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, 
 | 
			
		||||
                _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, 
 | 
			
		||||
                _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement, 
 | 
			
		||||
                _isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _serviceName, 
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ using Ocelot.Configuration.Parser;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Utilities;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
@@ -96,7 +97,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            Func<string> downstreamHostFunc = () => { return reRoute.DownstreamHost; };
 | 
			
		||||
            Func<HostAndPort> downstreamHostAndPortFunc = () => new HostAndPort(reRoute.DownstreamHost.Trim('/'), reRoute.DownstreamPort);
 | 
			
		||||
 | 
			
		||||
            if (isAuthenticated)
 | 
			
		||||
            {
 | 
			
		||||
@@ -109,22 +110,22 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                var claimsToClaims = GetAddThingsToRequest(reRoute.AddClaimsToRequest);
 | 
			
		||||
                var claimsToQueries = GetAddThingsToRequest(reRoute.AddQueriesToRequest);
 | 
			
		||||
 | 
			
		||||
                return new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate,
 | 
			
		||||
                return new ReRoute(new DownstreamPathTemplate(reRoute.DownstreamPathTemplate), reRoute.UpstreamTemplate,
 | 
			
		||||
                    reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
 | 
			
		||||
                    authOptionsForRoute, claimsToHeaders, claimsToClaims,
 | 
			
		||||
                    reRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostFunc, reRoute.DownstreamScheme);
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate, 
 | 
			
		||||
            return new ReRoute(new DownstreamPathTemplate(reRoute.DownstreamPathTemplate), reRoute.UpstreamTemplate, 
 | 
			
		||||
                reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, 
 | 
			
		||||
                null, new List<ClaimToThing>(), new List<ClaimToThing>(), 
 | 
			
		||||
                reRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostFunc, reRoute.DownstreamScheme);
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string BuildUpstreamTemplate(FileReRoute reRoute)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ namespace Ocelot.Configuration.File
 | 
			
		||||
            FileCacheOptions = new FileCacheOptions();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string DownstreamTemplate { get; set; }
 | 
			
		||||
        public string DownstreamPathTemplate { get; set; }
 | 
			
		||||
        public string UpstreamTemplate { get; set; }
 | 
			
		||||
        public string UpstreamHttpMethod { get; set; }
 | 
			
		||||
        public FileAuthenticationOptions AuthenticationOptions { get; set; }
 | 
			
		||||
@@ -28,5 +28,6 @@ namespace Ocelot.Configuration.File
 | 
			
		||||
        public string ServiceName { get; set; }
 | 
			
		||||
        public string DownstreamScheme {get;set;}
 | 
			
		||||
        public string DownstreamHost {get;set;}
 | 
			
		||||
        public int DownstreamPort { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +1,18 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class ReRoute
 | 
			
		||||
    {
 | 
			
		||||
        public ReRoute(string downstreamTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern, 
 | 
			
		||||
        public ReRoute(DownstreamPathTemplate downstreamPathTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern, 
 | 
			
		||||
            bool isAuthenticated, AuthenticationOptions authenticationOptions, List<ClaimToThing> configurationHeaderExtractorProperties, 
 | 
			
		||||
            List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries, 
 | 
			
		||||
            string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string serviceName, bool useServiceDiscovery,
 | 
			
		||||
            string serviceDiscoveryProvider, string serviceDiscoveryAddress, Func<string> downstreamHost, string downstreamScheme)
 | 
			
		||||
            string serviceDiscoveryProvider, string serviceDiscoveryAddress, Func<HostAndPort> downstreamHostAndPort, string downstreamScheme)
 | 
			
		||||
        {
 | 
			
		||||
            DownstreamTemplate = downstreamTemplate;
 | 
			
		||||
            DownstreamPathTemplate = downstreamPathTemplate;
 | 
			
		||||
            UpstreamTemplate = upstreamTemplate;
 | 
			
		||||
            UpstreamHttpMethod = upstreamHttpMethod;
 | 
			
		||||
            UpstreamTemplatePattern = upstreamTemplatePattern;
 | 
			
		||||
@@ -32,11 +33,11 @@ namespace Ocelot.Configuration
 | 
			
		||||
                UseServiceDiscovery = useServiceDiscovery;
 | 
			
		||||
                ServiceDiscoveryProvider = serviceDiscoveryProvider;
 | 
			
		||||
                ServiceDiscoveryAddress = serviceDiscoveryAddress;
 | 
			
		||||
                DownstreamHost = downstreamHost;
 | 
			
		||||
                DownstreamHostAndPort = downstreamHostAndPort;
 | 
			
		||||
                DownstreamScheme = downstreamScheme;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string DownstreamTemplate { get; private set; }
 | 
			
		||||
        public DownstreamPathTemplate DownstreamPathTemplate { get; private set; }
 | 
			
		||||
        public string UpstreamTemplate { get; private set; }
 | 
			
		||||
        public string UpstreamTemplatePattern { get; private set; }
 | 
			
		||||
        public string UpstreamHttpMethod { get; private set; }
 | 
			
		||||
@@ -54,7 +55,7 @@ namespace Ocelot.Configuration
 | 
			
		||||
        public bool UseServiceDiscovery { get; private set;}
 | 
			
		||||
        public string ServiceDiscoveryProvider { get; private set;}
 | 
			
		||||
        public string ServiceDiscoveryAddress { get; private set;}
 | 
			
		||||
        public Func<string> DownstreamHost {get;private set;}
 | 
			
		||||
        public Func<HostAndPort> DownstreamHostAndPort {get;private set;}
 | 
			
		||||
        public string DownstreamScheme {get;private set;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Validator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamPathTemplateAlreadyUsedError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamPathTemplateAlreadyUsedError(string message) : base(message, OcelotErrorCode.DownstreampathTemplateAlreadyUsedError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Validator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamPathTemplateContainsSchemeError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamPathTemplateContainsSchemeError(string message) 
 | 
			
		||||
            : base(message, OcelotErrorCode.DownstreamPathTemplateContainsSchemeError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Validator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamTemplateAlreadyUsedError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamTemplateAlreadyUsedError(string message) : base(message, OcelotErrorCode.DownstreamTemplateAlreadyUsedError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Validator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamTemplateContainsHostError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamTemplateContainsHostError(string message) 
 | 
			
		||||
            : base(message, OcelotErrorCode.DownstreamTemplateContainsHostError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Validator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamTemplateContainsSchemeError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamTemplateContainsSchemeError(string message) 
 | 
			
		||||
            : base(message, OcelotErrorCode.DownstreamTemplateContainsSchemeError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -26,7 +26,7 @@ namespace Ocelot.Configuration.Validator
 | 
			
		||||
                return new OkResponse<ConfigurationValidationResult>(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            result = CheckForReRoutesContainingDownstreamScheme(configuration);
 | 
			
		||||
            result = CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(configuration);
 | 
			
		||||
 | 
			
		||||
            if (result.IsError)
 | 
			
		||||
            {
 | 
			
		||||
@@ -70,25 +70,25 @@ namespace Ocelot.Configuration.Validator
 | 
			
		||||
            return Enum.TryParse(provider, true, out supportedProvider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ConfigurationValidationResult CheckForReRoutesContainingDownstreamScheme(FileConfiguration configuration)
 | 
			
		||||
        private ConfigurationValidationResult CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(FileConfiguration configuration)
 | 
			
		||||
        {   
 | 
			
		||||
            var errors = new List<Error>();
 | 
			
		||||
 | 
			
		||||
            foreach(var reRoute in configuration.ReRoutes)
 | 
			
		||||
            {
 | 
			
		||||
                if(reRoute.DownstreamTemplate.Contains("https://")
 | 
			
		||||
                || reRoute.DownstreamTemplate.Contains("http://"))
 | 
			
		||||
                if(reRoute.DownstreamPathTemplate.Contains("https://")
 | 
			
		||||
                || reRoute.DownstreamPathTemplate.Contains("http://"))
 | 
			
		||||
                {
 | 
			
		||||
                    errors.Add(new DownstreamTemplateContainsSchemeError($"{reRoute.DownstreamTemplate} contains scheme"));
 | 
			
		||||
                    errors.Add(new DownstreamPathTemplateContainsSchemeError($"{reRoute.DownstreamPathTemplate} contains scheme"));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(errors.Any())
 | 
			
		||||
            {
 | 
			
		||||
                return new ConfigurationValidationResult(false, errors);
 | 
			
		||||
                return new ConfigurationValidationResult(true, errors);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new ConfigurationValidationResult(true, errors);
 | 
			
		||||
            return new ConfigurationValidationResult(false, errors);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ConfigurationValidationResult CheckForDupliateReRoutes(FileConfiguration configuration)
 | 
			
		||||
@@ -105,7 +105,7 @@ namespace Ocelot.Configuration.Validator
 | 
			
		||||
                               .Where(x => x.Skip(1).Any());
 | 
			
		||||
 | 
			
		||||
            var errors = dupes
 | 
			
		||||
                .Select(d => new DownstreamTemplateAlreadyUsedError(string.Format("Duplicate DownstreamTemplate: {0}", d.Key.UpstreamTemplate)))
 | 
			
		||||
                .Select(d => new DownstreamPathTemplateAlreadyUsedError(string.Format("Duplicate DownstreamPath: {0}", d.Key.UpstreamTemplate)))
 | 
			
		||||
                .Cast<Error>()
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ using Ocelot.Configuration.Repository;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder.Finder;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
using Ocelot.DownstreamUrlCreator;
 | 
			
		||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
 | 
			
		||||
using Ocelot.Headers;
 | 
			
		||||
using Ocelot.Infrastructure.Claims.Parser;
 | 
			
		||||
@@ -59,6 +60,7 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            services.AddMvcCore().AddJsonFormatters();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddSingleton<IUrlBuilder, UrlBuilder>();
 | 
			
		||||
            services.AddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
 | 
			
		||||
            services.AddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>();
 | 
			
		||||
            services.AddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
 | 
			
		||||
@@ -69,7 +71,7 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            services.AddSingleton<IClaimsParser, ClaimsParser>();
 | 
			
		||||
            services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
 | 
			
		||||
            services.AddSingleton<IUrlPathPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
 | 
			
		||||
            services.AddSingleton<IDownstreamUrlPathPlaceholderReplacer, DownstreamUrlPathPlaceholderReplacer>();
 | 
			
		||||
            services.AddSingleton<IDownstreamPathPlaceholderReplacer, DownstreamTemplatePathPlaceholderReplacer>();
 | 
			
		||||
            services.AddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder.Finder.DownstreamRouteFinder>();
 | 
			
		||||
            services.AddSingleton<IHttpRequester, HttpClientHttpRequester>();
 | 
			
		||||
            services.AddSingleton<IHttpResponder, HttpContextResponder>();
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamTemplate}", downstreamRoute.Data.ReRoute.DownstreamTemplate);
 | 
			
		||||
            _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath}", downstreamRoute.Data.ReRoute.DownstreamPathTemplate);
 | 
			
		||||
 | 
			
		||||
            SetDownstreamRouteForThisRequest(downstreamRoute.Data);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamHostNullOrEmptyError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamHostNullOrEmptyError()
 | 
			
		||||
            : base("downstream host was null or empty", OcelotErrorCode.DownstreamHostNullOrEmptyError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamPathNullOrEmptyError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamPathNullOrEmptyError() 
 | 
			
		||||
            : base("downstream path was null or empty", OcelotErrorCode.DownstreamPathNullOrEmptyError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamSchemeNullOrEmptyError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamSchemeNullOrEmptyError()
 | 
			
		||||
            : base("downstream scheme was null or empty", OcelotErrorCode.DownstreamSchemeNullOrEmptyError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/Ocelot/DownstreamUrlCreator/IUrlBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Ocelot/DownstreamUrlCreator/IUrlBuilder.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator
 | 
			
		||||
{
 | 
			
		||||
    public interface IUrlBuilder
 | 
			
		||||
    {
 | 
			
		||||
        Response<DownstreamUrl> Build(string downstreamPath, string downstreamScheme, HostAndPort downstreamHostAndPort);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
@@ -11,17 +12,20 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
 | 
			
		||||
    public class DownstreamUrlCreatorMiddleware : OcelotMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RequestDelegate _next;
 | 
			
		||||
        private readonly IDownstreamUrlPathPlaceholderReplacer _urlReplacer;
 | 
			
		||||
        private readonly IDownstreamPathPlaceholderReplacer _replacer;
 | 
			
		||||
        private readonly IOcelotLogger _logger;
 | 
			
		||||
        private readonly IUrlBuilder _urlBuilder;
 | 
			
		||||
 | 
			
		||||
        public DownstreamUrlCreatorMiddleware(RequestDelegate next,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory,
 | 
			
		||||
            IDownstreamUrlPathPlaceholderReplacer urlReplacer,
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository)
 | 
			
		||||
            IDownstreamPathPlaceholderReplacer replacer,
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository, 
 | 
			
		||||
            IUrlBuilder urlBuilder)
 | 
			
		||||
            :base(requestScopedDataRepository)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
            _urlReplacer = urlReplacer;
 | 
			
		||||
            _replacer = replacer;
 | 
			
		||||
            _urlBuilder = urlBuilder;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<DownstreamUrlCreatorMiddleware>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -29,19 +33,34 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
 | 
			
		||||
        {
 | 
			
		||||
            _logger.LogDebug("started calling downstream url creator middleware");
 | 
			
		||||
 | 
			
		||||
            var downstreamUrl = _urlReplacer.Replace(DownstreamRoute.ReRoute.DownstreamTemplate, DownstreamRoute.TemplatePlaceholderNameAndValues);
 | 
			
		||||
            var dsPath = _replacer
 | 
			
		||||
                .Replace(DownstreamRoute.ReRoute.DownstreamPathTemplate, DownstreamRoute.TemplatePlaceholderNameAndValues);
 | 
			
		||||
 | 
			
		||||
            if (downstreamUrl.IsError)
 | 
			
		||||
            if (dsPath.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogDebug("IDownstreamUrlPathPlaceholderReplacer returned an error, setting pipeline error");
 | 
			
		||||
                _logger.LogDebug("IDownstreamPathPlaceholderReplacer returned an error, setting pipeline error");
 | 
			
		||||
 | 
			
		||||
                SetPipelineError(downstreamUrl.Errors);
 | 
			
		||||
                SetPipelineError(dsPath.Errors);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("downstream url is {downstreamUrl.Data.Value}", downstreamUrl.Data.Value);
 | 
			
		||||
            var dsScheme = DownstreamRoute.ReRoute.DownstreamScheme;
 | 
			
		||||
 | 
			
		||||
            SetDownstreamUrlForThisRequest(downstreamUrl.Data.Value);
 | 
			
		||||
            var dsHostAndPort = DownstreamRoute.ReRoute.DownstreamHostAndPort();
 | 
			
		||||
 | 
			
		||||
            var dsUrl = _urlBuilder.Build(dsPath.Data.Value, dsScheme, dsHostAndPort);
 | 
			
		||||
 | 
			
		||||
            if (dsUrl.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogDebug("IUrlBuilder returned an error, setting pipeline error");
 | 
			
		||||
 | 
			
		||||
                SetPipelineError(dsUrl.Errors);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("downstream url is {downstreamUrl.Data.Value}", dsUrl.Data.Value);
 | 
			
		||||
 | 
			
		||||
            SetDownstreamUrlForThisRequest(dsUrl.Data.Value);
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("calling next middleware");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								src/Ocelot/DownstreamUrlCreator/UrlBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/Ocelot/DownstreamUrlCreator/UrlBuilder.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator
 | 
			
		||||
{
 | 
			
		||||
    public class UrlBuilder : IUrlBuilder
 | 
			
		||||
    {
 | 
			
		||||
        public Response<DownstreamUrl> Build(string downstreamPath, string downstreamScheme, HostAndPort downstreamHostAndPort)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(downstreamPath))
 | 
			
		||||
            {
 | 
			
		||||
                return new ErrorResponse<DownstreamUrl>(new List<Error> {new DownstreamPathNullOrEmptyError()});
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrEmpty(downstreamScheme))
 | 
			
		||||
            {
 | 
			
		||||
                return new ErrorResponse<DownstreamUrl>(new List<Error> { new DownstreamSchemeNullOrEmptyError() });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrEmpty(downstreamHostAndPort.DownstreamHost))
 | 
			
		||||
            {
 | 
			
		||||
                return new ErrorResponse<DownstreamUrl>(new List<Error> { new DownstreamHostNullOrEmptyError() });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var builder = new UriBuilder
 | 
			
		||||
            {
 | 
			
		||||
                Host = downstreamHostAndPort.DownstreamHost,
 | 
			
		||||
                Path = downstreamPath,
 | 
			
		||||
                Scheme = downstreamScheme
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            if (downstreamHostAndPort.DownstreamPort > 0)
 | 
			
		||||
            {
 | 
			
		||||
                builder.Port = downstreamHostAndPort.DownstreamPort;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            var url = builder.Uri.ToString();
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<DownstreamUrl>(new DownstreamUrl(url));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +1,25 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamUrlPathPlaceholderReplacer : IDownstreamUrlPathPlaceholderReplacer
 | 
			
		||||
    public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
 | 
			
		||||
    {
 | 
			
		||||
        public Response<DownstreamUrl> Replace(string downstreamTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
 | 
			
		||||
        public Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamUrl = new StringBuilder();
 | 
			
		||||
            var downstreamPath = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
            upstreamUrl.Append(downstreamTemplate);
 | 
			
		||||
            downstreamPath.Append(downstreamPathTemplate.Value);
 | 
			
		||||
 | 
			
		||||
            foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
 | 
			
		||||
            {
 | 
			
		||||
                upstreamUrl.Replace(placeholderVariableAndValue.TemplateVariableName, placeholderVariableAndValue.TemplateVariableValue);
 | 
			
		||||
                downstreamPath.Replace(placeholderVariableAndValue.TemplateVariableName, placeholderVariableAndValue.TemplateVariableValue);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<DownstreamUrl>(new DownstreamUrl(upstreamUrl.ToString()));
 | 
			
		||||
            return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
{
 | 
			
		||||
    public interface IDownstreamUrlPathPlaceholderReplacer
 | 
			
		||||
    public interface IDownstreamPathPlaceholderReplacer
 | 
			
		||||
    {
 | 
			
		||||
        Response<DownstreamUrl> Replace(string downstreamTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues);   
 | 
			
		||||
        Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues);   
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    {
 | 
			
		||||
        UnauthenticatedError, 
 | 
			
		||||
        UnknownError,
 | 
			
		||||
        DownstreamTemplateAlreadyUsedError,
 | 
			
		||||
        DownstreampathTemplateAlreadyUsedError,
 | 
			
		||||
        UnableToFindDownstreamRouteError,
 | 
			
		||||
        CannotAddDataError,
 | 
			
		||||
        CannotFindDataError,
 | 
			
		||||
@@ -18,7 +18,9 @@
 | 
			
		||||
        UnauthorizedError,
 | 
			
		||||
        ClaimValueNotAuthorisedError,
 | 
			
		||||
        UserDoesNotHaveClaimError,
 | 
			
		||||
        DownstreamTemplateContainsSchemeError,
 | 
			
		||||
        DownstreamTemplateContainsHostError
 | 
			
		||||
        DownstreamPathTemplateContainsSchemeError,
 | 
			
		||||
        DownstreamPathNullOrEmptyError,
 | 
			
		||||
        DownstreamSchemeNullOrEmptyError,
 | 
			
		||||
        DownstreamHostNullOrEmptyError
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/Ocelot/Values/DownstreamPath.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Ocelot/Values/DownstreamPath.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
namespace Ocelot.Values
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamPath
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamPath(string value)
 | 
			
		||||
        {
 | 
			
		||||
            Value = value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Value { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/Ocelot/Values/DownstreamPathTemplate.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Ocelot/Values/DownstreamPathTemplate.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
namespace Ocelot.Values
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamPathTemplate
 | 
			
		||||
    {
 | 
			
		||||
        public DownstreamPathTemplate(string value)
 | 
			
		||||
        {
 | 
			
		||||
            Value = value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Value { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
namespace Ocelot.Values
 | 
			
		||||
{
 | 
			
		||||
    public class DownstreamUrl
 | 
			
		||||
    {
 | 
			
		||||
@@ -9,4 +9,4 @@
 | 
			
		||||
 | 
			
		||||
        public string Value { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/Ocelot/Values/HostAndPort.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/Ocelot/Values/HostAndPort.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
namespace Ocelot.Values
 | 
			
		||||
{
 | 
			
		||||
    public class HostAndPort
 | 
			
		||||
    {
 | 
			
		||||
        public HostAndPort(string downstreamHost, int downstreamPort)
 | 
			
		||||
        {
 | 
			
		||||
            DownstreamHost = downstreamHost;
 | 
			
		||||
            DownstreamPort = downstreamPort;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string DownstreamHost { get; private set; }
 | 
			
		||||
        public int DownstreamPort { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user