-
Notifications
You must be signed in to change notification settings - Fork 507
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
Switching Header and Query Param matching to use lists #657
Switching Header and Query Param matching to use lists #657
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: robscott The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
apis/v1alpha2/httproute_types.go
Outdated
// If multiple entries specify equivalent header names, the first entry with | ||
// an equivalent name MUST be given precedence. Due to the | ||
// case-insensitivity of header names, "foo" and "Foo" are considered | ||
// equivalent. |
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.
Question for clarification:
headers:
- name: foo
value: bar
- name: Foo
value: bar1
What happens if a request with header foo: bar1
comes in? Is it matched or not?
I'm not sure if I clearly understand the meaning of "precedence" here.
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.
Yeah, this could be clarified better. I was trying to say foo: bar
should be given precedence here since it appears first in the list. That means that foo: bar1
would not match (unless type was "Prefix").
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.
This is in conflict with the general rule, which is "multiple match values are ANDed". So I'm not sure that we need to add the complexity of a special case for duplicates (as a quality of implementation issue, maybe validation could reject this case or a controller could emit a warning).
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.
so in the above example no requests should match because the result of an AND here would always be false?
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.
so in the above example no requests should match because the result of an AND here would always be false?
Yup, exactly.
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.
There's a lot of nuance here and it's difficult to get the wording right. For example, the following would be valid:
- name: foo
type: RegularExpression
value: [a-z]
- name: Foo
type: RegularExpression
value: [a-z0-9]
It may not actually make any sense to configure a Route that way, but a value like z
would be valid. And similar ambiguity would likely also exist for ImplementationSpecific match types. So the only thing we can say for sure is the following:
Specifying different values with an exact match type for equivalent header names will not match any requests.
And once I took the time to write that out, it seemed obvious, so I just omitted it. Maybe providing the specific example you suggested would be a better way to explain this than the sentence I have above?
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.
Added an example here that I think helps explain how this should be interpreted.
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.
Actually given the regex example, we should just say if you repeat items with the same name, it will be "implementation specific" how this is implemented. Some infra may not support AND'ing regex together -- and ANDing regex is not an operator that is easy to do with a regex.
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.
Good point that ANDing a regex is simply not a practical expectation here. Instead of falling back to implementation specific handling of this, I think it may make the most sense simply to revert back to something resembling the original approach. Specifying that implementations must ignore subsequent matches for equivalent names and only implement the first one should be relatively easy to implement for everyone and results in a consistent experience.
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.
+1 makes sense, this is both easy to implement and consistent for users.
lgtm with @hbagdi's comments. =) |
On May 13, 2021 at 3:37 PM, Harry ***@***.***> wrote:
@hbagdi commented on this pull request.
In apis/v1alpha2/httproute_types.go:
@@ -406,15 +409,24 @@ type HTTPRouteMatch struct {
// +kubebuilder:default={type: "Prefix", value: "/"}
Path *HTTPPathMatch `json:"path,omitempty"`
- // Headers specifies a HTTP request header matcher.
+ // Headers specifies HTTP request header matchers. Multiple match values are
+ // ANDed together, meaning, a request must match all the specified headers
+ // to select the route.
+ //
+ // If multiple entries specify equivalent header names, the first entry with
+ // an equivalent name MUST be given precedence. Due to the
+ // case-insensitivity of header names, "foo" and "Foo" are considered
+ // equivalent.
That is hard to understand based on the current language. I've a suggestion to improve the language a little bit here.
I think having validation to prevent the user from providing two different values for the same header with type Exact is a good idea. We should open an issue to track it if you all agree.
We can just be more explicit about cane-insensitivity of HTTP headers (i.e. call it out in a separate sentence up front rather than an aside at the end). I agree that adding duplicate detection in the validation is good, but you will want to be careful with character sets (ie. USASCII, not UTF8).
|
704fe62
to
971a172
Compare
b8736b7
to
6121abf
Compare
This was found during manual testing for kubernetes-sigs#657: ``` $ kubectl apply -f examples | wc 38 76 1989 $ kubectl apply --recursive -f examples | wc 47 94 2424 ```
I found a bug in our verify script and opened up #670 to fix it. |
@robscott It seems the examples didn't pass validation, I'm not sure why they failed. Could you rebase on the latest HEAD on our dev branch? |
This matches the API conventions that prefer lists of named subobjects over maps.
6121abf
to
e2af0bf
Compare
@hbagdi it was actually a great catch - I had |
/lgtm |
What type of PR is this?
/kind cleanup
/kind api-change
What this PR does / why we need it:
This matches the API conventions that prefer lists of named subobjects over maps.
Does this PR introduce a user-facing change?: