+semver: breaking PRs merged from Develop, Eureka honour scheme, don't crash on dispose and validate duplicate placeholders in UpstreamPathTemplate

* initial commit for new feature #1077

allow to limit the number of concurrent tcp connection to a downstream service

* protect code against value not in accurate range

add unit test

* Do not crash host on Dispose

* Add test

* Pin GitVersion.CommandLine package version

* #683 validate if there are duplicated placeholders in UpstreamPathTemplate

* Use registered scheme from Eureka (#1087)

* extra test

* very brief mention MaxConnectionsPerServer in docs

* build develop like a PR

* more docs

Co-authored-by: jlukawska <56401969+jlukawska@users.noreply.github.com>
Co-authored-by: buretjph <58700930+buretjph@users.noreply.github.com>
Co-authored-by: Jonathan Mezach <jonathanmezach@gmail.com>
Co-authored-by: 彭伟 <pengweiqhca@sina.com>
This commit is contained in:
Tom Pallister 2020-01-19 15:00:21 +00:00 committed by GitHub
parent 664c6ef626
commit 65710f4a94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 792 additions and 560 deletions

View File

@ -27,4 +27,3 @@ workflows:
branches:
ignore:
- master
- develop

View File

@ -1,4 +1,4 @@
#tool "nuget:?package=GitVersion.CommandLine&version=5.0.1"
#tool "nuget:?package=GitVersion.CommandLine&version=5.0.1"
#tool "nuget:?package=GitReleaseNotes"
#addin nuget:?package=Cake.Json
#addin nuget:?package=Newtonsoft.Json

View File

@ -62,7 +62,8 @@ Here is an example ReRoute configuration, You don't need to set all of these thi
"HttpHandlerOptions": {
"AllowAutoRedirect": true,
"UseCookieContainer": true,
"UseTracing": true
"UseTracing": true,
"MaxConnectionsPerServer": 100
},
"DangerousAcceptAnyServerCertificateValidator": false
}
@ -222,3 +223,8 @@ If you want to ignore SSL warnings / errors set the following in your ReRoute co
"DangerousAcceptAnyServerCertificateValidator": true
I don't recommend doing this, I suggest creating your own certificate and then getting it trusted by your local / remote machine if you can.
MaxConnectionsPerServer
^^^^^^^^^^^^^^^^^^^^^^^
This controls how many connections the internal HttpClient will open. This can be set at ReRoute or global level.

View File

@ -155,6 +155,8 @@ Eureka. One of the services polls Eureka every 30 seconds (default) and gets the
When Ocelot asks for a given service it is retrieved from memory so performance is not a big problem. Please note that this code
is provided by the Pivotal.Discovery.Client NuGet package so big thanks to them for all the hard work.
Ocelot will use the scheme (http/https) set in Eureka if these values are not provided in ocelot.json
Dynamic Routing
^^^^^^^^^^^^^^^

View File

@ -26,7 +26,7 @@
if (instances != null && instances.Any())
{
services.AddRange(instances.Select(i => new Service(i.ServiceId, new ServiceHostAndPort(i.Host, i.Port), "", "", new List<string>())));
services.AddRange(instances.Select(i => new Service(i.ServiceId, new ServiceHostAndPort(i.Host, i.Port, i.Uri.Scheme), "", "", new List<string>())));
}
return Task.FromResult(services);

View File

@ -18,8 +18,11 @@
{
var useTracing = _tracer != null && options.UseTracing;
//be sure that maxConnectionPerServer is in correct range of values
int maxConnectionPerServer = (options.MaxConnectionsPerServer > 0) ? maxConnectionPerServer = options.MaxConnectionsPerServer : maxConnectionPerServer = int.MaxValue;
return new HttpHandlerOptions(options.AllowAutoRedirect,
options.UseCookieContainer, useTracing, options.UseProxy);
options.UseCookieContainer, useTracing, options.UseProxy, maxConnectionPerServer);
}
}
}

View File

@ -7,6 +7,7 @@
AllowAutoRedirect = false;
UseCookieContainer = false;
UseProxy = true;
MaxConnectionsPerServer = int.MaxValue;
}
public bool AllowAutoRedirect { get; set; }
@ -16,5 +17,7 @@
public bool UseTracing { get; set; }
public bool UseProxy { get; set; }
public int MaxConnectionsPerServer { get; set; }
}
}

