У меня есть хранилище, в котором файлы хранятся с именем файла, соответствующим их хешу MD5. Файлы хранятся так:
...
/srv/storage/25/
/srv/storage/25/25D6D1AD130E4EB7D11F6AB48C09414E
...
/srv/storage/DF/
/srv/storage/DF/DF35407C5E433B5644538B41C957ABCE
...
Дополнительные каталоги предназначены только для предотвращения увеличения размера одного корневого каталога.
Эти файлы бывают разных типов; текстовые файлы, файлы PDF, файлы XLS, все, что угодно. Я обслуживаю эти файлы через веб-интерфейс, в котором перечислены файлы с реальными человеческими именами файлов, которые связаны с файловым сервером HTTP. Чтобы упростить пользователям открытие этих файлов из браузера (Firefox) в соответствующем приложении, веб-приложение добавляет расширение файла к имени файла MD5 в URL-адресе файлового сервера, чтобы браузер мог определить соответствующий обработчик на основе расширения имени файла. Так, например, файл report2017.pdf
в веб-интерфейсе ссылки на
http://corp.biz/files/DF35407C5E433B5644538B41C957ABCE.pdf
который с помощью описанной ниже перезаписи будет обслуживать файл:
/srv/storage/DF/DF35407C5E433B5644538B41C957ABCE
Я использую это место на своем сайте Nginx, чтобы переписать URL-адрес на правильный путь в файловой системе:
location /files {
root /srv/storage;
rewrite '^/files/([0-9A-F]{2})([0-9A-F]{30}).*$' /$1/$1$2 break;
}
Потрясающие! Оно работает. За исключением того, что теперь Nginx отвечает Content-Type: application/octet-stream
для любого URL ниже /files
. Есть ли способ заставить Nginx разрешать тип MIME перед перезаписью?
Проблема с Content-Type: application/octet-stream
это то, что для файлов PDF, даже если имя файла в URL-адресе заканчивается на .pdf
, Firefox по какой-то причине сразу переходит на Сохранить файл диалог вместо того, чтобы позволить пользователям открывать его в программе просмотра PDF. Это происходит только в коробках, где для типа файла PDF установлено значение Предварительный просмотр в Firefox.
Я просто ради удовольствия попробовал, и это сработало:
location /files {
root /usr/share/nginx/html;
}
location ~ "^/files/([0-9a-fA-F]{2})([0-9a-fA-F]{30})(.*)$" {
return 301 $scheme://$http_host/files/$1/$1$2$3;
}
Похоже, вы забыли включить третью часть (ext). Это также должно работать:
location /files {
root /usr/share/nginx/html;
rewrite '^/files/([0-9a-fA-F]{2})([0-9a-fA-F]{30})(.*)$' /files/$1/$1$2$3 break;
}