Answers: <p>I could not get <code>/</code> to work but when I thought about it as a <code>Route</code> for my REST services it made more sense to me.  The following works.</p>
  <pre><code> rules:
    - matches:
      - path:
          type: PathPrefix
          value: /api/weather
      filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /weatherforecast
      backendRefs:
      - name: weather-svc
        port: 8080
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2024-05-13T04:44:44.607Z
Answers: 2024-05-13T04:44:44.607Z
Answers: Geoff Niehaus
Body: <p>My goal is to have a single <code>Gateway</code> that can be used to host multiple applications at different paths. The <code>URLRewrite</code> filter exists, however, when it does not seem to be working as expected.</p>
  <p>Using Cilium's Hubble for example, I have the following resource:</p>
  <pre class="lang-yaml prettyprint-override"><code>apiVersion: gateway.networking.k8s.io/v1beta1
  kind: HTTPRoute
  metadata:
    name: hubble
    namespace: kube-system
  spec:
    parentRefs:
      - name: gateway
        namespace: gateway-system
    rules:
      - matches:
          - path:
              type: PathPrefix
              value: /hubble
        filters:
          - type: URLRewrite
            urlRewrite:
              path:
                type: ReplacePrefixMatch
                replacePrefixMatch: /
        backendRefs:
          - name: hubble-ui
            port: 80
  </code></pre>
  <p>I would like to navigate to <code>http://k8s-ingress/hubble</code> to access Hubble, <code>http://k8s-ingress/argo-cd</code> to access Argo CD, <code>http://k8s-ingress/foobar</code> to access Foobar, etc.</p>
  <p>However, when I apply this resource and navigate to <code>http://k8s-ingress/hubble</code>, I do get a response, but it's an empty page, not the normal Hubble dashboard. (I can tell that the server is responding, however, because the browser tab name is set to <code>Hubble UI</code>.</p>
  <p><a href="https://i.sstatic.net/lYtL1.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/lYtL1.png" alt="enter image description here" /></a></p>
  <p>And if I <code>curl</code> it I do get a response:</p>
  <pre class="lang-bash prettyprint-override"><code>$&gt; curl http://k8s-ingress/hubble
  &lt;!doctype html&gt;&lt;html&gt;&lt;head&gt;&lt;meta charset=&quot;utf-8&quot;/&gt;&lt;title&gt;Hubble UI&lt;/title&gt;&lt;base href=&quot;/&quot;/&gt;&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;/&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,user-scalable=0,initial-scale=1,minimum-scale=1,maximum-scale=1&quot;/&gt;&lt;link rel=&quot;icon&quot; type=&quot;image/png&quot; sizes=&quot;32x32&quot; href=&quot;favicon-32x32.png&quot;/&gt;&lt;link rel=&quot;icon&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; href=&quot;favicon-16x16.png&quot;/&gt;&lt;link rel=&quot;shortcut icon&quot; href=&quot;favicon.ico&quot;/&gt;&lt;script defer=&quot;defer&quot; src=&quot;bundle.main.104f057a7d45238d9d45.js&quot;&gt;&lt;/script&gt;&lt;link href=&quot;bundle.main.3818224e482785607640.css&quot; rel=&quot;stylesheet&quot;&gt;&lt;/head&gt;&lt;body&gt;&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;%
  </code></pre>
  <p>I assume things aren't working because my server is treating my request like it's targeted at <code>/hubble</code> instead of <code>/</code>. Which doesn't normally resolve to anything. But isn't that the point of <code>URLRewrite/ReplacePrefixMatch</code>? To rewrite the path of a URI before routing to the server?</p>
  <p>Perhaps I'm misremembering, but isn't this how things work under Istio? For example the following <code>VirtualService</code> spec:</p>
  <pre class="lang-yaml prettyprint-override"><code>http:
    - match:
        - uri: 
            prefix: /hubble
      route:
        - destination:
            host: hubble-ui
            port: 
              number: 80
      rewrite:
        uri: /
  </code></pre>
  <p>I've also tried to use <code>URLRewrite/ReplaceFullPath</code> but it results in the same behavior as above.</p>
  <pre class="lang-yaml prettyprint-override"><code>    - matches:
          - path:
              type: PathPrefix
              value: /hubble
        filters:
          - type: URLRewrite
            urlRewrite:
              path:
                type: ReplaceFullPath
                replaceFullPath: /
        backendRefs:
          - name: hubble-ui
            port: 80
  </code></pre>
  <p><code>RequestRedirect/ReplaceFullpath</code> works somewhat. In that I can navigate to <code>http://k8s-ingress/hubble</code> and have my browser 302-redirected to <code>http://k8s-ingress</code> where I can successfully hit the Hubble UI. But this isn't what I want, as I would only be able to host a single application on the gateway at <code>/</code>.</p>
  <pre class="lang-yaml prettyprint-override"><code>    - matches:
          - path:
              type: PathPrefix
              value: /hubble
        filters:
          - type: RequestRedirect
            requestRedirect:
              path:
                type: ReplaceFullPath
                replaceFullPath: /
              statusCode: 302
      - backendRefs:
          - name: hubble-ui
            port: 80
  </code></pre>
  
