mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
Changed routing to support a catch all style
This commit is contained in:
parent
931a115ffa
commit
9cb201cfa9
@ -63,3 +63,36 @@ In order to change this you can specify on a per ReRoute basis the following set
|
|||||||
This means that when Ocelot tries to match the incoming upstream url with an upstream template the
|
This means that when Ocelot tries to match the incoming upstream url with an upstream template the
|
||||||
evaluation will be case sensitive. This setting defaults to false so only set it if you want
|
evaluation will be case sensitive. This setting defaults to false so only set it if you want
|
||||||
the ReRoute to be case sensitive is my advice!
|
the ReRoute to be case sensitive is my advice!
|
||||||
|
|
||||||
|
Catch All
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
Ocelot's routing also supports a catch all style routing where the user can specify that they want to match all traffic if you set up your config like below the request will be proxied straight through (it doesnt have to be url any placeholder name will work).
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"DownstreamPathTemplate": "/{url}",
|
||||||
|
"DownstreamScheme": "https",
|
||||||
|
"DownstreamPort": 80,
|
||||||
|
"DownstreamHost" "localhost",
|
||||||
|
"UpstreamPathTemplate": "/{url}",
|
||||||
|
"UpstreamHttpMethod": [ "Get" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
There is a gotcha if you want to do this kind of thing. The order of the ReRoutes in the config will now matter.
|
||||||
|
|
||||||
|
If you had this ReRoute after the catch all then it would never be matched. However if it was before the catch all it would match first.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"DownstreamPathTemplate": "/",
|
||||||
|
"DownstreamScheme": "https",
|
||||||
|
"DownstreamPort": 80,
|
||||||
|
"DownstreamHost" "10.0.10.1",
|
||||||
|
"UpstreamPathTemplate": "/",
|
||||||
|
"UpstreamHttpMethod": [ "Get" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
This is because when Ocelot tries to match a request to a ReRoute it has to look at all the possible matches and uses a regular expression to test the url.
|
@ -26,6 +26,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
var placeHolderName = upstreamTemplate.Substring(i, difference);
|
var placeHolderName = upstreamTemplate.Substring(i, difference);
|
||||||
placeholders.Add(placeHolderName);
|
placeholders.Add(placeHolderName);
|
||||||
|
|
||||||
|
//hack to handle /{url} case
|
||||||
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
|
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
|
||||||
{
|
{
|
||||||
return RegExForwardSlashAndOnePlaceHolder;
|
return RegExForwardSlashAndOnePlaceHolder;
|
||||||
|
@ -34,6 +34,30 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
|
|||||||
|
|
||||||
return new OkResponse<List<UrlPathPlaceholderNameAndValue>>(templateKeysAndValues);
|
return new OkResponse<List<UrlPathPlaceholderNameAndValue>>(templateKeysAndValues);
|
||||||
}
|
}
|
||||||
|
//hacking to handle special case of /{url}
|
||||||
|
//if this char is a forward slash and the template starts with /{ and last character of string is the next }
|
||||||
|
else if(string.IsNullOrEmpty(upstreamUrlPath) || (upstreamUrlPath.Length > counterForUrl && upstreamUrlPath[counterForUrl] == '/') && upstreamUrlPathTemplate.Length > 1
|
||||||
|
&& upstreamUrlPathTemplate.Substring(0, 2) == "/{"
|
||||||
|
&& upstreamUrlPathTemplate.IndexOf('}') == upstreamUrlPathTemplate.Length - 1)
|
||||||
|
{
|
||||||
|
var endOfPlaceholder = GetNextCounterPosition(upstreamUrlPathTemplate, counterForTemplate, '}');
|
||||||
|
var variableName = GetPlaceholderVariableName(upstreamUrlPathTemplate, 1);
|
||||||
|
|
||||||
|
UrlPathPlaceholderNameAndValue templateVariableNameAndValue;
|
||||||
|
|
||||||
|
if(upstreamUrlPath.Length == 1 || upstreamUrlPath.Length == 0)
|
||||||
|
{
|
||||||
|
templateVariableNameAndValue = new UrlPathPlaceholderNameAndValue(variableName, "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var variableValue = GetPlaceholderVariableValue(upstreamUrlPathTemplate, variableName, upstreamUrlPath, counterForUrl + 1);
|
||||||
|
templateVariableNameAndValue = new UrlPathPlaceholderNameAndValue(variableName, variableValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
templateKeysAndValues.Add(templateVariableNameAndValue);
|
||||||
|
counterForTemplate = endOfPlaceholder;
|
||||||
|
}
|
||||||
counterForUrl++;
|
counterForUrl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -61,6 +61,108 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.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]
|
[Fact]
|
||||||
public void should_return_response_200_with_simple_url()
|
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.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.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.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.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.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.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=-"))
|
.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.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/myApp1Name/api/products/1"))
|
.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.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.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.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/platform/swagger/lib/backbone-min.js"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/platform/swagger/lib/backbone-min.js"))
|
||||||
@ -587,8 +689,17 @@ namespace Ocelot.AcceptanceTests
|
|||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
{
|
{
|
||||||
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_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();
|
.Build();
|
||||||
|
@ -18,6 +18,18 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
_urlMatcher = new RegExUrlMatcher();
|
_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]
|
[Fact]
|
||||||
public void should_not_match_forward_slash_only_regex()
|
public void should_not_match_forward_slash_only_regex()
|
||||||
{
|
{
|
||||||
|
@ -8,14 +8,14 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
||||||
{
|
{
|
||||||
public class UrlPathToUrlTemplateMatcherTests
|
public class UrlPathPlaceholderNameAndValueFinderTests
|
||||||
{
|
{
|
||||||
private readonly IUrlPathPlaceholderNameAndValueFinder _finder;
|
private readonly IUrlPathPlaceholderNameAndValueFinder _finder;
|
||||||
private string _downstreamUrlPath;
|
private string _downstreamUrlPath;
|
||||||
private string _downstreamPathTemplate;
|
private string _downstreamPathTemplate;
|
||||||
private Response<List<UrlPathPlaceholderNameAndValue>> _result;
|
private Response<List<UrlPathPlaceholderNameAndValue>> _result;
|
||||||
|
|
||||||
public UrlPathToUrlTemplateMatcherTests()
|
public UrlPathPlaceholderNameAndValueFinderTests()
|
||||||
{
|
{
|
||||||
_finder = new UrlPathPlaceholderNameAndValueFinder();
|
_finder = new UrlPathPlaceholderNameAndValueFinder();
|
||||||
}
|
}
|
||||||
@ -30,6 +30,81 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
.BDDfy();
|
.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]
|
[Fact]
|
||||||
public void should_not_find_anything()
|
public void should_not_find_anything()
|
||||||
{
|
{
|
||||||
@ -169,8 +244,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
|||||||
{
|
{
|
||||||
foreach (var expectedResult in expectedResults)
|
foreach (var expectedResult in expectedResults)
|
||||||
{
|
{
|
||||||
var result = _result.Data
|
var result = _result.Data.First(t => t.TemplateVariableName == expectedResult.TemplateVariableName);
|
||||||
.First(t => t.TemplateVariableName == expectedResult.TemplateVariableName);
|
|
||||||
result.TemplateVariableValue.ShouldBe(expectedResult.TemplateVariableValue);
|
result.TemplateVariableValue.ShouldBe(expectedResult.TemplateVariableValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user