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:

  1. “~” for case sensitive matching
  2. “~*” for case insensitive matching
  3. 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:

  1. Directives with the “=” prefix that match the query exactly (literal string). If found, searching stops
  2. All remaining directives with conventional strings. If this match used the “^~” prefix, searching stops.
  3. Regular expressions, in the order they are defined in the configuration file.
  4. 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.

You may also like...

1 Response

  1. William Cobb says:

    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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.