mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 15:50:49 +08:00 
			
		
		
		
	merged develop
This commit is contained in:
		
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -236,3 +236,9 @@ _Pvt_Extensions
 | 
				
			|||||||
# FAKE - F# Make
 | 
					# FAKE - F# Make
 | 
				
			||||||
.fake/
 | 
					.fake/
 | 
				
			||||||
tools/
 | 
					tools/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# MacOS
 | 
				
			||||||
 | 
					.DS_Store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ocelot acceptance test config
 | 
				
			||||||
 | 
					test/Ocelot.AcceptanceTests/configuration.json
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								src/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/Ocelot/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/Ocelot/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/Ocelot/Authentication/Handler/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/Ocelot/Authentication/Handler/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -28,6 +28,8 @@ namespace Ocelot.Configuration.Builder
 | 
				
			|||||||
        private int _downstreamPort;
 | 
					        private int _downstreamPort;
 | 
				
			||||||
        private string _loadBalancer;
 | 
					        private string _loadBalancer;
 | 
				
			||||||
        private ServiceProviderConfiguraion _serviceProviderConfiguraion;
 | 
					        private ServiceProviderConfiguraion _serviceProviderConfiguraion;
 | 
				
			||||||
 | 
					        private bool _useQos;
 | 
				
			||||||
 | 
					        private QoSOptions _qosOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ReRouteBuilder WithLoadBalancer(string loadBalancer)
 | 
					        public ReRouteBuilder WithLoadBalancer(string loadBalancer)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -135,6 +137,19 @@ namespace Ocelot.Configuration.Builder
 | 
				
			|||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public ReRouteBuilder WithIsQos(bool input)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _useQos = input;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public ReRouteBuilder WithQosOptions(QoSOptions input)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _qosOptions = input;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ReRouteBuilder WithLoadBalancerKey(string loadBalancerKey)
 | 
					        public ReRouteBuilder WithLoadBalancerKey(string loadBalancerKey)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _loadBalancerKey = loadBalancerKey;
 | 
					            _loadBalancerKey = loadBalancerKey;
 | 
				
			||||||
