2

I have a location block like the following

location ^api/([^/]+)(/.+)$ {
     set $my_host $1;
     set $my_path $2;
     proxy_pass http://$myhost$my_path$is_args$args;
}

This works well for most normal cases for URIs such as /api/foo/bar?1234.

However when I introduce special URL encoded values, things go south. When the URI is /api/foo/bar[%7B%7D], $my_path is decoded and is passed to $my_host as /foo/bar[{}]. This isn't a valid URL.

I've tried to work around the limitations of NGINX by using a conditional to match against $request_uri and $uri, but the results are either double encoded or unencoded.

location ~* ^api/([^/]+)(/.+)$ {
     set $my_host $1;
     if ( $request_uri ~* ^api/([^/]+)(/.+)$ ) {
          set $my_path $2;
     }
     proxy_pass http://$myhost$my_path$is_args$args;
}

In the above case $my_path is /foo/bar[%257B%257D].

I have also attempted using set_unescape_uri from the set misc module for the second regex.

How can I get NGINX to remove the path components in the same format as the client provided them?

1 Answer 1

1

I guess something was wrong with set_unescape_uri and the regex variable or something else. Using the single argument form of set_unescape_uri works.

location ~* ^api/([^/]+)(/.+)$ {
     set $my_host $1;
     if ( $request_uri ~* ^api/([^/]+)(/.+)$ ) {
          set $my_path $2;
          set_unescape_uri $my_path;
     }
     proxy_pass http://$myhost$my_path$is_args$args;
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .