gateway-api icon indicating copy to clipboard operation
gateway-api copied to clipboard

HttpRoute should be able to match path prefix with case-insensitive option

Open gorban opened this issue 1 year ago • 4 comments

What would you like to be added:

Support for case-insensitive path prefix matching, e.g. with caseSensitive: false (naming not important to me, that's how it's called in xDS if you're using Envoy).

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: proxy-from-k8s-to-httpbin
spec:
  rules:
  - backendRefs:
    - ...
    matches:
    - path:
        type: PathPrefix
        value: /httpbin
        caseSensitive: false
    filters:
    - type: URLRewrite
      urlRewrite:
        path:
          type: ReplacePrefixMatch
          replacePrefixMatch: /

Why this is needed:

HttpRoute currently requires regular expressions to achieve case-insensitive path prefix matching.

  1. Existing code may expect URLs to be case-insensitive, since file systems can be case-insensitive. Windows Servers are a good example. Also, case-insensitivity helps users who might enter a URL manually in their address bar.
  2. We would also like to use replacePrefixMatch on a URLRewrite. This is explicitly disallowed for regular expressions, so we really need the case-insensitive support on prefix matches, specifically.
  3. Regular expressions are still a less optimal solution regardless:
    • The specific Gateway implementation may not guarantee reasonable ordering, and there is no flag to denote the priority of a regex match. We have to rely on a specific implementation like Envoy Gateway ordering the regular expression routes sensibly, which is not guaranteed by the Gateway API itself. If they are mis-ordered, a less specific path match could apply first. This is a problem if a more root path has an authentication requirement, but a nested, more specific path is intentionally public (like is common if you have a /prefix/authenticate path that accepts credentials to authenticate in the first place).
    • Regular expressions could be less performant.
  4. Feature parity with other API Gateway technologies (some required fields have be removed for brevity of examples):
    • Istio VirtualService, see ignoreUriCase:
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: proxy-from-k8s-to-httpbin
      spec:
        http:
        - match:
          - uri:
              prefix: /httpbin
            ignoreUriCase: true
          rewrite:
            uri: /
      
    • Kong Gateway which uses Kubernetes Ingress API (doesn't have case-insensitive, but Kong has explicit regex priority for confidence the more nested, specific route is applied):
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: proxy-from-k8s-to-httpbin
        annotations:
          kubernetes.io/ingress.class: kong
          konghq.com/strip-path: \"true\"
          konghq.com/regex-priority: \"1\"
      spec:
        rules:
        - http:
            paths:
            - path: /~/(?i)httpbin
              pathType: ImplementationSpecific
      
      ---
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: proxy-from-k8s-to-httpbin-get
        annotations:
          kubernetes.io/ingress.class: kong
          konghq.com/strip-path: \"true\"
          konghq.com/regex-priority: \"2\"
      spec:
        rules:
        - http:
            paths:
            - path: /~/(?i)httpbin/get
              pathType: ImplementationSpecific
      

From documentation:

ReplacePrefixMatch is only compatible with a PathPrefix HTTPRouteMatch.

gorban avatar May 31 '24 15:05 gorban

Thanks for filing this @gorban! If you have time to work on this in the next 2-3 months, do you mind proposing it in our v1.2 release scoping discussion?

robscott avatar Jun 03 '24 17:06 robscott

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle stale
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

k8s-triage-robot avatar Sep 01 '24 18:09 k8s-triage-robot

I do not want to discourage this proposal, but only to point out that the generic syntax for the HTTP path component determines it to be case-sensitive (RFC 3986).

I understand vendors may have opted to be less strict about this (either aiming for improved user experience or due to historical reasons) and I reckon the reasoning on trying to normalise the practice into the API (instead of fighting against it), regardless of what the spec says.

Perhaps my only piece of advice here then would be to ensure this concession relatively the RFC is somehow mentioned in the docs if this proposal ends up being accepted?

guicassolato avatar Sep 02 '24 09:09 guicassolato

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle rotten
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle rotten

k8s-triage-robot avatar Oct 02 '24 10:10 k8s-triage-robot

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

k8s-triage-robot avatar Nov 01 '24 10:11 k8s-triage-robot

@k8s-triage-robot: Closing this issue, marking it as "Not Planned".

In response to this:

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

k8s-ci-robot avatar Nov 01 '24 10:11 k8s-ci-robot