Nginx location - Distinguish requests by arguments or queries

Francis Daly francis at
Tue Feb 25 17:06:15 UTC 2020

On Tue, Feb 25, 2020 at 07:05:05AM -0500, stmx38 wrote:

Hi there,

> We have a case when we should permit different methods on the same location
> but different requests.

The nginx model does "location" matching without reference to the
query string.

But you may be able to build your own "good-enough" config, for your
use case.

> For location /test we should permit only POST, for /test?doc we should
> permit only GET methods.

As you have seen - limit_except does not do what you want.

But if you can enumerate the things that you want to allow (or: want
to block), then you can make your own variable from "method" and "uri"
that you can test. Only checking it within the one location{} should
reduce the impact on any other requests.

If you change the list of things that should be allowed, then you will
need ongoing maintenance of the hardcoded list.

Something like:

    map $request_method$request_uri $block_this {
        default 1;
        ~*GET/test\?doc 0;
        ~*POST/test\?. 1;
        ~*POST/test 0;

along with

    location /test {
        error_page  403 =405 /custom-error;
        if ($block_this = 1) { return 403; }
        proxy_pass http://test/in;

(Set the return code to what you want.)

may be adaptable to do what you want.

The case-insensitive is because I don't know if your clients do GET or get
or gEt; and I don't know how important it is that *no* "should-be-blocked"
requests get to your back-end. Adjust to taste based on testing.

Good luck with it,

Francis Daly        francis at

More information about the nginx mailing list