1

I have a set of url paths which having changed in my application, e.g.:

  • /dataview/unknownvvvo/ => /backend/unknown-vvvo
  • /dataview/servicecounter => /backend/servicecounter-events

I try to address this with rewrite rules in nginx:

user app app;

error_log /dev/stderr debug;

events {}

http {
    include       mime.types;
    default_type  application/octet-stream;
    rewrite_log on;
    
    charset  utf-8;

    server {
        listen  80;
        listen  [::]:80;

        root  /app/app/public;
        index index.php index.html;

        rewrite ^/dataview/unknownvvvo(.*)$ /backend/unknown-vvvo$1 last;
        rewrite ^/dataview/servicecounter(.*)$ /backend/servicecounter-events$1 last;

        location / {
            try_files $uri /index.php$is_args$args;
        }

        location /index.php {
            fastcgi_pass  php-fpm_cms:9000;
            include       fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
}

But when I call 'http://localhost/dataview/unknownvvvo' in the browser for example, the nginx error log tells me the rewrite was successful, but it gives me a 404 error: nginx_err

According to the nginx docs this should work, so what did I miss here?

  • If your PHP backend relies on the `REQUEST_URI` FastCGI parameter to determine the request URI and/or query arguments, your rewrite rules won't change that parameter - it is set according to the `$request_uri` variable, and that variable does not get changed with the rewrite rules, it is the `$uri` one that does. If you don't want to use HTTP 301 redirects as suggested by Richard Smith, you can try to re-define the `REQUEST_URI` via `fastcgi_param REQUEST_URI $uri$is_args$args;`. Check [this](https://stackoverflow.com/a/62971843/7121513) answer for an example. – Ivan Shatsky Mar 03 '22 at 22:43

2 Answers2

0

You are rewriting (with rewrite) from /dataview/unknownvvvo to /backend/unknown-vvvo, then rewriting (with try_files) from /backend/unknown-vvvo to /index.php. Your index.php script will use the values defined in fastcgi_params (probably REQUEST_URI) to determine the requested path - which of course, has not been changed.

The simplest solution is to use an external redirect, using permanent instead of last on the end of the rewrite statements.

rewrite ^/dataview/unknownvvvo(.*)$ /backend/unknown-vvvo$1 permanent;
rewrite ^/dataview/servicecounter(.*)$ /backend/servicecounter-events$1 permanent;
Richard Smith
  • 45,711
  • 6
  • 82
  • 81
  • Ah okay it was not quite clear to me, that index.php will use the original REQUEST URI, I thought it will use the rewritten URI. I just changed the last flags to permanent and it works like a charm! Thanks a lot! – Mr. Anderson Mar 04 '22 at 07:22
0

Changing "last" flags to "permanent" works. But changing fastcgi param REQUEST_URI to $uri$is_args$args not:

user app app;

error_log /dev/stderr debug;

events {}

http {
    include       mime.types;
    default_type  application/octet-stream;
    rewrite_log on;

    charset  utf-8;

    server {
        listen  80;
        listen  [::]:80;

        root /app/app/public;
        index index.php index.html;
    
        rewrite ^/dataview/unknownvvvo(.*)$ /backend/unknown-vvvo$1 last;
        rewrite ^/dataview/servicecounter(.*)$ /backend/servicecounter-events$1 last;


        location / {
            try_files $uri /index.php$is_args$args;
        }

        location /index.php {
            fastcgi_pass  php-fpm_cms:9000;
            include       fastcgi_params;

            fastcgi_param REQUEST_URI $uri$is_args$args;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
}

From console output it looks like that still the original request uri is passed to cgi server instead the rewritten one: enter image description here

  • what worked here is to use the set directive as described here: https://serverfault.com/questions/805881/nginx-populate-request-uri-with-rewritten-url – Mr. Anderson Mar 04 '22 at 08:22