View File

@ -6,32 +6,44 @@
/// </summary>
public class HttpHandlerOptions
{
public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer, bool useTracing, bool useProxy)
public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer, bool useTracing, bool useProxy, int maxConnectionsPerServer)
{
AllowAutoRedirect = allowAutoRedirect;
UseCookieContainer = useCookieContainer;
UseTracing = useTracing;
UseProxy = useProxy;
MaxConnectionsPerServer = maxConnectionsPerServer;
}
/// <summary>
/// Specify if auto redirect is enabled
/// </summary>
/// <value>AllowAutoRedirect</value>
public bool AllowAutoRedirect { get; private set; }
/// <summary>
/// Specify is handler has to use a cookie container
/// </summary>
/// <value>UseCookieContainer</value>
public bool UseCookieContainer { get; private set; }
/// <summary>
/// Specify is handler has to use a opentracing
/// </summary>
/// <value>UseTracing</value>
public bool UseTracing { get; private set; }
/// <summary>
/// Specify if handler has to use a proxy
/// </summary>
/// <value>UseProxy</value>
public bool UseProxy { get; private set; }
/// <summary>
/// Specify the maximum of concurrent connection to a network endpoint
/// </summary>
/// <value>MaxConnectionsPerServer</value>
public int MaxConnectionsPerServer { get; private set; }
}
}

View File

@ -6,6 +6,7 @@
private bool _useCookieContainer;
private bool _useTracing;
private bool _useProxy;
private int _maxConnectionPerServer;
public HttpHandlerOptionsBuilder WithAllowAutoRedirect(bool input)
{
@ -30,10 +31,16 @@
_useProxy = useProxy;
return this;
}
public HttpHandlerOptionsBuilder WithUseMaxConnectionPerServer(int maxConnectionPerServer)
{
_maxConnectionPerServer = maxConnectionPerServer;
return this;
}
public HttpHandlerOptions Build()
{
return new HttpHandlerOptions(_allowAutoRedirect, _useCookieContainer, _useTracing, _useProxy);
return new HttpHandlerOptions(_allowAutoRedirect, _useCookieContainer, _useTracing, _useProxy, _maxConnectionPerServer);
}
}
}

View File

@ -105,7 +105,8 @@ namespace Ocelot.Configuration.Repository
public void Dispose()
{
_timer.Dispose();
_timer?.Dispose();
_timer = null;
}
}
}

View File

