mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	make rate limiting whitelist a function so users can override with dynamic behaviour
* Make rate-limiting client whitelist dynamic * Refactor `RateLimitOptions.ClientWhiteList` * Fix typo in variable `enbleRateLimiting` * Fix case in variable `clientIdheader` author Taiwo Otubamowo <totubamowo@deloitte.co.uk> * fix 1045 * #492 log 500 with error log level, acceptance test, unit test * #492 minor changes * 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 * test Co-authored-by: Taiwo O. <44668623+totubamowo@users.noreply.github.com> Co-authored-by: Catcher Wong <catcher_hwq@outlook.com> 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:
		@@ -1,74 +1,75 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
			
		||||
    <TargetFramework>netcoreapp3.1</TargetFramework>
 | 
			
		||||
    <AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
 | 
			
		||||
    <OutputType>Exe</OutputType>
 | 
			
		||||
    <PackageId>Ocelot.AcceptanceTests</PackageId>
 | 
			
		||||
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
			
		||||
    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
			
		||||
    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
 | 
			
		||||
    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
 | 
			
		||||
    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
 | 
			
		||||
    <CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Update="appsettings.product.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </None>
 | 
			
		||||
    <None Update="appsettings.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </None>
 | 
			
		||||
    <None Update="idsrv3test.pfx">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </None>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Tracing.Butterfly\Ocelot.Tracing.Butterfly.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Cache.CacheManager\Ocelot.Cache.CacheManager.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Provider.Consul\Ocelot.Provider.Consul.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Provider.Eureka\Ocelot.Provider.Eureka.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
 | 
			
		||||
    <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
 | 
			
		||||
    <PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
 | 
			
		||||
    <PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
 | 
			
		||||
    <PackageReference Include="xunit" Version="2.4.1" />
 | 
			
		||||
    <PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
 | 
			
		||||
    <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
 | 
			
		||||
    <PackageReference Include="IdentityServer4" Version="3.0.1" />
 | 
			
		||||
    <PackageReference Include="Consul" Version="0.7.2.6" />
 | 
			
		||||
    <PackageReference Include="Rafty" Version="0.4.4" />
 | 
			
		||||
    <PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
 | 
			
		||||
    <PackageReference Include="CacheManager.Serialization.Json" Version="2.0.0-beta-1629" />
 | 
			
		||||
    <PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
			
		||||
    <TargetFramework>netcoreapp3.1</TargetFramework>
 | 
			
		||||
    <AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
 | 
			
		||||
    <OutputType>Exe</OutputType>
 | 
			
		||||
    <PackageId>Ocelot.AcceptanceTests</PackageId>
 | 
			
		||||
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
			
		||||
    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
			
		||||
    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
 | 
			
		||||
    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
 | 
			
		||||
    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
 | 
			
		||||
    <CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Update="appsettings.product.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </None>
 | 
			
		||||
    <None Update="appsettings.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </None>
 | 
			
		||||
    <None Update="idsrv3test.pfx">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </None>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Tracing.Butterfly\Ocelot.Tracing.Butterfly.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Cache.CacheManager\Ocelot.Cache.CacheManager.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Provider.Consul\Ocelot.Provider.Consul.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Provider.Eureka\Ocelot.Provider.Eureka.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
 | 
			
		||||
    <PackageReference Include="Moq" Version="4.13.0" />
 | 
			
		||||
    <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.66">
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
 | 
			
		||||
    <PackageReference Include="Shouldly" Version="4.0.0-beta0002" />
 | 
			
		||||
    <PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
 | 
			
		||||
    <PackageReference Include="xunit" Version="2.4.1" />
 | 
			
		||||
    <PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
 | 
			
		||||
    <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
 | 
			
		||||
    <PackageReference Include="IdentityServer4" Version="3.0.1" />
 | 
			
		||||
    <PackageReference Include="Consul" Version="0.7.2.6" />
 | 
			
		||||
    <PackageReference Include="Rafty" Version="0.4.4" />
 | 
			
		||||
    <PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="2.0.0-beta-1629" />
 | 
			
		||||
    <PackageReference Include="CacheManager.Serialization.Json" Version="2.0.0-beta-1629" />
 | 
			
		||||
    <PackageReference Include="Pivotal.Discovery.ClientCore" Version="2.2.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -34,7 +34,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 50092,
 | 
			
		||||
                                    Port = 51092,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/{everything}",
 | 
			
		||||
@@ -43,7 +43,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:50092", "/inline.132.bundle.js", 304))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51092", "/inline.132.bundle.js", 304))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/inline.132.bundle.js"))
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,8 @@
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_internal_server_error_if_downstream_service_returns_internal_server_error()
 | 
			
		||||
        {
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -49,6 +50,39 @@
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.InternalServerError))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_log_warning_if_downstream_service_returns_internal_server_error()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 53876,
 | 
			
		||||
                                },
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53876"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunningWithLogger())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenWarningShouldBeLogged())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string url)
 | 
			
		||||
 
 | 
			
		||||
@@ -10,12 +10,14 @@
 | 
			
		||||
    using Microsoft.Extensions.Configuration;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Microsoft.Extensions.Logging;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Newtonsoft.Json;
 | 
			
		||||
    using Ocelot.Cache.CacheManager;
 | 
			
		||||
    using Ocelot.Configuration.Creator;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using Ocelot.DependencyInjection;
 | 
			
		||||
    using Ocelot.Infrastructure;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
    using Ocelot.Provider.Consul;
 | 
			
		||||
@@ -1120,5 +1122,60 @@
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenOcelotIsRunningWithLogger()
 | 
			
		||||
        {
 | 
			
		||||
            _webHostBuilder = new WebHostBuilder();
 | 
			
		||||
 | 
			
		||||
            _webHostBuilder
 | 
			
		||||
                .ConfigureAppConfiguration((hostingContext, config) =>
 | 
			
		||||
                {
 | 
			
		||||
                    config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
 | 
			
		||||
                    var env = hostingContext.HostingEnvironment;
 | 
			
		||||
                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
 | 
			
		||||
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
 | 
			
		||||
                    config.AddJsonFile("ocelot.json", false, false);
 | 
			
		||||
                    config.AddEnvironmentVariables();
 | 
			
		||||
                })
 | 
			
		||||
                .ConfigureServices(s =>
 | 
			
		||||
                {
 | 
			
		||||
                    s.AddOcelot();
 | 
			
		||||
                    s.AddSingleton<IOcelotLoggerFactory, MockLoggerFactory>();
 | 
			
		||||
                })
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.UseOcelot().Wait();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            _ocelotServer = new TestServer(_webHostBuilder);
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ThenWarningShouldBeLogged()
 | 
			
		||||
        {
 | 
			
		||||
            MockLoggerFactory loggerFactory = (MockLoggerFactory)_ocelotServer.Host.Services.GetService<IOcelotLoggerFactory>();
 | 
			
		||||
            loggerFactory.Verify();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal class MockLoggerFactory : IOcelotLoggerFactory
 | 
			
		||||
        {
 | 
			
		||||
            private Mock<IOcelotLogger> _logger;
 | 
			
		||||
 | 
			
		||||
            public IOcelotLogger CreateLogger<T>()
 | 
			
		||||
            {
 | 
			
		||||
                if (_logger == null)
 | 
			
		||||
                {
 | 
			
		||||
                    _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
                    _logger.Setup(x => x.LogWarning(It.IsAny<string>())).Verifiable();
 | 
			
		||||
                }
 | 
			
		||||
                return _logger.Object;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public void Verify()
 | 
			
		||||
            {
 | 
			
		||||
                _logger.Verify(x => x.LogWarning(It.IsAny<string>()), Times.Once);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            };
 | 
			
		||||
            var expected = new RateLimitOptionsBuilder()
 | 
			
		||||
                .WithClientIdHeader("ClientIdHeader")
 | 
			
		||||
                .WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist)
 | 
			
		||||
                .WithClientWhiteList(() => fileReRoute.RateLimitOptions.ClientWhitelist)
 | 
			
		||||
                .WithDisableRateLimitHeaders(true)
 | 
			
		||||
                .WithEnableRateLimiting(true)
 | 
			
		||||
                .WithHttpStatusCode(200)
 | 
			
		||||
 
 | 
			
		||||
@@ -49,15 +49,15 @@ namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_middleware_and_ratelimiting()
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamTemplate = new UpstreamPathTemplateBuilder().Build();
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamTemplate = new UpstreamPathTemplateBuilder().Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithEnableRateLimiting(true)
 | 
			
		||||
                .WithRateLimitOptions(new RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new RateLimitRule("1s", 100, 3), 429))
 | 
			
		||||
                .WithRateLimitOptions(new RateLimitOptions(true, "ClientId", () => new List<string>(), false, "", "", new RateLimitRule("1s", 100, 3), 429))
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .WithUpstreamPathTemplate(upstreamTemplate)
 | 
			
		||||
                .Build();
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
@@ -82,7 +82,7 @@ namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
                     .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                         .WithEnableRateLimiting(true)
 | 
			
		||||
                         .WithRateLimitOptions(
 | 
			
		||||
                             new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule("1s", 100, 3), 429))
 | 
			
		||||
                             new Ocelot.Configuration.RateLimitOptions(true, "ClientId", () => new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule("1s", 100, 3), 429))
 | 
			
		||||
                         .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                         .Build())
 | 
			
		||||
                     .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