Tags: <kubernetes><istio><url-rewrite>
Title: Kubernetes Gateway API - Using HTTPRoute rules to rewrite URI paths
UserDisplayName: TJ Zimmerman
ThreadText: # Kubernetes Gateway API - Using HTTPRoute rules to rewrite URI paths
  
  (Asked by: username_0 on 2023-10-15)
  
  My goal is to have a single `Gateway` that can be used to host multiple applications at different paths. The `URLRewrite` filter exists, however, when it does not seem to be working as expected.
  
  Using Cilium's Hubble for example, I have the following resource:
  
  ```yaml
  apiVersion: gateway.networking.k8s.io/v1beta1
  kind: HTTPRoute
  metadata:
    name: hubble
    namespace: kube-system
  spec:
    parentRefs:
      - name: gateway
        namespace: gateway-system
    rules:
      - matches:
          - path:
              type: PathPrefix
              value: /hubble
        filters:
          - type: URLRewrite
            urlRewrite:
              path:
                type: ReplacePrefixMatch
                replacePrefixMatch: /
        backendRefs:
          - name: hubble-ui
            port: 80
  
  ```
  
  I would like to navigate to `http://k8s-ingress/hubble` to access Hubble, `http://k8s-ingress/argo-cd` to access Argo CD, `http://k8s-ingress/foobar` to access Foobar, etc.
  
  However, when I apply this resource and navigate to `http://k8s-ingress/hubble`, I do get a response, but it's an empty page, not the normal Hubble dashboard. (I can tell that the server is responding, however, because the browser tab name is set to `Hubble UI`.
  
  [![enter image description here](https://i.sstatic.net/lYtL1.png)](https://i.sstatic.net/lYtL1.png)
  
  And if I `curl` it I do get a response:
  
  ```bash
  $> curl http://k8s-ingress/hubble
  <!doctype html><html><head><meta charset="utf-8"/><title>Hubble UI</title><base href="/"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,user-scalable=0,initial-scale=1,minimum-scale=1,maximum-scale=1"/><link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png"/><link rel="shortcut icon" href="favicon.ico"/><script defer="defer" src="bundle.main.104f057a7d45238d9d45.js"></script><link href="bundle.main.3818224e482785607640.css" rel="stylesheet"></head><body><div id="app"></div></body></html>%
  
  ```
  
  I assume things aren't working because my server is treating my request like it's targeted at `/hubble` instead of `/`. Which doesn't normally resolve to anything. But isn't that the point of `URLRewrite/ReplacePrefixMatch`? To rewrite the path of a URI before routing to the server?
  
  Perhaps I'm misremembering, but isn't this how things work under Istio? For example the following `VirtualService` spec:
  
  ```yaml
  http:
    - match:
        - uri: 
            prefix: /hubble
      route:
        - destination:
            host: hubble-ui
            port: 
              number: 80
      rewrite:
        uri: /
  
  ```
  
  I've also tried to use `URLRewrite/ReplaceFullPath` but it results in the same behavior as above.
  
  ```yaml
      - matches:
          - path:
              type: PathPrefix
              value: /hubble
        filters:
          - type: URLRewrite
            urlRewrite:
              path:
                type: ReplaceFullPath
                replaceFullPath: /
        backendRefs:
          - name: hubble-ui
            port: 80
  
  ```
  
  `RequestRedirect/ReplaceFullpath` works somewhat. In that I can navigate to `http://k8s-ingress/hubble` and have my browser 302-redirected to `http://k8s-ingress` where I can successfully hit the Hubble UI. But this isn't what I want, as I would only be able to host a single application on the gateway at `/`.
  
  ```yaml
      - matches:
          - path:
              type: PathPrefix
              value: /hubble
        filters:
          - type: RequestRedirect
            requestRedirect:
              path:
                type: ReplaceFullPath
                replaceFullPath: /
              statusCode: 302
      - backendRefs:
          - name: hubble-ui
            port: 80
  
  ```
  
  **Tags:** kubernetes, istio, url-rewrite
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2024-05-13. Score: 1
  
  I could not get `/` to work but when I thought about it as a `Route` for my REST services it made more sense to me. The following works.
  
  ```
   rules:
    - matches:
      - path:
          type: PathPrefix
          value: /api/weather
      filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /weatherforecast
      backendRefs:
      - name: weather-svc
        port: 8080
  
  ```
  
  
  ---
  
  