mercredi 2 septembre 2020

Can't change url with map and do redirect

I need to set up redirecting some requests to api depending on the value of variables. When using if statements, everything works fine. But when I try to use map instead of if, I get a "the rewritten URI has a zero length" error.

My working config file using if:

proxy_set_header X-Forwarded-Proto $scheme; 
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
proxy_redirect off;

upstream backend {
    server 192.168.2.2:5987;
}
        
server {
    listen       80;
    server_name  exemple.com;
    client_max_body_size 32m;
    charset utf-8;
    location /static/ {
        alias /opt/project/public/;
    }
    location /media/ {
        alias /opt/project/media/;
    }  
    location /api/v2/ {
        set $go "";

        # abc query parameter exists 
        if ($arg_abc) {
            set $abc $arg_abc;
            set $go "abc";            
        }
        
        # id query parameter exists
        if ($arg_id) {
            set $mid $arg_id;
            set $go "${go}id";            
        }
        
        # For v2 REST API remove id query parameter from URL
        if ($args ~ (.*)id=[^&]*(.*)) {
            set $args $1$2;
        }
        
        # For v2 REST API remove abc query parameter from URL
        if ($args ~ (.*)abc=[^&]*(.*)) {
            set $args $1$2;
        }
        
        # only id query parameter exists
        if ($go = "id") {                                
          rewrite ^/api/v2/(.*)$ /api/v1/$1$mid/ last;
        }
        
        # only id and abc query parameters exists
        if ($go = "abcid") {          
          rewrite ^/api/v2/(.*)$ /api/v1/$1$mid/$abc/ last;
        }
    }
    location / {
        proxy_pass http://backend;
    }
}

And my not working config using map:

proxy_set_header X-Forwarded-Proto $scheme; 
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
proxy_redirect off;


map $arg_abc $abc {
    default     $arg_abc;
}
map $arg_abc $go {
    default     abc;
}

map $arg_id $mid {
    default     $arg_id;
}
map $arg_id $go {
    default     ${go}id;
}

map $args                 $args {
    ~(.*)id=[^&]*(.*)     $1$2;
    ~(.*)abc=[^&]*(.*)     $1$2;
}

map $go $api_v1 {
    id    /api/v1/$1$mid/;
    abcid  /api/v1/$1$mid/$abc/;
}

upstream backend {
    server 192.168.2.2:5987;
}
        
server {
    listen       80;
    server_name  exemple.com;
    client_max_body_size 32m;
    charset utf-8;
    location /static/ {
        alias /opt/project/public/;
    }
    location /media/ {
        alias /opt/project/media/;
    }  
    location /api/v2/ {
        set $go "";
        rewrite ^/api/v2/(.*)$ $api_v1 last;
    }
    location / {
        proxy_pass http://backend;
    }
}

As I found out, I get the error "the rewritten URI has a zero length" because the $api_v1 variable remains empty, since the $go value remains empty, but why is map not processing the url? I tried installing / before $api_v1 in location, but then only parameters without the /api/v1/ part come to my backend. For example, after processing the request http://exemple.com/api/v2/exemple/test/?id=9090&abc=xyz&stop=pots&rest=api I expect to get http://exemple.com/api/v1/exemple/test/9090/xyz/?stop=pots&rest=api

But I get http://exemple.com/?id=9090&abc=xyz&stop=pots&rest=api

What's wrong with my map settings?

Aucun commentaire:

Enregistrer un commentaire