mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 07:08:14 +08:00
Now defaults to case insensitive routing but you can override with a setting, also global request id setting available
This commit is contained in:
200
test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs
Normal file
200
test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs
Normal file
@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Configuration.File;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.AcceptanceTests
|
||||
{
|
||||
public class CaseSensitiveRoutingTests : IDisposable
|
||||
{
|
||||
private IWebHost _builder;
|
||||
private readonly Steps _steps;
|
||||
|
||||
public CaseSensitiveRoutingTests()
|
||||
{
|
||||
_steps = new Steps();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_response_200_when_global_ignore_case_sensitivity_set()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamTemplate = "http://localhost:51879/api/products/{productId}",
|
||||
UpstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_response_200_when_reroute_ignore_case_sensitivity_set()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamTemplate = "http://localhost:51879/api/products/{productId}",
|
||||
UpstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_response_404_when_reroute_respect_case_sensitivity_set()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamTemplate = "http://localhost:51879/api/products/{productId}",
|
||||
UpstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_response_200_when_reroute_respect_case_sensitivity_set()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamTemplate = "http://localhost:51879/api/products/{productId}",
|
||||
UpstreamTemplate = "/PRODUCTS/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_response_404_when_global_respect_case_sensitivity_set()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamTemplate = "http://localhost:51879/api/products/{productId}",
|
||||
UpstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_response_200_when_global_respect_case_sensitivity_set()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamTemplate = "http://localhost:51879/api/products/{productId}",
|
||||
UpstreamTemplate = "/PRODUCTS/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
|
||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
||||
{
|
||||
_builder = new WebHostBuilder()
|
||||
.UseUrls(url)
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.UseUrls(url)
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(async context =>
|
||||
{
|
||||
context.Response.StatusCode = statusCode;
|
||||
await context.Response.WriteAsync(responseBody);
|
||||
});
|
||||
})
|
||||
.Build();
|
||||
|
||||
_builder.Start();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_builder?.Dispose();
|
||||
_steps.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -76,6 +76,36 @@ namespace Ocelot.AcceptanceTests
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_global_request_id_and_forward()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamTemplate = "http://localhost:51879/",
|
||||
UpstreamTemplate = "/",
|
||||
UpstreamHttpMethod = "Get",
|
||||
}
|
||||
},
|
||||
GlobalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = _steps.RequestIdKey
|
||||
}
|
||||
};
|
||||
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
|
||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/", requestId))
|
||||
.Then(x => _steps.ThenTheRequestIdIsReturned(requestId))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsAServiceRunningOn(string url)
|
||||
{
|
||||
_builder = new WebHostBuilder()
|
||||
|
@ -1 +1 @@
|
||||
{"ReRoutes":[{"DownstreamTemplate":"http://localhost:41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0}}]}
|
||||
{"ReRoutes":[{"DownstreamTemplate":"http://localhost:41879/","UpstreamTemplate":"/","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}],"GlobalConfiguration":{"RequestIdKey":null}}
|
@ -36,7 +36,37 @@ namespace Ocelot.UnitTests.Configuration
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
||||
public void should_use_reroute_case_sensitivity_value()
|
||||
{
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamTemplate = "/api/products/{productId}",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = false
|
||||
}
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamTemplate("/products/{productId}")
|
||||
.WithUpstreamTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod("Get")
|
||||
.WithUpstreamTemplatePattern("(?i)/api/products/.*$")
|
||||
.Build()
|
||||
}))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
|
||||
{
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
@ -49,6 +79,101 @@ namespace Ocelot.UnitTests.Configuration
|
||||
UpstreamHttpMethod = "Get"
|
||||
}
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamTemplate("/products/{productId}")
|
||||
.WithUpstreamTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod("Get")
|
||||
.WithUpstreamTemplatePattern("(?i)/api/products/.*$")
|
||||
.Build()
|
||||
}))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
|
||||
{
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamTemplate = "/api/products/{productId}",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamTemplate("/products/{productId}")
|
||||
.WithUpstreamTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod("Get")
|
||||
.WithUpstreamTemplatePattern("/api/products/.*$")
|
||||
.Build()
|
||||
}))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_global_request_id_key()
|
||||
{
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamTemplate = "/api/products/{productId}",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
},
|
||||
GlobalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = "blahhhh"
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamTemplate("/products/{productId}")
|
||||
.WithUpstreamTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod("Get")
|
||||
.WithUpstreamTemplatePattern("/api/products/.*$")
|
||||
.WithRequestIdKey("blahhhh")
|
||||
.Build()
|
||||
}))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
||||
{
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamTemplate = "/api/products/{productId}",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
@ -95,6 +220,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
UpstreamTemplate = "/api/products/{productId}",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true,
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AdditionalScopes = new List<string>(),
|
||||
@ -153,6 +279,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
UpstreamTemplate = "/api/products/{productId}",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true,
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AdditionalScopes = new List<string>(),
|
||||
@ -183,7 +310,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
UpstreamTemplate = "/api/products/{productId}/variants/{variantId}",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get"
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
}))
|
||||
@ -212,7 +340,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
UpstreamTemplate = "/api/products/{productId}/variants/{variantId}/",
|
||||
DownstreamTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = "Get"
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
}))
|
||||
@ -241,7 +370,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
UpstreamTemplate = "/",
|
||||
DownstreamTemplate = "/api/products/",
|
||||
UpstreamHttpMethod = "Get"
|
||||
UpstreamHttpMethod = "Get",
|
||||
ReRouteIsCaseSensitive = true
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
@ -128,6 +128,27 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_ignore_case_sensitivity()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("(?i)api/product/products/.*/categories/.*/variant/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.Then(x => x.ThenTheResultIsTrue())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_respect_case_sensitivity()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.Then(x => x.ThenTheResultIsFalse())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
private void GivenIHaveAUpstreamPath(string downstreamPath)
|
||||
{
|
||||
_downstreamUrlPath = downstreamPath;
|
||||
|
Reference in New Issue
Block a user