Search code examples
nginxargs

Replacing specifing character in arguments of request via NGINX


I am trying to replace specific character (+ plus sign) in arguments part to space character (%20). I made rewrite for path part but while testing I learned that NGINX doesn't change arguments after ? sign (I am new to NGINX).

I tried to do it for args part of configuration but it doesn't work as it should, it adds $20 until I get error that page isn't redirecting correctly.

The request URL ) I receive is always the same.

func=autocomplete&q=<(unlimited number of letters and plus signs (mostly 4-5 plus signs)>&key_lic=xxxxx

The code in NGINX configurations is following.

location /autocomplete/luka/ {
        if ($args ~* "^([^+]*)(\+?)([^+]*)(\+?)([^+]*)(\+?)(.*)$"){
                set $args $1%20$3%20$5%20$7;
                rewrite  (.*)$ $1 redirect;
         }
        proxy_pass http://link.where.to.finish/wm2/;
 }

Thank you for any help I could get.


Solution

  • Your existing scheme fails because all of the + signs are optional.

    If you want to redirect your URI to one where all of the + signs are replaced by %20, you can just use a space and let Nginx and/or the browser handle the encoding.

    For example:

    if ($args ~ ^(.*)\+(.*)$) { return 302 "$uri?$1 $2"; }
    

    The redirect is recursive until all + signs are replaced.


    If you intention is to correct the URI without redirection, so that only the upstream server sees the + signs replaced by %20, use rewrite...last instead.

    For example:

    if ($args ~ ^(?<first>.*)\+(?<second>.*)$) { 
        rewrite ^(.*)$ "$1?$first%20$second?" last; 
    }
    

    In this case it is necessary to use named captures in the first regular expression so that they can be used in the second. See this document for details.