@@ -175,7 +190,9 @@ namespace Ocelot.Configuration.Builder
 | 
				
			|||||||
                _downstreamHost, 
 | 
					                _downstreamHost, 
 | 
				
			||||||
                _downstreamPort, 
 | 
					                _downstreamPort, 
 | 
				
			||||||
                _loadBalancerKey, 
 | 
					                _loadBalancerKey, 
 | 
				
			||||||
                _serviceProviderConfiguraion);
 | 
					                _serviceProviderConfiguraion, 
 | 
				
			||||||
 | 
					                _useQos, 
 | 
				
			||||||
 | 
					                _qosOptions);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,6 +95,7 @@ namespace Ocelot.Configuration.Creator
 | 
				
			|||||||
            var loadBalancerKey = BuildLoadBalancerKey(fileReRoute);
 | 
					            var loadBalancerKey = BuildLoadBalancerKey(fileReRoute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var upstreamTemplatePattern = BuildUpstreamTemplate(fileReRoute);
 | 
					            var upstreamTemplatePattern = BuildUpstreamTemplate(fileReRoute);
 | 
				
			||||||
 | 
					            var isQos = fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking > 0 && fileReRoute.QoSOptions.TimeoutValue >0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var serviceProviderConfiguration = BuildServiceProviderConfiguration(fileReRoute, globalConfiguration);
 | 
					            var serviceProviderConfiguration = BuildServiceProviderConfiguration(fileReRoute, globalConfiguration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -102,6 +103,7 @@ namespace Ocelot.Configuration.Creator
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var claimsToHeaders = BuildAddThingsToRequest(fileReRoute.AddHeadersToRequest);
 | 
					            var claimsToHeaders = BuildAddThingsToRequest(fileReRoute.AddHeadersToRequest);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var claimsToClaims = BuildAddThingsToRequest(fileReRoute.AddClaimsToRequest);
 | 
					            var claimsToClaims = BuildAddThingsToRequest(fileReRoute.AddClaimsToRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var claimsToQueries = BuildAddThingsToRequest(fileReRoute.AddQueriesToRequest);
 | 
					            var claimsToQueries = BuildAddThingsToRequest(fileReRoute.AddQueriesToRequest);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								src/Ocelot/Configuration/File/FileQoSOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/Ocelot/Configuration/File/FileQoSOptions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Ocelot.Configuration.File
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class FileQoSOptions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int ExceptionsAllowedBeforeBreaking { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int DurationOfBreak { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int TimeoutValue { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,6 +12,7 @@ namespace Ocelot.Configuration.File
 | 
				
			|||||||
            AddQueriesToRequest = new Dictionary<string, string>();
 | 
					            AddQueriesToRequest = new Dictionary<string, string>();
 | 
				
			||||||
            AuthenticationOptions = new FileAuthenticationOptions();
 | 
					            AuthenticationOptions = new FileAuthenticationOptions();
 | 
				
			||||||
            FileCacheOptions = new FileCacheOptions();
 | 
					            FileCacheOptions = new FileCacheOptions();
 | 
				
			||||||
 | 
					            QoSOptions = new FileQoSOptions();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string DownstreamPathTemplate { get; set; }
 | 
					        public string DownstreamPathTemplate { get; set; }
 | 
				
			||||||
@@ -29,6 +30,7 @@ namespace Ocelot.Configuration.File
 | 
				
			|||||||
        public string DownstreamScheme {get;set;}
 | 
					        public string DownstreamScheme {get;set;}
 | 
				
			||||||
        public string DownstreamHost {get;set;}
 | 
					        public string DownstreamHost {get;set;}
 | 
				
			||||||
        public int DownstreamPort { get; set; }
 | 
					        public int DownstreamPort { get; set; }
 | 
				
			||||||
 | 
					        public FileQoSOptions QoSOptions { get; set; }
 | 
				
			||||||
        public string LoadBalancer {get;set;}
 | 
					        public string LoadBalancer {get;set;}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								src/Ocelot/Configuration/QoSOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/Ocelot/Configuration/QoSOptions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					using Polly.Timeout;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Ocelot.Configuration
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class QoSOptions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public QoSOptions(int exceptionsAllowedBeforeBreaking, int durationofBreak, int timeoutValue, TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
 | 
				
			||||||
 | 
					            DurationOfBreak = TimeSpan.FromMilliseconds(durationofBreak);
 | 
				
			||||||
 | 
					            TimeoutValue = TimeSpan.FromMilliseconds(timeoutValue);
 | 
				
			||||||
 | 
					            TimeoutStrategy = timeoutStrategy;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					         
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int ExceptionsAllowedBeforeBreaking { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TimeSpan DurationOfBreak { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TimeSpan TimeoutValue { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TimeoutStrategy TimeoutStrategy { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -8,16 +8,27 @@ namespace Ocelot.Configuration
 | 
				
			|||||||
    public class ReRoute
 | 
					    public class ReRoute
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public ReRoute(PathTemplate downstreamPathTemplate, 
 | 
					        public ReRoute(PathTemplate downstreamPathTemplate, 
 | 
				
			||||||
            PathTemplate upstreamTemplate, HttpMethod upstreamHttpMethod, 
 | 
					            PathTemplate upstreamTemplate, 
 | 
				
			||||||
 | 
					            HttpMethod upstreamHttpMethod, 
 | 
				
			||||||
            string upstreamTemplatePattern, 
 | 
					            string upstreamTemplatePattern, 
 | 
				
			||||||
            bool isAuthenticated, AuthenticationOptions authenticationOptions, 
 | 
					            bool isAuthenticated, 
 | 
				
			||||||
 | 
					            AuthenticationOptions authenticationOptions, 
 | 
				
			||||||
            List<ClaimToThing> configurationHeaderExtractorProperties, 
 | 
					            List<ClaimToThing> configurationHeaderExtractorProperties, 
 | 
				
			||||||
            List<ClaimToThing> claimsToClaims, 
 | 
					            List<ClaimToThing> claimsToClaims, 
 | 
				
			||||||
            Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, 
 | 
					            Dictionary<string, string> routeClaimsRequirement, 
 | 
				
			||||||
 | 
					            bool isAuthorised, 
 | 
				
			||||||
            List<ClaimToThing> claimsToQueries, 
 | 
					            List<ClaimToThing> claimsToQueries, 
 | 
				
			||||||
            string requestIdKey, bool isCached, CacheOptions fileCacheOptions, 
 | 
					            string requestIdKey, 
 | 
				
			||||||
            string downstreamScheme, string loadBalancer, string downstreamHost, 
 | 
					            bool isCached, 
 | 
				
			||||||
            int downstreamPort, string loadBalancerKey, ServiceProviderConfiguraion serviceProviderConfiguraion)
 | 
					            CacheOptions fileCacheOptions, 
 | 
				
			||||||
 | 
					            string downstreamScheme, 
 | 
				
			||||||
 | 
					            string loadBalancer, 
 | 
				
			||||||
 | 
					            string downstreamHost, 
 | 
				
			||||||
 | 
					            int downstreamPort, 
 | 
				
			||||||
 | 
					            string loadBalancerKey, 
 | 
				
			||||||
 | 
					            ServiceProviderConfiguraion serviceProviderConfiguraion,
 | 
				
			||||||
 | 
					            bool isQos,
 | 
				
			||||||
 | 
					            QoSOptions qos)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LoadBalancerKey = loadBalancerKey;
 | 
					            LoadBalancerKey = loadBalancerKey;
 | 
				
			||||||
            ServiceProviderConfiguraion = serviceProviderConfiguraion;
 | 
					            ServiceProviderConfiguraion = serviceProviderConfiguraion;
 | 
				
			||||||
@@ -42,6 +53,8 @@ namespace Ocelot.Configuration
 | 
				
			|||||||
            ClaimsToHeaders = configurationHeaderExtractorProperties 
 | 
					            ClaimsToHeaders = configurationHeaderExtractorProperties 
 | 
				
			||||||
                ?? new List<ClaimToThing>();
 | 
					                ?? new List<ClaimToThing>();
 | 
				
			||||||
                DownstreamScheme = downstreamScheme;
 | 
					                DownstreamScheme = downstreamScheme;
 | 
				
			||||||
 | 
					            IsQos = isQos;
 | 
				
			||||||
 | 
					            QosOptions = qos;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string LoadBalancerKey {get;private set;}
 | 
					        public string LoadBalancerKey {get;private set;}
 | 
				
			||||||
@@ -60,6 +73,8 @@ namespace Ocelot.Configuration
 | 
				
			|||||||
        public bool IsCached { get; private set; }
 | 
					        public bool IsCached { get; private set; }
 | 
				
			||||||
        public CacheOptions FileCacheOptions { get; private set; }
 | 
					        public CacheOptions FileCacheOptions { get; private set; }
 | 
				
			||||||
        public string DownstreamScheme {get;private set;}
 | 
					        public string DownstreamScheme {get;private set;}
 | 
				
			||||||
 | 
					        public bool IsQos { get; private set; }
 | 
				
			||||||
 | 
					        public QoSOptions QosOptions { get; private set; }
 | 
				
			||||||
        public string LoadBalancer {get;private set;}
 | 
					        public string LoadBalancer {get;private set;}
 | 
				
			||||||
        public string DownstreamHost { get; private set; }
 | 
					        public string DownstreamHost { get; private set; }
 | 
				
			||||||
        public int DownstreamPort { get; private set; }
 | 
					        public int DownstreamPort { get; private set; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Microsoft.AspNetCore.Http;
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
using Ocelot.Responses;
 | 
					using Ocelot.Responses;
 | 
				
			||||||
 | 
					using Ocelot.Configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.Request.Builder
 | 
					namespace Ocelot.Request.Builder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -15,7 +16,9 @@ namespace Ocelot.Request.Builder
 | 
				
			|||||||
            IRequestCookieCollection cookies, 
 | 
					            IRequestCookieCollection cookies, 
 | 
				
			||||||
            QueryString queryString, 
 | 
					            QueryString queryString, 
 | 
				
			||||||
            string contentType, 
 | 
					            string contentType, 
 | 
				
			||||||
            RequestId.RequestId requestId)
 | 
					            RequestId.RequestId requestId,
 | 
				
			||||||
 | 
					            bool isQos,
 | 
				
			||||||
 | 
					            QoSOptions qos)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var request = await new RequestBuilder()
 | 
					            var request = await new RequestBuilder()
 | 
				
			||||||
                .WithHttpMethod(httpMethod)
 | 
					                .WithHttpMethod(httpMethod)
 | 
				
			||||||
@@ -26,6 +29,8 @@ namespace Ocelot.Request.Builder
 | 
				
			|||||||
                .WithHeaders(headers)
 | 
					                .WithHeaders(headers)
 | 
				
			||||||
                .WithRequestId(requestId)
 | 
					                .WithRequestId(requestId)
 | 
				
			||||||
                .WithCookies(cookies)
 | 
					                .WithCookies(cookies)
 | 
				
			||||||
 | 
					                .WithIsQos(isQos)
 | 
				
			||||||
 | 
					                .WithQos(qos)
 | 
				
			||||||
                .Build();
 | 
					                .Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return new OkResponse<Request>(request);
 | 
					            return new OkResponse<Request>(request);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Microsoft.AspNetCore.Http;
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
using Ocelot.Responses;
 | 
					using Ocelot.Responses;
 | 
				
			||||||
 | 
					using Ocelot.Configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.Request.Builder
 | 
					namespace Ocelot.Request.Builder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -14,6 +15,8 @@ namespace Ocelot.Request.Builder
 | 
				
			|||||||
            IRequestCookieCollection cookies,
 | 
					            IRequestCookieCollection cookies,
 | 
				
			||||||
            QueryString queryString,
 | 
					            QueryString queryString,
 | 
				
			||||||
            string contentType,
 | 
					            string contentType,
 | 
				
			||||||
            RequestId.RequestId requestId);
 | 
					            RequestId.RequestId requestId,
 | 
				
			||||||
 | 
					            bool isQos,
 | 
				
			||||||
 | 
					            QoSOptions qos);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ using System.Net.Http.Headers;
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Microsoft.AspNetCore.Http;
 | 
					using Microsoft.AspNetCore.Http;
 | 
				
			||||||
using Microsoft.Extensions.Primitives;
 | 
					using Microsoft.Extensions.Primitives;
 | 
				
			||||||
 | 
					using Ocelot.Configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.Request.Builder
 | 
					namespace Ocelot.Request.Builder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -22,6 +23,8 @@ namespace Ocelot.Request.Builder
 | 
				
			|||||||
        private RequestId.RequestId _requestId;
 | 
					        private RequestId.RequestId _requestId;
 | 
				
			||||||
        private IRequestCookieCollection _cookies;
 | 
					        private IRequestCookieCollection _cookies;
 | 
				
			||||||
        private readonly string[] _unsupportedHeaders = {"host"};
 | 
					        private readonly string[] _unsupportedHeaders = {"host"};
 | 
				
			||||||
 | 
					        private bool _isQos;
 | 
				
			||||||
 | 
					        private QoSOptions _qos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public RequestBuilder WithHttpMethod(string httpMethod)
 | 
					        public RequestBuilder WithHttpMethod(string httpMethod)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -71,6 +74,18 @@ namespace Ocelot.Request.Builder
 | 
				
			|||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public RequestBuilder WithIsQos(bool isqos)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _isQos = isqos;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public RequestBuilder WithQos(QoSOptions qos)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _qos = qos;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<Request> Build()
 | 
					        public async Task<Request> Build()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var uri = CreateUri();
 | 
					            var uri = CreateUri();
 | 
				
			||||||
@@ -90,7 +105,7 @@ namespace Ocelot.Request.Builder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var cookieContainer = CreateCookieContainer(uri);
 | 
					            var cookieContainer = CreateCookieContainer(uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return new Request(httpRequestMessage, cookieContainer);
 | 
					            return new Request(httpRequestMessage, cookieContainer,_isQos,_qos);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private Uri CreateUri()
 | 
					        private Uri CreateUri()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,8 @@ namespace Ocelot.Request.Middleware
 | 
				
			|||||||
            var buildResult = await _requestCreator
 | 
					            var buildResult = await _requestCreator
 | 
				
			||||||
                .Build(context.Request.Method, DownstreamUrl, context.Request.Body,
 | 
					                .Build(context.Request.Method, DownstreamUrl, context.Request.Body,
 | 
				
			||||||
                    context.Request.Headers, context.Request.Cookies, context.Request.QueryString,
 | 
					                    context.Request.Headers, context.Request.Cookies, context.Request.QueryString,
 | 
				
			||||||
                    context.Request.ContentType, new RequestId.RequestId(DownstreamRoute?.ReRoute?.RequestIdKey, context.TraceIdentifier));
 | 
					                    context.Request.ContentType, new RequestId.RequestId(DownstreamRoute?.ReRoute?.RequestIdKey, context.TraceIdentifier),
 | 
				
			||||||
 | 
					                    DownstreamRoute.ReRoute.IsQos,DownstreamRoute.ReRoute.QosOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (buildResult.IsError)
 | 
					            if (buildResult.IsError)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,23 @@
 | 
				
			|||||||
using System.Net;
 | 
					using Ocelot.Configuration;
 | 
				
			||||||
 | 
					using Ocelot.Values;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
using System.Net.Http;
 | 
					using System.Net.Http;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.Request
 | 
					namespace Ocelot.Request
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class Request
 | 
					    public class Request
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public Request(HttpRequestMessage httpRequestMessage, CookieContainer cookieContainer)
 | 
					        public Request(HttpRequestMessage httpRequestMessage, CookieContainer cookieContainer,bool isQos, QoSOptions qos)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            HttpRequestMessage = httpRequestMessage;
 | 
					            HttpRequestMessage = httpRequestMessage;
 | 
				
			||||||
            CookieContainer = cookieContainer;
 | 
					            CookieContainer = cookieContainer;
 | 
				
			||||||
 | 
					            IsQos = isQos;
 | 
				
			||||||
 | 
					            Qos = qos;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public HttpRequestMessage HttpRequestMessage { get; private set; }
 | 
					        public HttpRequestMessage HttpRequestMessage { get; private set; }
 | 
				
			||||||
        public CookieContainer CookieContainer { get; private set; }
 | 
					        public CookieContainer CookieContainer { get; private set; }
 | 
				
			||||||
 | 
					        public bool IsQos { get; private set; }
 | 
				
			||||||
 | 
					        public QoSOptions Qos { get; private set; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										74
									
								
								src/Ocelot/Requester/CircuitBreakingDelegatingHandler.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/Ocelot/Requester/CircuitBreakingDelegatingHandler.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					using Ocelot.Logging;
 | 
				
			||||||
 | 
					using Polly;
 | 
				
			||||||
 | 
					using Polly.CircuitBreaker;
 | 
				
			||||||
 | 
					using Polly.Timeout;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
 | 
					using System.Net.Http;
 | 
				
			||||||
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Ocelot.Requester
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class CircuitBreakingDelegatingHandler : DelegatingHandler
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly IOcelotLogger _logger;
 | 
				
			||||||
 | 
					        private readonly int _exceptionsAllowedBeforeBreaking;
 | 
				
			||||||
 | 
					        private readonly TimeSpan _durationOfBreak;
 | 
				
			||||||
 | 
					        private readonly Policy _circuitBreakerPolicy;
 | 
				
			||||||
 | 
					        private readonly TimeoutPolicy _timeoutPolicy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CircuitBreakingDelegatingHandler(int exceptionsAllowedBeforeBreaking, TimeSpan durationOfBreak,TimeSpan timeoutValue
 | 
				
			||||||
 | 
					            ,TimeoutStrategy timeoutStrategy, IOcelotLogger logger, HttpMessageHandler innerHandler)
 | 
				
			||||||
 | 
					            : base(innerHandler)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this._exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
 | 
				
			||||||
 | 
					            this._durationOfBreak = durationOfBreak;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _circuitBreakerPolicy = Policy
 | 
				
			||||||
 | 
					                .Handle<HttpRequestException>()
 | 
				
			||||||
 | 
					                .Or<TimeoutRejectedException>()
 | 
				
			||||||
 | 
					                .Or<TimeoutException>()
 | 
				
			||||||
 | 
					                .CircuitBreakerAsync(
 | 
				
			||||||
 | 
					                    exceptionsAllowedBeforeBreaking: exceptionsAllowedBeforeBreaking,
 | 
				
			||||||
 | 
					                    durationOfBreak: durationOfBreak,
 | 
				
			||||||
 | 
					                    onBreak: (ex, breakDelay) =>
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        _logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."),
 | 
				
			||||||
 | 
					                    onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.")
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					            _timeoutPolicy = Policy.TimeoutAsync(timeoutValue, timeoutStrategy);
 | 
				
			||||||
 | 
					            _logger = logger;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Task<HttpResponseMessage> responseTask = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                responseTask = Policy.WrapAsync(_circuitBreakerPolicy, _timeoutPolicy).ExecuteAsync<HttpResponseMessage>(() =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return  base.SendAsync(request,cancellationToken);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                return responseTask;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (BrokenCircuitException ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _logger.LogError($"Reached to allowed number of exceptions. Circuit is open. AllowedExceptionCount: {_exceptionsAllowedBeforeBreaking}, DurationOfBreak: {_durationOfBreak}",ex);
 | 
				
			||||||
 | 
					                throw;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (HttpRequestException)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return responseTask;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static bool IsTransientFailure(HttpResponseMessage result)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return result.StatusCode >= HttpStatusCode.InternalServerError;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								src/Ocelot/Requester/HttpClientBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/Ocelot/Requester/HttpClientBuilder.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					using Ocelot.Configuration;
 | 
				
			||||||
 | 
					using Ocelot.Logging;
 | 
				
			||||||
 | 
					using Ocelot.Values;
 | 
				
			||||||
 | 
					using Polly.Timeout;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Net.Http;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Ocelot.Requester
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    internal class HttpClientBuilder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly Dictionary<int, Func<DelegatingHandler>> handlers = new Dictionary<int, Func<DelegatingHandler>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public HttpClientBuilder WithCircuitBreaker(QoSOptions qos, IOcelotLogger logger, HttpMessageHandler innerHandler)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            handlers.Add(5000, () => new CircuitBreakingDelegatingHandler(qos.ExceptionsAllowedBeforeBreaking, qos.DurationOfBreak, qos.TimeoutValue, qos.TimeoutStrategy, logger, innerHandler));
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal HttpClient Build(HttpMessageHandler innerHandler)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return handlers.Any() ? new HttpClient(CreateHttpMessageHandler()) : new HttpClient(innerHandler);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private HttpMessageHandler CreateHttpMessageHandler()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            HttpMessageHandler httpMessageHandler = new HttpClientHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            handlers.OrderByDescending(handler => handler.Key).Select(handler => handler.Value).Reverse().ToList().ForEach(handler =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var delegatingHandler = handler();
 | 
				
			||||||
 | 
					                delegatingHandler.InnerHandler = httpMessageHandler;
 | 
				
			||||||
 | 
					                httpMessageHandler = delegatingHandler;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return httpMessageHandler;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,15 +4,30 @@ using System.Net.Http;
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Ocelot.Errors;
 | 
					using Ocelot.Errors;
 | 
				
			||||||
using Ocelot.Responses;
 | 
					using Ocelot.Responses;
 | 
				
			||||||
 | 
					using Ocelot.Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.Requester
 | 
					namespace Ocelot.Requester
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class HttpClientHttpRequester : IHttpRequester
 | 
					    public class HttpClientHttpRequester : IHttpRequester
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly IOcelotLogger _logger;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _logger = loggerFactory.CreateLogger<HttpClientHttpRequester>();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<Response<HttpResponseMessage>> GetResponse(Request.Request request)
 | 
					        public async Task<Response<HttpResponseMessage>> GetResponse(Request.Request request)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            HttpClientBuilder builder = new HttpClientBuilder();    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer })
 | 
					            using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer })
 | 
				
			||||||
            using (var httpClient = new HttpClient(handler))
 | 
					            {
 | 
				
			||||||
 | 
					                if (request.IsQos)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    builder.WithCircuitBreaker(request.Qos, _logger, handler);
 | 
				
			||||||
 | 
					                }           
 | 
				
			||||||
 | 
					                using (var httpClient = builder.Build(handler))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
@@ -31,3 +46,4 @@ namespace Ocelot.Requester
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -7,5 +7,7 @@ namespace Ocelot.Requester
 | 
				
			|||||||
    public interface IHttpRequester
 | 
					    public interface IHttpRequester
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Task<Response<HttpResponseMessage>> GetResponse(Request.Request request);
 | 
					        Task<Response<HttpResponseMessage>> GetResponse(Request.Request request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "version": "0.0.0-dev",
 | 
					  "version": "0.0.0-dev",
 | 
				
			||||||
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
 | 
					    "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
 | 
				
			||||||
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
 | 
					    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
 | 
				
			||||||
@@ -28,7 +27,8 @@
 | 
				
			|||||||
    "CacheManager.Core": "0.9.2",
 | 
					    "CacheManager.Core": "0.9.2",
 | 
				
			||||||
    "CacheManager.Microsoft.Extensions.Configuration": "0.9.2",
 | 
					    "CacheManager.Microsoft.Extensions.Configuration": "0.9.2",
 | 
				
			||||||
    "CacheManager.Microsoft.Extensions.Logging": "0.9.2",
 | 
					    "CacheManager.Microsoft.Extensions.Logging": "0.9.2",
 | 
				
			||||||
        "Consul": "0.7.2.1"
 | 
					    "Consul": "0.7.2.1",
 | 
				
			||||||
 | 
					    "Polly": "5.0.3"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "runtimes": {
 | 
					  "runtimes": {
 | 
				
			||||||
    "win10-x64": {},
 | 
					    "win10-x64": {},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								test/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/.DS_Store
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -165,6 +165,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamScheme = _downstreamServiceScheme,
 | 
					                            DownstreamScheme = _downstreamServiceScheme,
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Post",
 | 
					                            UpstreamHttpMethod = "Post",
 | 
				
			||||||
 | 
					                            
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
					                                AdditionalScopes =  new List<string>(),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamScheme = "http",
 | 
					                            DownstreamScheme = "http",
 | 
				
			||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/products/{productId}",
 | 
					                            UpstreamPathTemplate = "/products/{productId}",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get"
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -63,7 +63,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/products/{productId}",
 | 
					                            UpstreamPathTemplate = "/products/{productId}",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            ReRouteIsCaseSensitive = false
 | 
					                            ReRouteIsCaseSensitive = false,
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -91,7 +91,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/products/{productId}",
 | 
					                            UpstreamPathTemplate = "/products/{productId}",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            ReRouteIsCaseSensitive = true
 | 
					                            ReRouteIsCaseSensitive = true,
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -119,7 +119,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/PRODUCTS/{productId}",
 | 
					                            UpstreamPathTemplate = "/PRODUCTS/{productId}",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            ReRouteIsCaseSensitive = true
 | 
					                            ReRouteIsCaseSensitive = true,
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -147,7 +147,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/products/{productId}",
 | 
					                            UpstreamPathTemplate = "/products/{productId}",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            ReRouteIsCaseSensitive = true
 | 
					                            ReRouteIsCaseSensitive = true,
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -175,7 +175,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/PRODUCTS/{productId}",
 | 
					                            UpstreamPathTemplate = "/PRODUCTS/{productId}",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            ReRouteIsCaseSensitive = true
 | 
					                            ReRouteIsCaseSensitive = true,
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,6 +88,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -125,6 +126,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            RequestIdKey = _steps.RequestIdKey
 | 
					                            RequestIdKey = _steps.RequestIdKey,
 | 
				
			||||||
                         }
 | 
					                         }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -67,7 +67,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            RequestIdKey = _steps.RequestIdKey
 | 
					 
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,6 +46,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamPort = 51879,
 | 
					                            DownstreamPort = 51879,
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -74,6 +75,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamPort = 51879,
 | 
					                            DownstreamPort = 51879,
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -102,6 +104,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamPort = 51879,
 | 
					                            DownstreamPort = 51879,
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -130,6 +133,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamPort = 51879,
 | 
					                            DownstreamPort = 51879,
 | 
				
			||||||
                            UpstreamPathTemplate = "/products/",
 | 
					                            UpstreamPathTemplate = "/products/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -186,6 +190,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                        DownstreamPort = 51879,
 | 
					                        DownstreamPort = 51879,
 | 
				
			||||||
                        UpstreamPathTemplate = "/products/{productId}",
 | 
					                        UpstreamPathTemplate = "/products/{productId}",
 | 
				
			||||||
                        UpstreamHttpMethod = "Get",
 | 
					                        UpstreamHttpMethod = "Get",
 | 
				
			||||||
 | 
					                        QoSOptions = new FileQoSOptions()
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            ExceptionsAllowedBeforeBreaking = 3,
 | 
				
			||||||
 | 
					                            DurationOfBreak = 5,
 | 
				
			||||||
 | 
					                            TimeoutValue = 5000
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -212,7 +222,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamHost = "localhost",
 | 
					                            DownstreamHost = "localhost",
 | 
				
			||||||
                            DownstreamPort = 51879,
 | 
					                            DownstreamPort = 51879,
 | 
				
			||||||
                            UpstreamPathTemplate = "/products/{productId}",
 | 
					                            UpstreamPathTemplate = "/products/{productId}",
 | 
				
			||||||
                            UpstreamHttpMethod = "Get"
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@@ -240,7 +250,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            DownstreamPort = 51879,
 | 
					                            DownstreamPort = 51879,
 | 
				
			||||||
                            DownstreamScheme = "http",
 | 
					                            DownstreamScheme = "http",
 | 
				
			||||||
                            UpstreamPathTemplate = "/",
 | 
					                            UpstreamPathTemplate = "/",
 | 
				
			||||||
                            UpstreamHttpMethod = "Post"
 | 
					                            UpstreamHttpMethod = "Post", 
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamPathTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}}
 | 
					 | 
				
			||||||
@@ -7,6 +7,11 @@
 | 
				
			|||||||
      "DownstreamPort": 52876,
 | 
					      "DownstreamPort": 52876,
 | 
				
			||||||
      "UpstreamTemplate": "/identityserverexample",
 | 
					      "UpstreamTemplate": "/identityserverexample",
 | 
				
			||||||
      "UpstreamHttpMethod": "Get",
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "AuthenticationOptions": {
 | 
					      "AuthenticationOptions": {
 | 
				
			||||||
        "Provider": "IdentityServer",
 | 
					        "Provider": "IdentityServer",
 | 
				
			||||||
        "ProviderRootUrl": "http://localhost:52888",
 | 
					        "ProviderRootUrl": "http://localhost:52888",
 | 
				
			||||||
@@ -47,7 +52,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts",
 | 
					      "UpstreamTemplate": "/posts",
 | 
				
			||||||
      "UpstreamHttpMethod": "Get",
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
            "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/posts/{postId}",
 | 
					      "DownstreamPathTemplate": "/posts/{postId}",
 | 
				
			||||||
@@ -55,7 +64,12 @@
 | 
				
			|||||||
      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
					      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
				
			||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts/{postId}",
 | 
					      "UpstreamTemplate": "/posts/{postId}",
 | 
				
			||||||
            "UpstreamHttpMethod": "Get"
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/posts/{postId}/comments",
 | 
					      "DownstreamPathTemplate": "/posts/{postId}/comments",
 | 
				
			||||||
@@ -63,7 +77,12 @@
 | 
				
			|||||||
      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
					      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
				
			||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts/{postId}/comments",
 | 
					      "UpstreamTemplate": "/posts/{postId}/comments",
 | 
				
			||||||
            "UpstreamHttpMethod": "Get"
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/comments",
 | 
					      "DownstreamPathTemplate": "/comments",
 | 
				
			||||||
@@ -71,7 +90,12 @@
 | 
				
			|||||||
      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
					      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
				
			||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/comments",
 | 
					      "UpstreamTemplate": "/comments",
 | 
				
			||||||
            "UpstreamHttpMethod": "Get"
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/posts",
 | 
					      "DownstreamPathTemplate": "/posts",
 | 
				
			||||||
@@ -79,7 +103,12 @@
 | 
				
			|||||||
      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
					      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
				
			||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts",
 | 
					      "UpstreamTemplate": "/posts",
 | 
				
			||||||
            "UpstreamHttpMethod": "Post"
 | 
					      "UpstreamHttpMethod": "Post",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/posts/{postId}",
 | 
					      "DownstreamPathTemplate": "/posts/{postId}",
 | 
				
			||||||
@@ -87,7 +116,12 @@
 | 
				
			|||||||
      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
					      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
				
			||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts/{postId}",
 | 
					      "UpstreamTemplate": "/posts/{postId}",
 | 
				
			||||||
            "UpstreamHttpMethod": "Put"
 | 
					      "UpstreamHttpMethod": "Put",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/posts/{postId}",
 | 
					      "DownstreamPathTemplate": "/posts/{postId}",
 | 
				
			||||||
@@ -95,7 +129,12 @@
 | 
				
			|||||||
      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
					      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
				
			||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts/{postId}",
 | 
					      "UpstreamTemplate": "/posts/{postId}",
 | 
				
			||||||
            "UpstreamHttpMethod": "Patch"
 | 
					      "UpstreamHttpMethod": "Patch",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/posts/{postId}",
 | 
					      "DownstreamPathTemplate": "/posts/{postId}",
 | 
				
			||||||
@@ -103,7 +142,12 @@
 | 
				
			|||||||
      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
					      "DownstreamHost": "jsonplaceholder.typicode.com",
 | 
				
			||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts/{postId}",
 | 
					      "UpstreamTemplate": "/posts/{postId}",
 | 
				
			||||||
            "UpstreamHttpMethod": "Delete"
 | 
					      "UpstreamHttpMethod": "Delete",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/api/products",
 | 
					      "DownstreamPathTemplate": "/api/products",
 | 
				
			||||||
@@ -112,6 +156,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/products",
 | 
					      "UpstreamTemplate": "/products",
 | 
				
			||||||
      "UpstreamHttpMethod": "Get",
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -130,7 +179,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/products",
 | 
					      "UpstreamTemplate": "/products",
 | 
				
			||||||
      "UpstreamHttpMethod": "Post",
 | 
					      "UpstreamHttpMethod": "Post",
 | 
				
			||||||
            "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "DownstreamPathTemplate": "/api/products/{productId}",
 | 
					      "DownstreamPathTemplate": "/api/products/{productId}",
 | 
				
			||||||
@@ -139,6 +192,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/products/{productId}",
 | 
					      "UpstreamTemplate": "/products/{productId}",
 | 
				
			||||||
      "UpstreamHttpMethod": "Put",
 | 
					      "UpstreamHttpMethod": "Put",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -148,6 +206,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/products/{productId}",
 | 
					      "UpstreamTemplate": "/products/{productId}",
 | 
				
			||||||
      "UpstreamHttpMethod": "Delete",
 | 
					      "UpstreamHttpMethod": "Delete",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -157,6 +220,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/customers",
 | 
					      "UpstreamTemplate": "/customers",
 | 
				
			||||||
      "UpstreamHttpMethod": "Get",
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -166,6 +234,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/customers/{customerId}",
 | 
					      "UpstreamTemplate": "/customers/{customerId}",
 | 
				
			||||||
      "UpstreamHttpMethod": "Get",
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -175,6 +248,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/customers",
 | 
					      "UpstreamTemplate": "/customers",
 | 
				
			||||||
      "UpstreamHttpMethod": "Post",
 | 
					      "UpstreamHttpMethod": "Post",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -184,6 +262,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/customers/{customerId}",
 | 
					      "UpstreamTemplate": "/customers/{customerId}",
 | 
				
			||||||
      "UpstreamHttpMethod": "Put",
 | 
					      "UpstreamHttpMethod": "Put",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -193,6 +276,11 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/customers/{customerId}",
 | 
					      "UpstreamTemplate": "/customers/{customerId}",
 | 
				
			||||||
      "UpstreamHttpMethod": "Delete",
 | 
					      "UpstreamHttpMethod": "Delete",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -202,9 +290,15 @@
 | 
				
			|||||||
      "DownstreamPort": 80,
 | 
					      "DownstreamPort": 80,
 | 
				
			||||||
      "UpstreamTemplate": "/posts/",
 | 
					      "UpstreamTemplate": "/posts/",
 | 
				
			||||||
      "UpstreamHttpMethod": "Get",
 | 
					      "UpstreamHttpMethod": "Get",
 | 
				
			||||||
 | 
					      "QoSOptions": {
 | 
				
			||||||
 | 
					        "ExceptionsAllowedBeforeBreaking": 3,
 | 
				
			||||||
 | 
					        "DurationOfBreak": 10,
 | 
				
			||||||
 | 
					        "TimeoutValue": 5000
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
					      "FileCacheOptions": { "TtlSeconds": 15 }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  "GlobalConfiguration": {
 | 
					  "GlobalConfiguration": {
 | 
				
			||||||
    "RequestIdKey": "OcRequestId"
 | 
					    "RequestIdKey": "OcRequestId"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,6 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
				
			|||||||
        private readonly HttpClient _client;
 | 
					        private readonly HttpClient _client;
 | 
				
			||||||
        private HttpResponseMessage _result;
 | 
					        private HttpResponseMessage _result;
 | 
				
			||||||
        private HostAndPort _hostAndPort;
 | 
					        private HostAndPort _hostAndPort;
 | 
				
			||||||
        private OkResponse<Ocelot.Request.Request> _request;
 | 
					 | 
				
			||||||
        private OkResponse<string> _downstreamUrl;
 | 
					        private OkResponse<string> _downstreamUrl;
 | 
				
			||||||
        private OkResponse<DownstreamRoute> _downstreamRoute;
 | 
					        private OkResponse<DownstreamRoute> _downstreamRoute;
 | 
				
			||||||
        private ErrorResponse<ILoadBalancer> _getLoadBalancerHouseError;
 | 
					        private ErrorResponse<ILoadBalancer> _getLoadBalancerHouseError;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ using Ocelot.Request.Middleware;
 | 
				
			|||||||
using Ocelot.Responses;
 | 
					using Ocelot.Responses;
 | 
				
			||||||
using TestStack.BDDfy;
 | 
					using TestStack.BDDfy;
 | 
				
			||||||
using Xunit;
 | 
					using Xunit;
 | 
				
			||||||
 | 
					using Ocelot.Configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.UnitTests.Request
 | 
					namespace Ocelot.UnitTests.Request
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -74,7 +75,7 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
 | 
					            this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
 | 
				
			||||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
					                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
				
			||||||
                .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), new CookieContainer())))
 | 
					                .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), new CookieContainer(), true, new QoSOptions(3, 8 ,5000, Polly.Timeout.TimeoutStrategy.Pessimistic))))
 | 
				
			||||||
                .When(x => x.WhenICallTheMiddleware())
 | 
					                .When(x => x.WhenICallTheMiddleware())
 | 
				
			||||||
                .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
 | 
					                .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
 | 
				
			||||||
                .BDDfy();
 | 
					                .BDDfy();
 | 
				
			||||||
@@ -93,7 +94,7 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
            _request = new OkResponse<Ocelot.Request.Request>(request);
 | 
					            _request = new OkResponse<Ocelot.Request.Request>(request);
 | 
				
			||||||
            _requestBuilder
 | 
					            _requestBuilder
 | 
				
			||||||
                .Setup(x => x.Build(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Stream>(), It.IsAny<IHeaderDictionary>(),
 | 
					                .Setup(x => x.Build(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Stream>(), It.IsAny<IHeaderDictionary>(),
 | 
				
			||||||
                It.IsAny<IRequestCookieCollection>(), It.IsAny<QueryString>(), It.IsAny<string>(), It.IsAny<Ocelot.RequestId.RequestId>()))
 | 
					                It.IsAny<IRequestCookieCollection>(), It.IsAny<QueryString>(), It.IsAny<string>(), It.IsAny<Ocelot.RequestId.RequestId>(),It.IsAny<bool>(), It.IsAny<QoSOptions>()))
 | 
				
			||||||
                .ReturnsAsync(_request);
 | 
					                .ReturnsAsync(_request);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ using Ocelot.Responses;
 | 
				
			|||||||
using Shouldly;
 | 
					using Shouldly;
 | 
				
			||||||
using TestStack.BDDfy;
 | 
					using TestStack.BDDfy;
 | 
				
			||||||
using Xunit;
 | 
					using Xunit;
 | 
				
			||||||
 | 
					using Ocelot.Configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.UnitTests.Request
 | 
					namespace Ocelot.UnitTests.Request
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -25,6 +26,8 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
        private readonly IRequestCreator _requestCreator;
 | 
					        private readonly IRequestCreator _requestCreator;
 | 
				
			||||||
        private Response<Ocelot.Request.Request> _result;
 | 
					        private Response<Ocelot.Request.Request> _result;
 | 
				
			||||||
        private Ocelot.RequestId.RequestId _requestId;
 | 
					        private Ocelot.RequestId.RequestId _requestId;
 | 
				
			||||||
 | 
					        private bool _isQos;
 | 
				
			||||||
 | 
					        private QoSOptions _qos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public RequestBuilderTests()
 | 
					        public RequestBuilderTests()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -37,6 +40,7 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            this.Given(x => x.GivenIHaveHttpMethod("GET"))
 | 
					            this.Given(x => x.GivenIHaveHttpMethod("GET"))
 | 
				
			||||||
                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
					                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
				
			||||||
 | 
					                .And(x=> x.GivenTheQos(true,new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
                .When(x => x.WhenICreateARequest())
 | 
					                .When(x => x.WhenICreateARequest())
 | 
				
			||||||
                .And(x => x.ThenTheCorrectDownstreamUrlIsUsed("http://www.bbc.co.uk/"))
 | 
					                .And(x => x.ThenTheCorrectDownstreamUrlIsUsed("http://www.bbc.co.uk/"))
 | 
				
			||||||
                .BDDfy();
 | 
					                .BDDfy();
 | 
				
			||||||
@@ -47,6 +51,8 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            this.Given(x => x.GivenIHaveHttpMethod("POST"))
 | 
					            this.Given(x => x.GivenIHaveHttpMethod("POST"))
 | 
				
			||||||
                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
					                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
				
			||||||
 | 
					                .And(x => x.GivenTheQos(true,new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                .When(x => x.WhenICreateARequest())
 | 
					                .When(x => x.WhenICreateARequest())
 | 
				
			||||||
                .And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post))
 | 
					                .And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post))
 | 
				
			||||||
                .BDDfy();
 | 
					                .BDDfy();
 | 
				
			||||||
@@ -59,6 +65,8 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
					                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
				
			||||||
                .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
 | 
					                .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
 | 
				
			||||||
                .And(x => x.GivenTheContentTypeIs("application/json"))
 | 
					                .And(x => x.GivenTheContentTypeIs("application/json"))
 | 
				
			||||||
 | 
					                              .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                              .When(x => x.WhenICreateARequest())
 | 
					                              .When(x => x.WhenICreateARequest())
 | 
				
			||||||
               .And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom")))
 | 
					               .And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom")))
 | 
				
			||||||
               .BDDfy();
 | 
					               .BDDfy();
 | 
				
			||||||
@@ -71,6 +79,8 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
					                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
				
			||||||
                .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
 | 
					                .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
 | 
				
			||||||
                .And(x => x.GivenTheContentTypeIs("application/json"))
 | 
					                .And(x => x.GivenTheContentTypeIs("application/json"))
 | 
				
			||||||
 | 
					                .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
               .When(x => x.WhenICreateARequest())
 | 
					               .When(x => x.WhenICreateARequest())
 | 
				
			||||||
               .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary
 | 
					               .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -88,6 +98,8 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
					                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
				
			||||||
                .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
 | 
					                .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
 | 
				
			||||||
                .And(x => x.GivenTheContentTypeIs("application/json; charset=utf-8"))
 | 
					                .And(x => x.GivenTheContentTypeIs("application/json; charset=utf-8"))
 | 
				
			||||||
 | 
					                                .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
               .When(x => x.WhenICreateARequest())
 | 
					               .When(x => x.WhenICreateARequest())
 | 
				
			||||||
               .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary
 | 
					               .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -107,6 +119,8 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    {"ChopSticks", "Bubbles" }
 | 
					                    {"ChopSticks", "Bubbles" }
 | 
				
			||||||
                }))
 | 
					                }))
 | 
				
			||||||
 | 
					                                .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                .When(x => x.WhenICreateARequest())
 | 
					                .When(x => x.WhenICreateARequest())
 | 
				
			||||||
                .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary
 | 
					                .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -124,6 +138,7 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
					                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
				
			||||||
                .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary()))
 | 
					                .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary()))
 | 
				
			||||||
                .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", requestId)))
 | 
					                .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", requestId)))
 | 
				
			||||||
 | 
					                              .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
  .When(x => x.WhenICreateARequest())
 | 
					  .When(x => x.WhenICreateARequest())
 | 
				
			||||||
                .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary
 | 
					                .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -142,6 +157,7 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
                    {"RequestId", "534534gv54gv45g" }
 | 
					                    {"RequestId", "534534gv54gv45g" }
 | 
				
			||||||
                }))
 | 
					                }))
 | 
				
			||||||
                .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", Guid.NewGuid().ToString())))
 | 
					                .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", Guid.NewGuid().ToString())))
 | 
				
			||||||
 | 
					                               .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
 .When(x => x.WhenICreateARequest())
 | 
					 .When(x => x.WhenICreateARequest())
 | 
				
			||||||
                .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary
 | 
					                .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -161,6 +177,7 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
					                .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
 | 
				
			||||||
                .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary()))
 | 
					                .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary()))
 | 
				
			||||||
                .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId(requestIdKey, requestIdValue)))
 | 
					                .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId(requestIdKey, requestIdValue)))
 | 
				
			||||||
 | 
					                              .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))
 | 
				
			||||||
  .When(x => x.WhenICreateARequest())
 | 
					  .When(x => x.WhenICreateARequest())
 | 
				
			||||||
                .And(x => x.ThenTheRequestIdIsNotInTheHeaders())
 | 
					                .And(x => x.ThenTheRequestIdIsNotInTheHeaders())
 | 
				
			||||||
                .BDDfy();
 | 
					                .BDDfy();
 | 
				
			||||||
