Score:1

Prevent Nginx regex rule to override another rule

hm flag

I have a Nginx server acting as a reverse proxy for a couple services, the config is similar to this one

location /backend/service1 {
        proxy_pass http://pathto/service1;
}

location / {
        root /a/folder
}

location ~* (\.js|\.css)$
        expires 8d;

        root /home/files/abc/bcd;
}

My problem here is that recently the service1 from backend has to serve a couple static files like /backend/service1/something/file1.js or /backend/service1/something/style.css and the second location, since it's a regex location rule, overrides the first one

All static files provided by backend/service1 have a certain prefix (something), so I tried to improve the regex from the second location to have negative lookahead/lookbehind, but it doesn't seem to work, probably because the main pattern has to have a fixed length (this is what i tried without luck)

location /backend/service1 {
        proxy_pass http://pathto/service1;
}

location / {
        root /a/folder
}

location ~* (?<!something)(.*)(\.js|\.css)$
        expires 8d;

        root /home/files/abc/bcd;
}

How can I achieve this?

jp flag
https://nginx.org/en/docs/http/ngx_http_core_module.html#location
RabidTunes avatar
hm flag
I already checked the docs, but after checking it for the third time I came to a solution, see my answer below, so thanks I guess
Score:3
jp flag

If "something" immediately follows /backend/service1, you can add another more specific location that takes precedence over regex locations:

location /backend/service1 {
    proxy_pass http://pathto/service1;
}  
location ^~ /backend/service1/something/ {
    proxy_pass http://pathto/service1/something/;
}  
location ~* \.(js|css)$ { ... }

If the "something" is embedded anywhere in the URL, you will need to use a regular expression, possibly with the notorious negative lookahead. By trial and error, I found a working expression:

location ~* ^(?!.*something).*\.(js|css)$ { ... }
Score:0
hm flag

I accepted the other answer, but something that also worked for my case is nesting the location that had the regex. Something like this

location /backend/service1 {
        proxy_pass http://pathto/service1;
}

location / {
        location / {
            root /a/folder
        }

        location ~* (\.js|\.css)$
            expires 8d;

            root /home/files/abc/bcd;
        }
}

This way if the destination URI is prefixed by /backend/service1 the first location will trigger, for any other locations, the / location will trigger and then the regex can take effect

Richard Smith avatar
jp flag
This solution does not answer your question. And is the same as using `location ^~ /backend/service1`
RabidTunes avatar
hm flag
Why do you say that it does not answer my question? I fixed my issue doing this, is it wrong? Will give me issues in the future?
RabidTunes avatar
hm flag
I will try later your solution because it is simpler, and if it works, I will accept your answer in favor of mine, but i actually did fix my issue with my approach, so I don't understand your comment
Richard Smith avatar
jp flag
I am not saying that it does not solve your problem, and its good that you've found a solution that works for you. But the question you posted to SF specifically asked about a certain prefix "something", and this answer does not address that.
RabidTunes avatar
hm flag
Your solution works and it's simpler so I accepted that and I edited this, thanks!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.