@@ -102,8 +102,8 @@ namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddlewareMultipleTime(int times)
 | 
			
		||||
        {
 | 
			
		||||
            var clientId = "ocelotclient1";
 | 
			
		||||
 | 
			
		||||
            var clientId = "ocelotclient1";
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < times; i++)
 | 
			
		||||
            {
 | 
			
		||||
                var request = new HttpRequestMessage(new HttpMethod("GET"), _url);
 | 
			
		||||
@@ -117,8 +117,8 @@ namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddlewareWithWhiteClient()
 | 
			
		||||
        {
 | 
			
		||||
            var clientId = "ocelotclient2";
 | 
			
		||||
 | 
			
		||||
            var clientId = "ocelotclient2";
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < 10; i++)
 | 
			
		||||
            {
 | 
			
		||||
                var request = new HttpRequestMessage(new HttpMethod("GET"), _url);
 | 
			
		||||
@@ -127,10 +127,10 @@ namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
                _downstreamContext.HttpContext.Request.Headers.TryAdd("ClientId", clientId);
 | 
			
		||||
 | 
			
		||||
                _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
                _responseStatusCode = (int)_downstreamContext.HttpContext.Response.StatusCode;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                _responseStatusCode = (int)_downstreamContext.HttpContext.Response.StatusCode;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenresponseStatusCodeIs429()
 | 
			
		||||
        {
 | 
			
		||||
            _responseStatusCode.ShouldBe(429);
 | 
			
		||||
@@ -145,7 +145,7 @@ namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
    internal class FakeStream : Stream
 | 
			
		||||
    {
 | 
			
		||||
        public override void Flush()
 | 
			
		||||
        {
 | 
			
		||||
        {
 | 
			
		||||
            //do nothing
 | 
			
		||||
            //throw new System.NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
@@ -176,4 +176,4 @@ namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
        public override long Length { get; }
 | 
			
		||||
        public override long Position { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,14 @@
 | 
			
		||||
            error.ShouldBeOfType<RequestCanceledError>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_request_canceled_for_subtype()
 | 
			
		||||
        {
 | 
			
		||||
            var error = _mapper.Map(new SomeException());
 | 
			
		||||
 | 
			
		||||
            error.ShouldBeOfType<RequestCanceledError>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error_from_mapper()
 | 
			
		||||
        {
 | 
			
		||||
@@ -56,5 +64,8 @@
 | 
			
		||||
 | 
			
		||||
            error.ShouldBeOfType<AnyError>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private class SomeException : OperationCanceledException
 | 
			
		||||
        { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,9 +41,10 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        public void should_call_services_correctly()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs())
 | 
			
		||||
                .And(x => x.GivenTheRequesterReturns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage())))
 | 
			
		||||
                .And(x => x.GivenTheRequesterReturns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage(System.Net.HttpStatusCode.OK))))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheDownstreamResponseIsSet())
 | 
			
		||||
                .Then(x => InformationIsLogged())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -57,6 +58,17 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_log_downstream_internal_server_error()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs())
 | 
			
		||||
                    .And(x => x.GivenTheRequesterReturns(
 | 
			
		||||
                        new OkResponse<HttpResponseMessage>(new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError))))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.WarningIsLogged())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIsSet()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.IsError.ShouldBeTrue();
 | 
			
		||||
@@ -98,5 +110,23 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
            _downstreamContext.DownstreamResponse.Content.ShouldBe(_response.Data.Content);
 | 
			
		||||
            _downstreamContext.DownstreamResponse.StatusCode.ShouldBe(_response.Data.StatusCode);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WarningIsLogged()
 | 
			
		||||
        {
 | 
			
		||||
            _logger.Verify(
 | 
			
		||||
                x => x.LogWarning(                 
 | 
			
		||||
                    It.IsAny<string>()
 | 
			
		||||
                   ),
 | 
			
		||||
                Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InformationIsLogged()
 | 
			
		||||
        {
 | 
			
		||||
            _logger.Verify(
 | 
			
		||||
                x => x.LogInformation(
 | 
			
		||||
                    It.IsAny<string>()
 | 
			
		||||
                ),
 | 
			
		||||
                Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user