-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#360 Routing based on values in designated upstream request headers #1684
base: develop
Are you sure you want to change the base?
#360 Routing based on values in designated upstream request headers #1684
Conversation
Zbyněk, thanks for the great PR! 💪 Does the PR close the #624 ? I am a bit confused by this PR because you said that it makes little sense to me to keep working on this any longer. |
Zbyněk, |
Well, you wanted to salvage my changes from the old branch, so I thought it shouldn't hurt to just to take them and put them in a new branch. 😄 At any rate, I have been thinking about the practical benefit of the current solution. You see, since users will still have to provide unique upstream URL for different downstreams, I thought that maybe we could consider allowing identical upstream URL, but differentiating the mappings based on the headers.It kind of makes sense in my head, but let me know what you and maybe also other maintainers think. EDIT: Actually, just looking at the first post in #360 , it becomes clear that the above is a requirement, not just an option. I will have to look into allowing it as it looks like Ocelot currently won't allow multiple upstream routes to be the same. |
src/Ocelot/Configuration/File/FileUpstreamHeaderRoutingOptions.cs
Outdated
Show resolved
Hide resolved
src/Ocelot/Configuration/File/FileUpstreamHeaderRoutingOptions.cs
Outdated
Show resolved
Hide resolved
src/Ocelot/DownstreamRouteFinder/Finder/DownstreamRouteFinder.cs
Outdated
Show resolved
Hide resolved
src/Ocelot/DownstreamRouteFinder/Finder/DownstreamRouteFinder.cs
Outdated
Show resolved
Hide resolved
Cheers for the feedback, @RaynaldM . I have integrated it along with a modification to the |
src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs
Outdated
Show resolved
Hide resolved
src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs
Outdated
Show resolved
Hide resolved
Having taken a look at how URL placeholder extraction and replacement works, it's quite obvious that the current algorithm (implemented in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mrclayman Hi Zbyněk!
Some suggestions:
- Use file-scoped namespaces for new added files always, because we have .NET 6+ environment
- Remove and Sort Usings by standard refactoring action in Visual Studio. I see you use some other RAD tool.
- Use
var
option to define a variable for reference types
Don't judge me much while resolving these issues please! 🤣 👇
Helpful unit tests:
src/Ocelot/Configuration/Creator/UpstreamHeaderRoutingOptionsCreator.cs
Outdated
Show resolved
Hide resolved
src/Ocelot/DownstreamRouteFinder/Finder/DownstreamRouteFinder.cs
Outdated
Show resolved
Hide resolved
src/Ocelot/DownstreamRouteFinder/Finder/DownstreamRouteFinder.cs
Outdated
Show resolved
Hide resolved
src/Ocelot/DownstreamRouteFinder/Finder/DownstreamRouteFinder.cs
Outdated
Show resolved
Hide resolved
test/Ocelot.UnitTests/DownstreamRouteFinder/DownstreamRouteFinderTests.cs
Outdated
Show resolved
Hide resolved
test/Ocelot.UnitTests/DownstreamRouteFinder/DownstreamRouteFinderTests.cs
Outdated
Show resolved
Hide resolved
This is crazy idea! Why not to fix code review issues first? 😉 |
I work in Linux. There is no Visual Studio for that. I have already had to disable |
Ping @raman-m, hope you didn't fall off the edge of the earth. 🙂 |
@mrclayman Conflicts in usings block mostly! |
Also why Upstream- prefix? Do we have |
I have already told you, I am NOT using Windows and therefore Visual Studio. Right now, I am desperately trying to find some merge tool that does not f*ck up line endings. |
eb9db94
to
b903752
Compare
All right, I have rebased this branch against the current state of |
As for the |
🆗 Got it! Try to use Visual Code if your workplace is Linux! |
Sorry, for being silent for 3 weeks. Our team is tiny: a few people only. I'd like to postpone this thread because of 30+ open PRs with lower number.
Thanks for your great contribution! 👍 |
…pstream request headers.
…onsider when evaluating duplication between upstream path mappings.
… characters: should_*
b903752
to
5f56f96
Compare
private static IHeaderDictionary NormalizeHeaderNames(IHeaderDictionary headers) | ||
{ | ||
var upperCaseHeaders = new HeaderDictionary(); | ||
foreach (KeyValuePair<string, StringValues> kv in headers) | ||
{ | ||
var key = kv.Key.ToUpperInvariant(); | ||
upperCaseHeaders.Add(key, kv.Value); | ||
} | ||
|
||
return upperCaseHeaders; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private static IHeaderDictionary NormalizeHeaderNames(IHeaderDictionary headers) | |
{ | |
var upperCaseHeaders = new HeaderDictionary(); | |
foreach (KeyValuePair<string, StringValues> kv in headers) | |
{ | |
var key = kv.Key.ToUpperInvariant(); | |
upperCaseHeaders.Add(key, kv.Value); | |
} | |
return upperCaseHeaders; | |
} | |
private static IHeaderDictionary NormalizeHeaderNames(IHeaderDictionary headers) => | |
new HeaderDictionary(headers.ToDictionary( | |
h => h.Key.ToUpperInvariant(), | |
h => h.Value | |
)); |
public bool HasAllOf(IHeaderDictionary requestHeaders) | ||
{ | ||
IHeaderDictionary normalizedHeaders = NormalizeHeaderNames(requestHeaders); | ||
foreach (var h in Headers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
foreach (var h in Headers) | |
foreach (var header in Headers) |
public bool HasAnyOf(IHeaderDictionary requestHeaders) | ||
{ | ||
IHeaderDictionary normalizedHeaders = NormalizeHeaderNames(requestHeaders); | ||
foreach (var h in Headers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
foreach (var h in Headers) | |
foreach (var header in Headers) |
|
||
public class UpstreamRoutingHeaders | ||
{ | ||
public IReadOnlyDictionary<string, ICollection<string>> Headers { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public IReadOnlyDictionary<string, ICollection<string>> Headers { get; } | |
public readonly IReadOnlyDictionary<string, ICollection<string>> Headers { get; } |
could be private ?
IHeaderDictionary normalizedHeaders = NormalizeHeaderNames(requestHeaders); | ||
foreach (var h in Headers) | ||
{ | ||
if (normalizedHeaders.TryGetValue(h.Key, out var values) && | ||
h.Value.Intersect(values, StringComparer.OrdinalIgnoreCase).Any()) | ||
{ | ||
return true; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IHeaderDictionary normalizedHeaders = NormalizeHeaderNames(requestHeaders); | |
foreach (var h in Headers) | |
{ | |
if (normalizedHeaders.TryGetValue(h.Key, out var values) && | |
h.Value.Intersect(values, StringComparer.OrdinalIgnoreCase).Any()) | |
{ | |
return true; | |
} | |
} | |
var normalizedHeaders = NormalizeHeaderNames(requestHeaders); | |
foreach (var (key, value) in Headers) | |
{ | |
if (normalizedHeaders.TryGetValue(key, out var values)) | |
{ | |
if (value.Any(item => values.Contains(item, StringComparer.OrdinalIgnoreCase))) | |
{ | |
return true; | |
} | |
} | |
} |
Zbyněk, is it feasible to resolve all the merge conflicts at this moment? Please fix this 60 items diff pressing the Sync fork button! |
Closes #360
Addition of support for request re-routing based also on upstream header configuration as per issues
Proposed Changes
Downstream URL placeholder replacement mentioned in issue #360 is not yet supported although I do have plans to add support for that as well.