diff --git a/build.cake b/build.cake index 20d40a4e..be56fa3f 100644 --- a/build.cake +++ b/build.cake @@ -310,9 +310,10 @@ Task("DownloadGitHubReleaseArtifacts") Information("Release url " + releaseUrl); - var assets_url = ParseJson(GetResource(releaseUrl)) - .GetValue("assets_url") - .Value(); + var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl)); + + //todo - remove when publish working..var assets_url = ParseJson(GetResource(releaseUrl)) + assets_url.GetValue("assets_url").Value(); Information("Assets url " + assets_url); diff --git a/src/Ocelot/Configuration/Creator/UpstreamTemplatePatternCreator.cs b/src/Ocelot/Configuration/Creator/UpstreamTemplatePatternCreator.cs index 95b339a9..4e02a158 100644 --- a/src/Ocelot/Configuration/Creator/UpstreamTemplatePatternCreator.cs +++ b/src/Ocelot/Configuration/Creator/UpstreamTemplatePatternCreator.cs @@ -41,8 +41,8 @@ namespace Ocelot.Configuration.Creator } var route = reRoute.ReRouteIsCaseSensitive - ? $"{upstreamTemplate}{RegExMatchEndString}" - : $"{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}"; + ? $"^{upstreamTemplate}{RegExMatchEndString}" + : $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}"; return route; } diff --git a/test/Ocelot.AcceptanceTests/QoSTests.cs b/test/Ocelot.AcceptanceTests/QoSTests.cs index 8825b75b..e8a8e6a1 100644 --- a/test/Ocelot.AcceptanceTests/QoSTests.cs +++ b/test/Ocelot.AcceptanceTests/QoSTests.cs @@ -98,7 +98,7 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = "http", DownstreamHost = "localhost", DownstreamPort = 51880, - UpstreamPathTemplate = "working", + UpstreamPathTemplate = "/working", UpstreamHttpMethod = new List { "Get" }, } } diff --git a/test/Ocelot.AcceptanceTests/RoutingTests.cs b/test/Ocelot.AcceptanceTests/RoutingTests.cs index 648cbd71..9a79a632 100644 --- a/test/Ocelot.AcceptanceTests/RoutingTests.cs +++ b/test/Ocelot.AcceptanceTests/RoutingTests.cs @@ -443,6 +443,46 @@ namespace Ocelot.AcceptanceTests .BDDfy(); } + [Fact] + public void should_return_404_when_calling_upstream_route_with_no_matching_downstream_re_route_github_issue_134() + { + var configuration = new FileConfiguration + { + ReRoutes = new List + { + new FileReRoute + { + DownstreamPathTemplate = "/api/v1/vacancy", + DownstreamScheme = "http", + DownstreamHost = "localhost", + DownstreamPort = 51879, + UpstreamPathTemplate = "/vacancy/", + UpstreamHttpMethod = new List { "Options", "Put", "Get", "Post", "Delete" }, + ServiceName = "botCore", + LoadBalancer = "LeastConnection" + }, + new FileReRoute + { + DownstreamPathTemplate = "/api/v1/vacancy/{vacancyId}", + DownstreamScheme = "http", + DownstreamHost = "localhost", + DownstreamPort = 51879, + UpstreamPathTemplate = "/vacancy/{vacancyId}", + UpstreamHttpMethod = new List { "Options", "Put", "Get", "Post", "Delete" }, + ServiceName = "botCore", + LoadBalancer = "LeastConnection" + } + } + }; + + this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/v1/vacancy/1", 200, "Hello from Laura")) + .And(x => _steps.GivenThereIsAConfiguration(configuration)) + .And(x => _steps.GivenOcelotIsRunning()) + .When(x => _steps.WhenIGetUrlOnTheApiGateway("api/vacancy/1")) + .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound)) + .BDDfy(); + } + private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody) { _builder = new WebHostBuilder() @@ -453,7 +493,7 @@ namespace Ocelot.AcceptanceTests .Configure(app => { app.Run(async context => - { + { _downstreamPath = context.Request.PathBase.Value; context.Response.StatusCode = statusCode; await context.Response.WriteAsync(responseBody); diff --git a/test/Ocelot.UnitTests/Configuration/UpstreamTemplatePatternCreatorTests.cs b/test/Ocelot.UnitTests/Configuration/UpstreamTemplatePatternCreatorTests.cs index 34db1232..21c5be38 100644 --- a/test/Ocelot.UnitTests/Configuration/UpstreamTemplatePatternCreatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/UpstreamTemplatePatternCreatorTests.cs @@ -28,7 +28,7 @@ namespace Ocelot.UnitTests.Configuration this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("(?i)/PRODUCTS/.*/$")) + .Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.*/$")) .BDDfy(); } @@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.Configuration }; this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("/PRODUCTS/.*/$")) + .Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.*/$")) .BDDfy(); } @@ -57,7 +57,7 @@ namespace Ocelot.UnitTests.Configuration this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/$")) + .Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/$")) .BDDfy(); } @@ -72,7 +72,7 @@ namespace Ocelot.UnitTests.Configuration this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$")) + .Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/variants/.*/$")) .BDDfy(); } [Fact] @@ -86,7 +86,7 @@ namespace Ocelot.UnitTests.Configuration this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$")) + .Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/variants/.*/$")) .BDDfy(); } diff --git a/test/Ocelot.UnitTests/DownstreamRouteFinder/UrlMatcher/RegExUrlMatcherTests.cs b/test/Ocelot.UnitTests/DownstreamRouteFinder/UrlMatcher/RegExUrlMatcherTests.cs index 70dd747d..9f76228b 100644 --- a/test/Ocelot.UnitTests/DownstreamRouteFinder/UrlMatcher/RegExUrlMatcherTests.cs +++ b/test/Ocelot.UnitTests/DownstreamRouteFinder/UrlMatcher/RegExUrlMatcherTests.cs @@ -28,6 +28,16 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher .BDDfy(); } + [Fact] + public void should_not_match_issue_134() + { + this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.*/$")) + .When(x => x.WhenIMatchThePaths()) + .And(x => x.ThenTheResultIsFalse()) + .BDDfy(); + } + [Fact] public void should_match_forward_slash_only_regex() { @@ -42,7 +52,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void should_find_match_when_template_smaller_than_valid_path() { this.Given(x => x.GivenIHaveAUpstreamPath("/api/products/2354325435624623464235")) - .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("/api/products/.*$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/api/products/.*$")) .When(x => x.WhenIMatchThePaths()) .And(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -52,7 +62,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void should_not_find_match() { this.Given(x => x.GivenIHaveAUpstreamPath("/api/values")) - .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("/$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$")) .When(x => x.WhenIMatchThePaths()) .And(x => x.ThenTheResultIsFalse()) .BDDfy(); @@ -62,7 +72,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url() { this.Given(x => x.GivenIHaveAUpstreamPath("")) - .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^$")) .When(x => x.WhenIMatchThePaths()) .And(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -72,7 +82,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_no_slash() { this.Given(x => x.GivenIHaveAUpstreamPath("api")) - .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api$")) + .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -82,7 +92,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_one_slash() { this.Given(x => x.GivenIHaveAUpstreamPath("api/")) - .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/$")) + .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -92,7 +102,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_downstream_template() { this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/")) - .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/$")) + .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -102,7 +112,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_downstream_template_with_one_place_holder() { this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1")) - .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*$")) + .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -112,7 +122,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_downstream_template_with_two_place_holders() { this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2")) - .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/.*$")) + .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/.*$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -122,7 +132,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something() { this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2")) - .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -132,7 +142,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something() { this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123")) - .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/.*$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/.*$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -142,7 +152,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher public void can_match_down_stream_url_with_downstream_template_with_three_place_holders() { this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/")) - .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -152,7 +162,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher 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/$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)api/product/products/.*/categories/.*/variant/$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsTrue()) .BDDfy(); @@ -162,7 +172,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher 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/$")) + .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$")) .When(x => x.WhenIMatchThePaths()) .Then(x => x.ThenTheResultIsFalse()) .BDDfy();