0

I need to rewrite URLs in NGINX. I tried many examples from google searches but failed.

/manager/?whmpca=order_process&a=add&pid=5&a=add&currency=1&billingcycle=monthly

I need to rewrite it as

/manager/cart/a/add/pid/5/currency/1/billingcycle/monthly/

or something like this

/manager/pid/5/currency/1/monthly

Edit 1: can we simply replace '&' and '=' from URL to '/'. In this way we will get something like

manager/whmpca/order_process/a/add/pid/5/a/add/currency/1/billingcycle/monthly

Edit 2: here is my complete configuration file.

server {
        server_name example.com www.example.com *.example.com 10.10.10.10;
        listen 10.10.10.10:443 default ssl;
        root /home/example/public_html;
        index index.php index.htm index.html;
        rewrite_log on;
#HMPRESS rewrite config
#       location /manager {
#       try_files $uri $uri/ /manager/?whmpca=$uri&$args;
#       }
location ~ ^/manager/?$ {
    return 302 /manager/cart/a/$arg_a/pid/$arg_pid/currency/$arg_currency/billingcycle/$arg_billingcycle;
}
## wordpress configuration

        location = /favicon.ico {
         log_not_found off; access_log off;
        }
        location / {
        try_files $uri $uri/ /index.php$args;
        }
## wordpress conf ends
        include /etc/nginx/fastcgi_cache.conf;
        include /etc/nginx/static-files.conf;
        include /etc/nginx/exclusions.conf;
        access_log /var/log/virtualmin/example.com_access_log;
        error_log /var/log/virtualmin/example.com_error_log notice;
        fastcgi_param GATEWAY_INTERFACE CGI/1.1;
        fastcgi_param SERVER_SOFTWARE nginx;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;
        fastcgi_param SCRIPT_FILENAME /home/example/public_html$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param REQUEST_URI $request_uri;
        fastcgi_param DOCUMENT_URI $document_uri;
        fastcgi_param DOCUMENT_ROOT /home/example/public_html;
        fastcgi_param SERVER_PROTOCOL $server_protocol;
        fastcgi_param REMOTE_ADDR $remote_addr;
        fastcgi_param REMOTE_PORT $remote_port;
        fastcgi_param SERVER_ADDR $server_addr;
        fastcgi_param SERVER_PORT $server_port;
        fastcgi_param SERVER_NAME $server_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS $https;
        location ~ \.php(/|$) {
                try_files $uri $fastcgi_script_name =404;
                fastcgi_pass unix:/var/php-nginx/134783825911919.sock/socket;
        }
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        ssl_certificate /home/example/ssl.combined;
        ssl_certificate_key /home/example/ssl.newkey.bak;

}
Faheem
  • 11
  • 2
  • can we achieve it in a different way? For example simply replace '&' and '=' with '/'. we will then get the url `/manager/whmpca/order_process/a/add/pid/1/a/add/currency/1/billingcycle/monthly` – Faheem Jun 01 '21 at 16:39
  • No, there is no search & replace functionality like that in nginx. One could achieve this with OpenResty nginx and custom Lua module. I think the best way to implement this is in your backend. The rewriting logic might be too complex to implement in nginx. – Tero Kilkanen Jun 01 '21 at 18:08

2 Answers2

0
if ( $args ~ "whmpca=order_process&a=add&pid=(\d)&a=add&currency=(\d)&billingcycle=monthly" ) {
  set $pid $1;
  set $cur $2;
}
rewrite /manager/cart/a/add/pid/$pid/currency/$cur/billingcycle/monthly/ redirect;
Gerard H. Pille
  • 2,569
  • 1
  • 13
  • 11
  • Thanks for your answer but unfortunately it is not working. below is error nginx: [emerg] unexpected "}" in /etc/nginx/sites-enabled/example.com.conf:22 I then moved "}" at the end of this code like below: if ( $args ~ "whmpca=order_process&a=add&pid=(\d)&a=add&currency=(\d)&billingcycle=monthly" ) { set $pid $1 set $cur $2 rewrite /manager/cart/a/add/pid/$pid/currency/$cur/billingcycle/monthly/ redirect; } but unfortunately following is the error: nginx: [emerg] invalid number of arguments in "set" directive in /etc/nginx/sites-enabled/example.com.conf:23 – Faheem Jun 01 '21 at 14:31
  • I forgot the semicolons!! – Gerard H. Pille Jun 01 '21 at 14:34
  • nginx: [emerg] the duplicate "pid" variable in /etc/nginx/sites-enabled/example.com.conf:20 – Faheem Jun 01 '21 at 14:52
  • if ( someting ) { do bla }; <-- Semicolon is missing – djdomi Jun 01 '21 at 15:03
  • @djdomi no it isn't. – Gerard H. Pille Jun 01 '21 at 15:08
  • @user2082094: change the names of the variables to something you haven't used before, like $ppid and $pcur. – Gerard H. Pille Jun 01 '21 at 15:09
  • I tried it. I changed the variable names and the error gone but the URL is not redirecting after restarting nginx. – Faheem Jun 01 '21 at 15:18
  • Then this part isn't being used. You have to check your full configuration. And don't forget to clean the browser's cache. – Gerard H. Pille Jun 01 '21 at 15:56
  • here is the error log in nginx. ` "whmpca=order_process&a=add&pid=(\d)&a=add&currency=(\d)&billingcycle=monthly" does not match "", client: 37.xxx.xxx.xxx, server: example.com, request: "POST /wp-admin/admin-ajax.php HTTP/1.1", host: "example.com", referrer: "https://example.com/manager/?whmpca=order_process&a=add&pid=26&a=add&currency=1&billingcycle=monthly" ` – Faheem Jun 01 '21 at 16:12
  • I believe a POST doesn't have arguments, but rather a request body. – Gerard H. Pille Jun 01 '21 at 18:35
0

nginx stores individual query arguments to variables with $arg_ prefix.

In this case, you can use the following pattern:

location ~ ^/manager/?$ {
    return 302 /manager/cart/a/$arg_a/pid/$arg_pid/currency/$arg_currency/billingcycle/$arg_billingcycle;
}

However, if you need to limit actions based on value of whmpca argument, then additional restrictions are needed.

This also requires that every request has these arguments. If one argument is missing, it will break.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • I got a 'too many redirects' error in the browser and also URL is missing arg values. `/manager/cart/a//pid//currency//billingcycle/` – Faheem Jun 01 '21 at 16:31
  • I changed the `location` to prevent matches to the redirected URL. Did you specify all the arguments in the original request? – Tero Kilkanen Jun 01 '21 at 17:09
  • It is now working and rewriting URL but page not found error appears. one more thing, now I can't access other URLs in /manager/, it is redirecting all to /manager/cart/a/..... I posted a comment under the original question, can you please suggest something according to the comment. – Faheem Jun 01 '21 at 17:21
  • If there is a page not found error, then it means your backend cannot understand the URLs you are creating. You need to check what is the correct format URLs your backend understands and then put correct information to the question. – Tero Kilkanen Jun 01 '21 at 18:12