0

Occasionally I need some plain browsable directories on my site. I do achieve this with the following config:

 ... root /var/www/example.com/file_dump; autoindex off; ... location / { try_files $uri /error.html @django; } location @django { ... } location ~ ^/test/.+/? { autoindex on; } 

So if I would create a directory /var/www/example.com/file_dump/test/something, I would get the list of files at the address example.com/test/something.

I have tried to be smarter than this with the following config:

 location / { if (!-d test/$uri) { autoindex on; } try_files $uri /error.html @django; } 

But I've met the following error:

nginx: [emerg] "autoindex" directive is not allowed here...

Why Nginx does not allow autoindex within the conditional statements? Can I enable autoindex dynamically by the other means?

4
  • I'm not sure what answer you are expecting. What about "nginx does not allow autoindex directive within the if block in location because if in location is not listed as allowed contexts for the autoindex directive (unlike some others)"? nginx conditional statements is a very special thing and should be used with caution. The best practice is to avoid the if whenever possible. Commented Nov 23, 2020 at 16:12
  • if is still evil. Commented Nov 23, 2020 at 16:25
  • @IvanShatsky I guess my question is more about whether I can employ autoindex dynamically by the other means, thus without the if. @MichaelHampton Thank you, I'm aware of the ifisevil. Commented Nov 23, 2020 at 18:28
  • @NarūnasK Documentation for every nginx directive specifies the context (http, server, location, if in location) where that directive can be used. Commented Nov 23, 2020 at 18:57

1 Answer 1

0

Since the enabled/disabled autoindex feature is a location-only property, your only way is to use different locations for autoindex-enabled and autoindex-disabled requests. Although some nginx directives allow using the variables as their arguments, autoindex is not one of those.

It is completely unclear what do you want to achieve checking the if (!-d test/$uri) { ... } statement. If that was meaning if $uri is some existing directory under /var/www/example.com/file_dump/test/ directory, here is a possible workaround:

server { ... set $is_dir loc_default; if (-d $document_root$uri) { set $is_dir loc_index; } set $loc loc_default; if ($uri ~ ^/test/.) { set $loc $is_dir; } location / { try_files /dev/null @$loc; } location @loc_default { try_files $uri /error.html @django; } location @loc_index { autoindex on; # try_files $uri $uri/ =404 is assumed by default } location @django { ... } } 

However it is absolutely meaningless to check if the $uri is an existing directory, using just

 set $loc loc_default; if ($uri ~ ^/test/.) { set $loc loc_index; } 

will give you the same behavior.

Same thing can be achieved using the map block:

map $uri $loc { ~^/test/. loc_index; # you can check multiply patterns here, for example ~^/another/ loc_index; # if none matched default loc_default; } server { ... location / { try_files /dev/null @$loc; } location @loc_default { try_files $uri /error.html @django; } location @loc_index { autoindex on; # try_files $uri $uri/ =404 is assumed by default } location @django { ... } } 

The try_files /dev/null <named_location> trick is taken from this excellent answer.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.