@@ -171,6 +188,12 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
            _requestId = requestId;
 | 
					            _requestId = requestId;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void GivenTheQos(bool isQos, QoSOptions qos)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _isQos = isQos;
 | 
				
			||||||
 | 
					            _qos = qos;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void should_use_cookies()
 | 
					        public void should_use_cookies()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -281,7 +304,7 @@ namespace Ocelot.UnitTests.Request
 | 
				
			|||||||
        private void WhenICreateARequest()
 | 
					        private void WhenICreateARequest()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _result = _requestCreator.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers,
 | 
					            _result = _requestCreator.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers,
 | 
				
			||||||
                _cookies, _query, _contentType, _requestId).Result;
 | 
					                _cookies, _query, _contentType, _requestId,_isQos,_qos).Result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,7 @@ namespace Ocelot.UnitTests.Requester
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void should_call_scoped_data_repository_correctly()
 | 
					        public void should_call_scoped_data_repository_correctly()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),new CookieContainer())))
 | 
					            this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),new CookieContainer(),true, new Ocelot.Configuration.QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))))
 | 
				
			||||||
                .And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
 | 
					                .And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
 | 
				
			||||||
                .And(x => x.GivenTheScopedRepoReturns())
 | 
					                .And(x => x.GivenTheScopedRepoReturns())
 | 
				
			||||||
                .When(x => x.WhenICallTheMiddleware())
 | 
					                .When(x => x.WhenICallTheMiddleware())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ namespace Ocelot.UnitTests.ServiceDiscovery
 | 
				
			|||||||
    public class ConfigurationServiceProviderTests
 | 
					    public class ConfigurationServiceProviderTests
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private ConfigurationServiceProvider _serviceProvider;
 | 
					        private ConfigurationServiceProvider _serviceProvider;
 | 
				
			||||||
        private HostAndPort _hostAndPort;
 | 
					 | 
				
			||||||
        private List<Service> _result;
 | 
					        private List<Service> _result;
 | 
				
			||||||
        private List<Service> _expected;
 | 
					        private List<Service> _expected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user