@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
public class FileConfigurationFluentValidator : AbstractValidator<FileConfiguration>, IConfigurationValidator
@ -35,6 +36,10 @@
.Must((config, reRoute) => HaveServiceDiscoveryProviderRegistered(reRoute, config.GlobalConfiguration.ServiceDiscoveryProvider))
.WithMessage((config, reRoute) => $"Unable to start Ocelot, errors are: Unable to start Ocelot because either a ReRoute or GlobalConfiguration are using ServiceDiscoveryOptions but no ServiceDiscoveryFinderDelegate has been registered in dependency injection container. Are you missing a package like Ocelot.Provider.Consul and services.AddConsul() or Ocelot.Provider.Eureka and services.AddEureka()?");
RuleForEach(configuration => configuration.ReRoutes)
.Must((config, reRoute) => IsPlaceholderNotDuplicatedIn(reRoute.UpstreamPathTemplate))
.WithMessage((config, reRoute) => $"{nameof(reRoute)} {reRoute.UpstreamPathTemplate} has duplicated placeholder");
RuleFor(configuration => configuration.GlobalConfiguration.ServiceDiscoveryProvider)
.Must(HaveServiceDiscoveryProviderRegistered)
.WithMessage((config, reRoute) => $"Unable to start Ocelot, errors are: Unable to start Ocelot because either a ReRoute or GlobalConfiguration are using ServiceDiscoveryOptions but no ServiceDiscoveryFinderDelegate has been registered in dependency injection container. Are you missing a package like Ocelot.Provider.Consul and services.AddConsul() or Ocelot.Provider.Eureka and services.AddEureka()?");
@ -109,6 +114,14 @@
return reRoutesForAggregate.Count() == fileAggregateReRoute.ReRouteKeys.Count;
}
private bool IsPlaceholderNotDuplicatedIn(string upstreamPathTemplate)
{
Regex regExPlaceholder = new Regex("{[^}]+}");
var matches = regExPlaceholder.Matches(upstreamPathTemplate);
var upstreamPathPlaceholders = matches.Select(m => m.Value);
return upstreamPathPlaceholders.Count() == upstreamPathPlaceholders.Distinct().Count();
}
private static bool DoesNotContainReRoutesWithSpecificRequestIdKeys(FileAggregateReRoute fileAggregateReRoute,
List<FileReRoute> reRoutes)
{

View File

@ -37,7 +37,10 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
return;
}
if (!string.IsNullOrEmpty(context.DownstreamReRoute.DownstreamScheme))
{
context.DownstreamRequest.Scheme = context.DownstreamReRoute.DownstreamScheme;
}
if (ServiceFabricRequest(context))
{

View File

@ -45,6 +45,11 @@ namespace Ocelot.LoadBalancer.Middleware
context.DownstreamRequest.Port = hostAndPort.Data.DownstreamPort;
}
if (!string.IsNullOrEmpty(hostAndPort.Data.Scheme))
{
context.DownstreamRequest.Scheme = hostAndPort.Data.Scheme;
}
try
{
await _next.Invoke(context);

View File

@ -90,7 +90,9 @@ namespace Ocelot.Requester
{
AllowAutoRedirect = context.DownstreamReRoute.HttpHandlerOptions.AllowAutoRedirect,
UseCookies = context.DownstreamReRoute.HttpHandlerOptions.UseCookieContainer,
UseProxy = context.DownstreamReRoute.HttpHandlerOptions.UseProxy
UseProxy = context.DownstreamReRoute.HttpHandlerOptions.UseProxy,
MaxConnectionsPerServer = context.DownstreamReRoute.HttpHandlerOptions.MaxConnectionsPerServer
};
}
@ -101,6 +103,7 @@ namespace Ocelot.Requester
AllowAutoRedirect = context.DownstreamReRoute.HttpHandlerOptions.AllowAutoRedirect,
UseCookies = context.DownstreamReRoute.HttpHandlerOptions.UseCookieContainer,
UseProxy = context.DownstreamReRoute.HttpHandlerOptions.UseProxy,
MaxConnectionsPerServer = context.DownstreamReRoute.HttpHandlerOptions.MaxConnectionsPerServer,
CookieContainer = new CookieContainer()
};
}

View File

@ -34,7 +34,7 @@ namespace Ocelot.ServiceDiscovery
foreach (var downstreamAddress in reRoute.DownstreamAddresses)
{
var service = new Service(reRoute.ServiceName, new ServiceHostAndPort(downstreamAddress.Host, downstreamAddress.Port), string.Empty, string.Empty, new string[0]);
var service = new Service(reRoute.ServiceName, new ServiceHostAndPort(downstreamAddress.Host, downstreamAddress.Port, reRoute.DownstreamScheme), string.Empty, string.Empty, new string[0]);
services.Add(service);
}

View File

@ -8,8 +8,13 @@
DownstreamPort = downstreamPort;
}
public ServiceHostAndPort(string downstreamHost, int downstreamPort, string scheme)
: this(downstreamHost, downstreamPort) => Scheme = scheme;
public string DownstreamHost { get; }
public int DownstreamPort { get; }
public string Scheme { get; }
}
}

View File

