Hacker News new | ask | show | jobs
by leeoniya 5099 days ago
You don't have to if you've done it for 3 years and are familiar with nginx's "rules". Otherwise if you want to avoid wasting 3 hours, you sometimes have to.

Those rules are not well defined either. What is a "literal string" / "conventional string"? Ok, "=" is clear, but what is /images/, how about /im[ag]es/, and /images/$? Since these literal strings are not quoted, what black magic is used to classify the location directive as regex or literal? I would actually love to know this, probably the biggest stumbling point for me. Especially since it uses decoded uris, because "$" could have been a "%24" in a literal string path, OR it could be a regex end of line assertion...wtf?

if you can somehow understand this without having to poke the logs or through vast experience of prior trial and error, my hat's off to you, sir.

2 comments

As has been covered the type of matching being done is easy to tell from the prefix, though, until you get used to them you will probably be checking the documentation for just what each prefix means.

The real WTF is when choosing which location is the most specific when there is a string literal and a regex match.

Ignoring ^~ locations which will always be preferred over regex the only locations that can actually be chosen over regex is exact match "=" or default string literal (no prefix) that has an exact match. This part is what is typically the real cause of "I don't know WTF is going on here."

The type of match is made explicit before the string/pattern.

"location = string" and "location string" and "location ^~ string" are non-regex matches.

"location ~ pattern" and "location ~* pattern" are regex matches.

Matching order is unintuitive and therefore bad, and there are plenty of other quirks with nginx configs that should be made more intuitive, but confusion between regex and non-regex is unusual.

It's all described right here: http://wiki.nginx.org/HttpCoreModule#location

ok, read through it again. the regex distinction is clear, that was my bad. the choice of prefix symbols is pretty poor. ^~ looks related to ~ and ~*. in the docs, the regex prefixes are presented first, so i associated ~ as a regex indicator. how wrong i was.

i generally disagree with ^ being the universal "not" indicator out of context since it's a "beginning of line assertion" when not preceded by "[" within a regex. The fact that it indicates what follows is a regex-halting literal string prefix match (exactly what ^ would indicate in a normal regex) is plain confusing.

thanks