mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 16:30:48 +08:00 
			
		
		
		
	Changed routing to support a catch all style
This commit is contained in:
		@@ -52,7 +52,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -61,6 +61,108 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_favouring_forward_slash_with_path_route()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHost = "localhost",
 | 
			
		||||
                            DownstreamPort = 51880,
 | 
			
		||||
                            UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHost = "localhost",
 | 
			
		||||
                            DownstreamPort = 51879,
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51880/", "/test", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/test"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_favouring_forward_slash_route_because_it_is_first()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHost = "localhost",
 | 
			
		||||
                            DownstreamPort = 51880,
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHost = "localhost",
 | 
			
		||||
                            DownstreamPort = 51879,
 | 
			
		||||
                            UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51880/", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_with_nothing_and_placeholder_only()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHost = "localhost",
 | 
			
		||||
                            DownstreamPort = 51879,
 | 
			
		||||
                            UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway(""))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_with_simple_url()
 | 
			
		||||
        {
 | 
			
		||||
@@ -80,7 +182,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -378,7 +480,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 201, string.Empty))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 201, string.Empty))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenThePostHasContent("postContent"))
 | 
			
		||||
@@ -406,7 +508,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/newThing", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/newThing?DeviceType=IphoneApp&Browser=moonpigIphone&BrowserString=-&CountryCode=123&DeviceName=iPhone 5 (GSM+CDMA)&OperatingSystem=iPhone OS 7.1.2&BrowserVersion=3708AdHoc&ipAddress=-"))
 | 
			
		||||
@@ -434,7 +536,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/myApp1Name/api/products/1", 200, "Some Product"))
 | 
			
		||||
            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("/myApp1Name/api/products/1"))
 | 
			
		||||
@@ -490,7 +592,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -564,7 +666,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", "", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", "/api/swagger/lib/backbone-min.js", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/platform/swagger/lib/backbone-min.js"))
 | 
			
		||||
@@ -587,8 +689,17 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    app.Run(async context =>
 | 
			
		||||
                    {   
 | 
			
		||||
                        _downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
 | 
			
		||||
                        context.Response.StatusCode = statusCode;
 | 
			
		||||
                        await context.Response.WriteAsync(responseBody);
 | 
			
		||||
 | 
			
		||||
                        if(_downstreamPath != basePath)
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync("downstream path didnt match base path");
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync(responseBody);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,18 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
            _urlMatcher = new RegExUrlMatcher();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_match_slash_becaue_we_need_to_match_something_after_it()
 | 
			
		||||
        {
 | 
			
		||||
            const string RegExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].*";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenIHaveAUpstreamPath("/"))
 | 
			
		||||
              .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(RegExForwardSlashAndOnePlaceHolder))
 | 
			
		||||
              .When(x => x.WhenIMatchThePaths())
 | 
			
		||||
              .And(x => x.ThenTheResultIsFalse())
 | 
			
		||||
              .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_match_forward_slash_only_regex()
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,14 +8,14 @@ using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
{
 | 
			
		||||
    public class UrlPathToUrlTemplateMatcherTests 
 | 
			
		||||
    public class UrlPathPlaceholderNameAndValueFinderTests 
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IUrlPathPlaceholderNameAndValueFinder _finder;
 | 
			
		||||
        private string _downstreamUrlPath;
 | 
			
		||||
        private string _downstreamPathTemplate;
 | 
			
		||||
        private Response<List<UrlPathPlaceholderNameAndValue>> _result;
 | 
			
		||||
 | 
			
		||||
        public UrlPathToUrlTemplateMatcherTests()
 | 
			
		||||
        public UrlPathPlaceholderNameAndValueFinderTests()
 | 
			
		||||
        {
 | 
			
		||||
            _finder = new UrlPathPlaceholderNameAndValueFinder();
 | 
			
		||||
        }
 | 
			
		||||
@@ -30,6 +30,81 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void can_match_down_stream_url_with_nothing_then_placeholder_no_value_is_blank()
 | 
			
		||||
        {
 | 
			
		||||
            var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> 
 | 
			
		||||
            {
 | 
			
		||||
                new UrlPathPlaceholderNameAndValue("{url}", "")
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenIHaveAUpstreamPath(""))
 | 
			
		||||
                .And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
 | 
			
		||||
                .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
 | 
			
		||||
                .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void can_match_down_stream_url_with_nothing_then_placeholder_value_is_test()
 | 
			
		||||
        {
 | 
			
		||||
            var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> 
 | 
			
		||||
            {
 | 
			
		||||
                new UrlPathPlaceholderNameAndValue("{url}", "test")
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenIHaveAUpstreamPath("/test"))
 | 
			
		||||
                .And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
 | 
			
		||||
                .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
 | 
			
		||||
                .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void can_match_down_stream_url_with_forward_slash_then_placeholder_no_value_is_blank()
 | 
			
		||||
        {
 | 
			
		||||
            var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> 
 | 
			
		||||
            {
 | 
			
		||||
                new UrlPathPlaceholderNameAndValue("{url}", "")
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenIHaveAUpstreamPath("/"))
 | 
			
		||||
                .And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
 | 
			
		||||
                .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
 | 
			
		||||
                .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void can_match_down_stream_url_with_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> 
 | 
			
		||||
            {
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenIHaveAUpstreamPath("/"))
 | 
			
		||||
                .And(x => x.GivenIHaveAnUpstreamUrlTemplate("/"))
 | 
			
		||||
                .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
 | 
			
		||||
                .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void can_match_down_stream_url_with_forward_slash_then_placeholder_then_another_value()
 | 
			
		||||
        {
 | 
			
		||||
            var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> 
 | 
			
		||||
            {
 | 
			
		||||
                new UrlPathPlaceholderNameAndValue("{url}", "1")
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenIHaveAUpstreamPath("/1/products"))
 | 
			
		||||
                .And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}/products"))
 | 
			
		||||
                .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
 | 
			
		||||
                .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_find_anything()
 | 
			
		||||
        {
 | 
			
		||||
@@ -169,8 +244,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var expectedResult in expectedResults)
 | 
			
		||||
            {
 | 
			
		||||
                var result = _result.Data
 | 
			
		||||
                    .First(t => t.TemplateVariableName == expectedResult.TemplateVariableName);
 | 
			
		||||
                var result = _result.Data.First(t => t.TemplateVariableName == expectedResult.TemplateVariableName);
 | 
			
		||||
                result.TemplateVariableValue.ShouldBe(expectedResult.TemplateVariableValue);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
		Reference in New Issue
	
	Block a user