@ -41,13 +41,13 @@ namespace Ocelot.UnitTests.Configuration
_internalConfigCreator = new Mock<IInternalConfigurationCreator>();
_internalConfigCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).ReturnsAsync(new OkResponse<IInternalConfiguration>(_internalConfig));
_poller = new FileConfigurationPoller(_factory.Object, _repo.Object, _config.Object, _internalConfigRepo.Object, _internalConfigCreator.Object);
_poller.StartAsync(new CancellationToken());
}
[Fact]
public void should_start()
{
this.Given(x => ThenTheSetterIsCalled(_fileConfig, 1))
this.Given(x => GivenPollerHasStarted())
.Given(x => ThenTheSetterIsCalled(_fileConfig, 1))
.BDDfy();
}
@ -71,7 +71,8 @@ namespace Ocelot.UnitTests.Configuration
}
};
this.Given(x => WhenTheConfigIsChanged(newConfig, 0))
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 0))
.Then(x => ThenTheSetterIsCalledAtLeast(newConfig, 1))
.BDDfy();
}
@ -96,7 +97,8 @@ namespace Ocelot.UnitTests.Configuration
}
};
this.Given(x => WhenTheConfigIsChanged(newConfig, 10))
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 10))
.Then(x => ThenTheSetterIsCalled(newConfig, 1))
.BDDfy();
}
@ -121,11 +123,24 @@ namespace Ocelot.UnitTests.Configuration
}
};
this.Given(x => WhenProviderErrors())
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenProviderErrors())
.Then(x => ThenTheSetterIsCalled(newConfig, 0))
.BDDfy();
}
[Fact]
public void should_dispose_cleanly_without_starting()
{
this.When(x => WhenPollerIsDisposed())
.BDDfy();
}
private void GivenPollerHasStarted()
{
_poller.StartAsync(CancellationToken.None);
}
private void WhenProviderErrors()
{
_repo
@ -141,6 +156,11 @@ namespace Ocelot.UnitTests.Configuration
.ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
}
private void WhenPollerIsDisposed()
{
_poller.Dispose();
}
private void ThenTheSetterIsCalled(FileConfiguration fileConfig, int times)
{
var result = WaitFor(4000).Until(() =>

View File

@ -41,7 +41,7 @@ namespace Ocelot.UnitTests.Configuration
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true);
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
@ -60,7 +60,7 @@ namespace Ocelot.UnitTests.Configuration
}
};
var expectedOptions = new HttpHandlerOptions(false, false, true, true);
var expectedOptions = new HttpHandlerOptions(false, false, true, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.And(x => GivenARealTracer())
@ -73,7 +73,7 @@ namespace Ocelot.UnitTests.Configuration
public void should_create_options_with_useCookie_false_and_allowAutoRedirect_true_as_default()
{
var fileReRoute = new FileReRoute();
var expectedOptions = new HttpHandlerOptions(false, false, false, true);
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
@ -94,7 +94,7 @@ namespace Ocelot.UnitTests.Configuration
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true);
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
@ -110,7 +110,7 @@ namespace Ocelot.UnitTests.Configuration
HttpHandlerOptions = new FileHttpHandlerOptions()
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true);
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
@ -129,7 +129,64 @@ namespace Ocelot.UnitTests.Configuration
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, false);
var expectedOptions = new HttpHandlerOptions(false, false, false, false, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_specified_MaxConnectionsPerServer()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = 10
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, 10);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = -1
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range_when_zero()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = 0
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
@ -154,6 +211,7 @@ namespace Ocelot.UnitTests.Configuration
_httpHandlerOptions.UseCookieContainer.ShouldBe(expected.UseCookieContainer);
_httpHandlerOptions.UseTracing.ShouldBe(expected.UseTracing);
_httpHandlerOptions.UseProxy.ShouldBe(expected.UseProxy);
_httpHandlerOptions.MaxConnectionsPerServer.ShouldBe(expected.MaxConnectionsPerServer);
}
private void GivenARealTracer()

View File

@ -1341,6 +1341,32 @@
.BDDfy();
}
[Fact]
public void configuration_is_invalid_when_placeholder_is_used_twice_in_upstream_path_template()
{
this.Given(x => x.GivenAConfiguration(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/bar/{everything}",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort() { Host = "a.b.cd" },
},
UpstreamPathTemplate = "/foo/bar/{everything}/{everything}",
UpstreamHttpMethod = new List<string> { "Get" },
},
},
}))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsNotValid())
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "reRoute /foo/bar/{everything}/{everything} has duplicated placeholder"))
.BDDfy();
}
private void GivenAConfiguration(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;

View File

@ -350,6 +350,36 @@
.BDDfy();
}
[Fact]
public void should_not_replace_by_empty_scheme()
{
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamScheme("")
.WithServiceName("Ocelot/OcelotApp")
.WithUseServiceDiscovery(true)
.Build();
var downstreamRoute = new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute)
.Build());
var config = new ServiceProviderConfigurationBuilder()
.WithType("ServiceFabric")
.WithHost("localhost")
.WithPort(19081)
.Build();
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheDownstreamRequestUriIs("https://localhost:19081?PartitionKind=test&PartitionKey=1"))
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1"))
.BDDfy();
}
private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config)
{
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null);

