skip to Main Content

I have a requirement to rewrite all URLs to lowercase.

E.g. test.com/CHILD to test.com/child

Frontend application is developed on docker on azure kubernetes services. Ingress is controlled on nginx ingress controller.

3

Answers


  1. The ingress controller supports case insensitive regular expressions in the spec.rules.http.paths.path field. This can be enabled by setting the nginx.ingress.kubernetes.io/use-regex annotation to true (the default is false). For more information please check here

    Using the nginx.ingress.kubernetes.io/use-regex annotation will indicate whether or not the paths defined on an Ingress use regular expressions. The default value is false.

    The following will indicate that regular expression paths are being used:

    nginx.ingress.kubernetes.io/use-regex: "true"
    

    The following will indicate that regular expression paths are not being used:

    nginx.ingress.kubernetes.io/use-regex: "false"
    

    When this annotation is set to true, the case insensitive regular expression location modifier will be enforced on ALL paths for a given host regardless of what Ingress they are defined on.

    [Reference]

    Login or Signup to reply.
  2. You can rewrite URLs using Lua as described in the Enforce Lower Case URLs (NGINX) article.

    All we need to do is add the following configuration block to nginx:

    location ~ [A-Z] {
        rewrite_by_lua_block {
            ngx.redirect(string.lower(ngx.var.uri), 301);
        }
    }
    

    I will show you how it works.


    First, I created an Ingress resource with the previously mentioned configuration:

    $ cat test-ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: test-ingress
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/server-snippet: |
         location ~ [A-Z] {
            rewrite_by_lua_block {
                ngx.redirect(string.lower(ngx.var.uri), 301);
            }
          }
    spec:
      rules:
      - http:
          paths:
          - path: /app-1
            pathType: Prefix
            backend:
              service:
                name: app-1
                port:
                  number: 80
                  
                  
    $ kubectl apply -f test-ingress.yaml
    ingress.networking.k8s.io/test-ingress created
    
    $ kubectl get ing
    NAME           CLASS    HOSTS   ADDRESS          PORTS   AGE
    test-ingress   <none>   *       <PUBLIC_IP>      80      58s
    

    Then I created a sample app-1 Pod and exposed it on port 80:

    $ kubectl run app-1 --image=nginx
    pod/app-1 created
    
    $ kubectl expose pod app-1 --port=80
    service/app-1 exposed
    

    Finally, we can test if rewrite works as expected:

    $ curl -I <PUBLIC_IP>/APP-1
    HTTP/1.1 301 Moved Permanently
    Date: Wed, 06 Oct 2021 13:53:56 GMT
    Content-Type: text/html
    Content-Length: 162
    Connection: keep-alive
    Location: /app-1
    
    $ curl -L <PUBLIC_IP>/APP-1
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    ...
    

    Additionally, in the ingress-nginx-controller logs, we can see the following log entries:

    10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /APP-1 HTTP/1.1" 301 162 "-" "curl/7.64.0" 83 0.000 [-] [] - - - - c4720e38c06137424f7b951e06c3762b
    10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /app-1 HTTP/1.1" 200 615 "-" "curl/7.64.0" 83 0.001 [default-app-1-80] [] 10.4.1.13:80 615 0.001 200 f96b5664765035de8832abebefcabccf
    
    Login or Signup to reply.
  3. The idea of the solution is ok, but this would rewrite all urls of this controller not only the one for this ingress. Putting it into the configuration-snippet is also not possible, as this leads to an duplicate rewrite_by_lua_block.
    I put the rule into a differen lua block

    nginx.ingress.kubernetes.io/configuration-snippet: |
      access_by_lua_block {
        if string.match(ngx.var.uri, "[A-Z]") then
          ngx.redirect(string.lower(ngx.var.uri), 301);
        end
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search