Comments 18
Обожаю магию. Всякое нестандартное использование периодически выручает от более громоздких велосипедов и сторонних (вне nginx) скриптов.
Недостатки магии таковы, что её использование может выйти боком, даже если заклинания верные

Не очень понял такой момент — нельзя ли просто в location @delete переписать URL, дальше проксировать его и тем самым избавиться от if?

Именно в данном случае нет, потому что нам обязательно нужно провалидировать путь и получить из пути кусок, чтобы кто-то случайно, а может и специально, не подал на вход uri содержащий ../ или нечто подобное, что приведёт к удалению папки upload вместе со всеми остальными файлами. Впрочем, может быть я слишком перестраховываюсь. Но этот if не настолько плох, чтобы думать над тем, чтобы избавиться от него. Также хочу заметить, что если файлы будут загружаться и скачиваться из корня домена, то этот if можно убрать.

Провалидировать можно с помощью самого регулярного выражения

Вы безусловно правы, от этого if можно легко избавиться даже в текущей ситуации, иб достаточно того, что путь валидируется ещё на этапе GET-запроса в первый location, а имя папки для удаления можно из него же записать в переменную вот так, которую после использовать в location delete

Для этого нужно немного поправить первый location
location ~ ^/uploads/(?<path>[\w]+)/([^/]*)?$ {
...
}


А location delete сделать таким
location @delete {
    set $token "cb110ef4c4165e495001e297feae7092";
    proxy_method DELETE;
    proxy_set_header Token $token;
    proxy_pass https://example.com/upload/$path/;
}

попридираюсь к велосипеду:
cat /dev/urandom | head -c8 | xxd -ps | tr -d "\n"
заменить на
hexdump -n 16 -e '/4 "%x"' </dev/urandom


то же самое — cat лишний в cat /dev/urandom | tr -dc "[:graph:]"
можно заменить на tr -dc "[:graph:]" </dev/urandom

даже если через head и прочее — cat /dev/urandom | head -c16 очень легко превращается в head -c16 /dev/urandom. Это даже забыв про hexdump и подобное.
Всё верно, но не стал использовать по причине того, что если разрешить GET, то автоматом будет разрешён HEAD. Таким образом в случае если какой-то из клиентов сделает HEAD перед тем как скачать файл, то файл будет удалён, но при этом отдан не будет.
Также подобные if вполне укладываются в допустимые, т.к. «The only 100% safe things which may be done inside if in a location context are:
return ...;
rewrite… last;»
Для того чтобы работала докачка и файл удалялся только после полного скачивания нужно чуть подправить конфиг:
location delete {
proxy_method DELETE;
proxy_set_header Token «cb110ef4c4165e495001e297feae7092»;
if ($request_completion = OK){
proxy_pass example.com/upload$folder/;
}
}
Only those users with full accounts are able to leave comments. Log in, please.