View File

@ -1,3 +1,5 @@
using System;
using System.Linq.Expressions;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.LoadBalancer
@ -108,6 +110,26 @@ namespace Ocelot.UnitTests.LoadBalancer
.BDDfy();
}
[Fact]
public void should_set_scheme()
{
var downstreamRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute, new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>()))
.And(x => x.GivenTheLoadBalancerHouseReturns())
.And(x => x.GivenTheLoadBalancerReturnsOk())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenAnHostAndPortIsSetOnPipeline())
.BDDfy();
}
private void WhenICallTheMiddleware()
{
_middleware = new LoadBalancingMiddleware(_next, _loggerFactory.Object, _loadBalancerHouse.Object);
@ -135,6 +157,13 @@ namespace Ocelot.UnitTests.LoadBalancer
.ReturnsAsync(_getHostAndPortError);
}
private void GivenTheLoadBalancerReturnsOk()
{
_loadBalancer
.Setup(x => x.Lease(It.IsAny<DownstreamContext>()))
.ReturnsAsync(new OkResponse<ServiceHostAndPort>(new ServiceHostAndPort("abc", 123, "https")));
}
private void GivenTheLoadBalancerReturns()
{
_hostAndPort = new ServiceHostAndPort("127.0.0.1", 80);
@ -186,6 +215,13 @@ namespace Ocelot.UnitTests.LoadBalancer
_downstreamContext.Errors.ShouldBe(_getHostAndPortError.Errors);
}
private void ThenAnHostAndPortIsSetOnPipeline()
{
_downstreamContext.DownstreamRequest.Host.ShouldBeEquivalentTo("abc");
_downstreamContext.DownstreamRequest.Port.ShouldBeEquivalentTo(123);
_downstreamContext.DownstreamRequest.Scheme.ShouldBeEquivalentTo("https");
}
private void ThenTheDownstreamUrlIsReplacedWith(string expectedUri)
{
_downstreamContext.DownstreamRequest.ToHttpRequestMessage().RequestUri.OriginalString.ShouldBe(expectedUri);

View File

@ -52,7 +52,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue))
.WithDelegatingHandlers(new List<string>
{
"FakeDelegatingHandler",
@ -88,7 +88,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue))
.WithDelegatingHandlers(new List<string>
{
"FakeDelegatingHandlerTwo",
@ -125,7 +125,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue))
.WithDelegatingHandlers(new List<string>
{
"FakeDelegatingHandlerTwo",
@ -161,7 +161,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue))
.WithDelegatingHandlers(new List<string>
{
"FakeDelegatingHandler",
@ -195,7 +195,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue))
.WithLoadBalancerKey("")
.Build();
@ -221,7 +221,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue))
.WithDelegatingHandlers(new List<string>
{
"FakeDelegatingHandler",
@ -249,7 +249,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue)).WithLoadBalancerKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
@ -269,7 +269,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue)).WithLoadBalancerKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheServiceProviderReturnsNothing())
@ -289,7 +289,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue)).WithLoadBalancerKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
@ -309,7 +309,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true, int.MaxValue)).WithLoadBalancerKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
@ -331,7 +331,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue))
.WithLoadBalancerKey("")
.Build();
@ -361,7 +361,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true, true, int.MaxValue))
.WithLoadBalancerKey("")
.Build();

View File

@ -52,7 +52,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -73,7 +73,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -99,7 +99,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -126,7 +126,7 @@ namespace Ocelot.UnitTests.Requester
var reRouteA = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -134,7 +134,7 @@ namespace Ocelot.UnitTests.Requester
var reRouteB = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -161,7 +161,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -184,7 +184,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -216,7 +216,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -252,7 +252,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())

View File

@ -57,7 +57,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(upstreamTemplate)
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -86,7 +86,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(upstreamTemplate)
.WithQosOptions(new QoSOptionsBuilder().Build())
@ -114,7 +114,7 @@ namespace Ocelot.UnitTests.Requester
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true, int.MaxValue))
.WithLoadBalancerKey("")
.WithUpstreamPathTemplate(upstreamTemplate)
.WithQosOptions(new QoSOptionsBuilder().WithTimeoutValue(1).Build())