How to: Override a Location directive on NginX
How to: Override a Location directive on NginX
Sometimes when coding you are in need to re-use a lot of the logic across different systems but find yourself needing to overwrite some of that functionality on a special case. In this particular scenario I needed to overwrite a Location directive on NginX. What do I mean by that? Well, I do a lot of includes as a lot of functionality is shared across several sites but from time to time I have a special request/need where I need to implement custom behavior. For that reason I was defining a Location directive twice on NginX. To avoid itI could had dropped an include but it would mean manually maintaining a copy of some directives specially for this site. To avoid that I was looking for a way to define a Location directive twice and have one of them take preference. For those using EasyCamp’s EasyEngine you might find yourself trying to overwrite some of the default functionality/configuration but come across issues when trying to define the same location elsewhere.
When you declare the same Location directive on NginX you get an error indicating:
nginx: [emerg] duplicate location “/wp-login.php” in /etc/somepath/common.conf:25
In order to achieve this functionality I relied on NginX ability to stop processing further location directives. You need to change the declaration of the Location directive by using a different operator. Like, if you were using the = operator, have the new definition use the ^~ operator. Below is an example:
location = /wp-login.php
becomes
location ^~ /wp-login.php
If you read NginX’s documentation: http://wiki.nginx.org/HttpCoreModule#location you’ll find the following:
This directive allows different configurations depending on the URI. It can be configured using both literal strings and regular expressions. To use regular expressions, you must use a prefix:
- “~” for case sensitive matching
- “~*” for case insensitive matching
- there is no syntax for NOT matching a regular expression. Instead, match the target regular expression and assign an empty block, then use location / to match anything else.
The order in which location directives are checked is as follows:
- Directives with the “=” prefix that match the query exactly (literal string). If found, searching stops
- All remaining directives with conventional strings. If this match used the “^~” prefix, searching stops.
- Regular expressions, in the order they are defined in the configuration file.
- If #3 yielded a match, that result is used. Otherwise, the match from #2 is used.
So all directives were searching stop would help you to completely overwrite a Location directive. As I mentioned, you need to leverage the fact that NginX considers a query with different operator an entirely different Location directive avoiding the “duplicate location” error message when running “nginx -t” to verify your configuration.
This is very useful. As an EasyEngine user, I’ve been troubled by this issue: https://github.com/EasyEngine/easyengine/issues/150. I’m working on a solution and being able to override location directives is necessary to avoid duplicating configs.