Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"proxy_pass" cannot have URI part in location given by regular expression

Tags:

nginx

I've developed a URL shortening web application.

It consists of two separate docker containers: one containing the backend REST api and another containing the frontend static website.

These two containers are linked to an nginx container. The configuration for this nginx container is below:

worker_processes 1;

events { worker_connections 1024; }

http {
    upstream api {
        server short-url:8080;
    }

    upstream frontend {
        server short-url-frontend:8081;
    }

    gzip on;
    gzip_vary on;
    gzip_min_length 860;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css text/xml application/javascript application/x-javascript application/xml;
    gzip_disable "MSIE [1-6]\.";

    server {
        listen 80;
        root    /user/share/nginx/html;

        location /urlshortener/v1 {
            proxy_pass         http://api/urlshortener/v1;
            proxy_redirect     off;
            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-Host $server_name;
        }

        location ~ ^/([A-Za-z0-9]+) {
            rewrite ^/([A-Za-z0-9]+) /$1
            proxy_pass         http://api/urlshortener/v1;
        }

        location / {
            proxy_pass          http://frontend;
            proxy_set_header    Host              $host;
            proxy_set_header    X-Real-IP         $remote_addr;
            proxy_set_header    X-Forwarded-for   $remote_addr;
        }
    }

}

If a url ends with /urlshortening/v1, I'm proxying to the backend.

If a url starts with /, I'm proxying to the frontend.

Shortened urls e.g. /3xTy or /a0q need to be proxied to the backend so that the user can be navigated to the original url. In order to do this, I've defined a location with a regular expression.

location ~ ^/([A-Za-z0-9]+) {
    rewrite ^/([A-Za-z0-9]+) /$1
   proxy_pass         http://api/urlshortener/v1;
}

This block of code gives me the following error:

2018/11/17 16:47:03 [emerg] 1#1: "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/nginx.conf:36

I've gone through several examples and reviewed a number of answers and I believe that the configuration I have should work. Can someone please explain why I'm getting this error?

like image 929
W.K.S Avatar asked Nov 17 '18 17:11

W.K.S


2 Answers

If you use a URI with a proxy_pass statement within a regular expression location, you need to build the entire URI using one or more variables. See this document for details.

So the alternatives are to (1), capture the URI from the location expression and add it to the proxy_pass statement. For example:

location ~ ^/([A-Za-z0-9]+) {
    proxy_pass http://api/urlshortener/v1/$1;
}

Or (2), use proxy_pass without a URI part, and construct the desired URI using a rewrite...break. For example:

location ~ ^/([A-Za-z0-9]+) {
    rewrite ^/([A-Za-z0-9]+) /urlshortener/v1/$1 break; 
    proxy_pass http://api;
}

See this document for details.

like image 106
Richard Smith Avatar answered Nov 07 '22 06:11

Richard Smith


I was getting same error and the correct answer could not be helping in my situation. here was my problematic configs:

# proxying wordpress static files
location ~* (((product|blog|product-category)\/.*)|(\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)))$ {
    proxy_pass https://mainhost.cdkeysell.ir/;
    ...
}

so after comparing it with my other wesite with similar configs without such error I found this could be simply solved by removing the latter / at end of proxy_pass config:

# proxying wordpress static files
location ~* (((product|blog|product-category)\/.*)|(\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)))$ {
    # proxy_pass https://mainhost.cdkeysell.ir/; ==> final `/` caused error
    proxy_pass https://mainhost.cdkeysell.ir;
    ...
}
like image 2
Mojtaba Rezaeian Avatar answered Nov 07 '22 05:11

Mojtaba Rezaeian