Стильный современный «autoindex» в Angie/nginx без sms и сторонних модулей#
Полное руководство по настройке современного автоматического индекса директорий в Angie и nginx: готовые темы оформления на XSLT и JavaScript, интеграция с WebDAV и практические примеры конфигурации.
Авто-индекс — это функциональность HTTP-сервера, позволяющая при обращении к каталогу на файловой системе автоматически выводить список содержащихся в нем файлов.*
Поводом для этой статьи стал вопрос из нашего Telegram-чата поддержки (присоединяйтесь — он открыт для всех!): «Почему в репозиториях Angie среди множества сторонних модулей отсутствует Nginx Fancy Index?».
Меня удивило, что кто-то пользуется устаревшим модулем, поскольку ещё в 2014 году я добавил во встроенный в nginx модуль «autoindex» поддержку форматов JSON и XML, что делает сторонние решения избыточными.
Для чего понадобился сторонний модуль, упомянутый в вопросе, — вполне понятно, ведь внешний вид страницы со списком файлов по умолчанию выглядит весьма аскетично, поэтому хочется его разукрасить и улучшить. А как это сделать элегантно и просто без дополнительных модулей, я продемонстрирую наглядно на готовых примерах.
Показывать я буду на Angie, но все это также применимо и к nginx, хотя продолжать его использовать на сегодняшний день вместо Angie — нет никакого смысла, и скорее даже вредно.
Кроме того, в Angie версии 1.1.0 модуль autoindex
был ещё доработан и теперь
обеспечивает "естественную" сортировку, результат которой выглядит более
логично. Проблему, которую это решает, можно наглядно видеть в листинге тарболов
на официальном сайте самого nginx: Кривая сортировка в nginx на примере https://nginx.org/download/#
После nginx-0.1.1.tar.gz идет сразу nginx-0.1.10.tar.gz и так до версии nginx-0.1.19.tar.gz, где опять появляется неожиданное вкрапление nginx-0.1.2.tar.gz… и т. д.; очевидный беспорядок, к которому приводит "тупое" посимвольное сравнение строк с помощью strcmp().
А вот как выглядит такой же листинг в Angie: "Естественная" сортировка в Angie#
Здесь для демонстрации мне пришлось создать пачку пустых файлов. Я бы показал на
живом примере, но мы доберемся до
двухзначных версий только через полгода (но уже заранее все предусмотрели!). На
самом деле таких небольших, на первый взгляд незаметных добработок в Angie ещё
много в самых разных аспектах. Итак, для начала давайте пройдемся по всем основным способам улучшения
авто-индекса, которые могут встретиться и применялись в разное время ещё в
nginx, обсудим их плюсы и минусы. Способ заключается в том, что с помощью данных встроенных модулей (директивы
sub_filter)
изменяется тело ответа и к стандартному HTML-выводу с листингом добавляются
CSS-стили, возможно, JS-скрипты, а при необходимости может меняться и структура
разметки. Когда-то это было самым простым и тривиальным решением, позволявшим без
сторонних модулей улучшить встроенный autoindex, но на сегодня есть способы
гораздо лучше, поэтому останавливаться на нем подробно не будем. Тут всё
очевидно. Суть такого модуля заключается в том, что добавляется множество новых директив,
позволяющих всячески настраивать то, как будет выглядеть выводимый HTML:
добавлять стили, менять формат даты и т. п. Основная проблема — это необходимость в установке стороннего модуля. И хорошо,
если он уже есть в репозитории, однако возможно и то, что в официальных
репозиториях на сайте nginx его нет; тогда модуль нужно собирать самостоятельно.
Кроме того, качество сторонних модулей обычно сильно не дотягивает до качества
родных модулей, и можно столкнуться с неожиданными ошибками и даже уязвимостями. А ещё есть риск того, что в какой-то момент модуль окажется несовместим со
свежей версией и оперативно исправить это будет некому, ведь последнее (на
данный момент) изменение в репозитории ngx_fancyindex было два года назад.
Основной автор, похоже, забросил разработку. При этом по своим возможностям этот
способ, в общем-то, недалеко ушел от предыдущего варианта. Настраиваем autoindex_format xml;
и родной autoindex начинает выдавать список директорий в формате XML. Это
позволяет далее легко преобразовывать данные в практически любую желаемую форму
на стороне самого сервера или даже клиента. Наиболее интересно преобразование с помощью встроенного XSLT-фильтра: Шаблоны XSLT — очень удобный способ работать с XML. Вы можете создать свой
шаблон, а можете найти уже готовый и получить красочную HTML-страничку на
выходе. На некоторые из таких мы посмотрим далее. Из минусов использования XSLT-фильтра на стороне веб-сервера можно отметить чуть
большую нагрузку на процессор и дополнительную зависимость от libxml2/libxslt. А из плюсов здесь то, что на выходе можно получить готовый HTML абсолютно любого
желаемого вида, не требующий дополнительной обработки со стороны клиента, а
потому способ будет работать даже с отключенным JavaScript. И не обязательно преобразовывать индекс именно в HTML. Можно в любой другой
формат, например CSV, или даже вывести листинг в виде текстового ASCII-арта при
запросе curl-утилитой из консоли — ведь в ваших руках вся мощь
XSLT-шаблонизации. Как в предыдущем случае, но на этот раз указываем autoindex_format json;,
либо autoindex_format jsonp;
и получаем готовый JSON со всеми причитающимися возможностями по его дальнейшей
обработке. С помощью встроенного JS-модуля с JSON
легко работать на стороне сервера. Но наиболее практичным и интересным вариантом
выглядит обработка на клиенте, т. е. в самом браузере. Используя addition-фильтр
или шаблонизацию SSI,
можно взять список директорий в JSON и обернуть его в некий HTML-шаблон с
JavaScript-функцией для его преобразования. А можно просто настроить отдачу
статической HTML-страницы с JS-скриптом, который асинхронно запрашивает JSON, и
авто-индекс тогда будет работать как одностраничное приложение. Готовые решения
рассмотрим далее. Из минусов здесь — разве то, что если JavaScript может быть выключен или не
поддерживаться клиентом, но в наше время это большая редкость.В дополнительные
же плюсы можно записать то, что данные в формате JSON достаточно компактно
упакованы и прекрасно сжимаются. В случае одностраничного приложения объем
информации, передаваемой на клиент в ходе навигации по директориям, минимален. Если же ко всему этому настроить ещё и WebDAV, то доступна будет не только
навигация по директориям на сервере, но и манипуляции с ними. А теперь давайте для примера настроим несколько готовых решений, которые легко
найти в GitHub. Все действия будут выполняться на deb-дистрибутиве. Мы собираем пакеты для
огромного количества систем, так что
воспроизвести эти шаги на любой другой системе не составит труда. А для удобства
миграции с nginx мы написали простое руководство. У себя для простоты я буду использовать такую базовую заготовку минимальной
конфигурации (/etc/angie/angie.conf): Запустив с ней Angie: И открыв в браузере страницу по адресу http://example.org/angie/, я могу
наблюдать стандартный вывод авто-индекса: В качестве директории, для которой выводится список поддиректорий и файлов, была
выбрана директория /srv/www/public/angie/ на сервере, в которую я распаковал
исходники Angie. Сперва попробуем готовые XSLT-шаблоны с преобразованием на стороне сервера. Давайте попробуем включить вывод XML, для чего в наш location добавим
директиву autoindex_format xml: Обновим конфигурацию: И посмотрим, как будет выглядеть ответ: Как видим, ответ представляет собой довольно простой XML-документ, состоящий из
корневого элемента list. Внутри него могут располагаться элементы
directory, обозначающие директории, и элементы file, обозначающие файлы.
Также может встретиться элемент other в случае, если в файловой системе
присутствует объект другого типа (например, unix-сокет). Эти элементы содержат
соответствующие имена файлов, директорий и прочих объектов. У них всех есть
атрибут mtime, содержащий время модификации в формате ISO 8601, а у элементов
file дополнительно присутствует атрибут size, содержащий размер файла в
байтах. Далее установим динамический xslt-модуль: Модуль во время установки сам подсказывает, что нужно прописать в конфигурацию
для его загрузки. Так и сделаем: добавим указанную строчку в основную секцию
конфигурации: На этом подготовительные работы закончены, давайте пробовать. Репозиторий: EvilVir/Nginx-Autoindex Прежде всего скачиваем XSLT-шаблон autoindex.xslt: И прописываем его в настройках location с
помощью директивы xslt_stylesheet
таким образом: Обратите внимание, что файл шаблона у меня находится за пределами публичной
корневой директории веб-сервера, указанной в root. Не забываем перезагрузить конфигурацию: Чтобы убедиться, что всё прошло успешно, проверяем: Как видно поколение конфигурации изменилось с #2 на #3 (т. к. это был
уже 2-й reload), значит всё получилось. В этом заключается одно из множества отличий от nginx по удобству использования:
у Angie в именах процессов можно увидеть номер поколения, который увеличивается
на единицу при каждой успешной перезагрузке конфигурации, а в имени
мастер-процесса дополнительно выводится версия веб-сервера. Кроме того, можно
вывести список модулей с помощью команд
angie -m и angie -M. Если номер поколения не изменился или возникла другая проблема, то стоит
посмотреть лог ошибок: Но у нас всё хорошо: можно открыть http://example.org/angie/ в браузере и
посмотреть, что получилось: Тема для авто-индекса EvilVir/Nginx-Autoindex# Тема достаточно простая, она хорошо подойдет тем, кто любит темные ненавязчивые
тона. Из удобств здесь есть "хлебные крошки", по которым можно перемещаться на
несколько директорий вниз: "Хлебные крошки" в EvilVir/Nginx-Autoindex# Данный шаблон также поддерживает загрузку и удаление файлов через WebDAV. Так,
давайте попробуем расширить нашу конфигурацию: Тут мы дополнительно разрешили WebDAV-запросы
на добавление файлов с помощью метода PUT, а также с помощью директивы
client_max_body_size
увеличили ограничение на размер тела запроса до 10 Мб, чтобы иметь возможность
загружать файлы большего размера, чем задано по умолчанию (1 Мб). Для простоты настройку ограничения доступа оставим за рамками данной статьи.
Здесь достаточно отметить её очевидную необходимость в случае публичного доступа
к серверу. Создадим директорию для загрузки файлов: Чтобы рабочие процессы могли в неё писать, присвоим ей пользователя и группу, от которых они работают: Перезагружаем конфигурацию и проверяем, что номер поколения конфигурации снова сменился: Если бы этого не случилось, то причина обязательно была бы в логе: Ради примера открываем в браузере нашу директорию upload
(http://example.org/angie/upload/) и пробуем перетащить мышкой туда тарбол с
исходниками Angie: Загрузка файлов в EvilVir/Nginx-Autoindex# Похоже, всё работает! И даже индикатор прогресса загрузки есть. Всё же проверим, что файл действительно был загружен в директорию на сервере: Автор темы дает ещё более сложные примеры настроек, в том числе с авторизацией. Кроме того, у этой темы также есть форк: ViRb3/serve-zip. Он добавлят кнопку для скачивания
содержимого директории в виде одного ZIP-архива за счет проксирования запроса на
дополнительный HTTP-сервис на Go: Скачивание директории в виде ZIP-архива в ViRb3/serve-zip# Кстати, посмотреть тему вживую можно тут: https://download.angie.software/ А мы двигаемся дальше, к следующей теме оформления. Репозиторий: gibatronic/ngx-superbindex Принцип всё тот же, скачиваем XSLT-шаблон superbindex.xslt: И указываем его в нашей конфигурации: Опять перезагружаем конфигурацию: И убеждаемся, что все прошло успешно: В противном случае смотрим ошибку в логе: У нас все в порядке, поэтому обновляем в браузере страницу
http://example.org/angie/ и смотрим на результат: Навигация с помощью клавиатуры в gibatronic/ngx-superbindex# Это минималистичная тема с довольно необычными возможностями вроде навигации с
помощью набора имен файлов или директорий на клавиатуре. Из других возможностей здесь заявлены настройки цветовой палитры, а также
автоматическое переключение между светлой и темной темой в зависимости от
настроек системы. Идем дальше, к следующей теме оформления. Репозиторий: jbox-web/nginx-index-template Скачиваем XSLT-шаблон nginx_template.xslt: И прописываем его в настройках: Обратите внимание, что данный шаблон в качестве параметра требует передачи URI. После сохранения конфигурации не забываем перезагрузить ее: И проверить смену поколения: В случае ошибок проверяем лог: Что получилось в браузере, покажет страница http://example.org/angie/: Тема для авто-индекса jbox-web/nginx-index-template# Интересно, что в заголовке указано «Debian Repository» — видимо, автор темы
делал её под эту задачу. Но заголовок можно легко найти и поменять в самом
шаблоне: Это визуально легкая тема, но здесь есть "хлебные крошки". Смотрим следующую. Репозиторий: Airkro/nginx-simple-index Скачиваем XSLT-шаблон template.xslt: И прописываем его в настройках: Перезагрузка конфигурации: Проверяем, что новая конфигурация загружена: Если нет, то смотрим ошибку в логе: В результате http://example.org/angie/ теперь выглядит так: Тема для авто-индекса Airkro/nginx-simple-index# Это простенькая тема, но есть "хлебные крошки" и поддержка темного режима. Из
необычных возможностей: через параметр шаблона lang='zh-cn' можно задать
локализацию на китайском. При желании тем же способом можно легко добавить
перевод на русский; вот как это выглядит в шаблоне: Я добавил: И прописал в настройках: Вот что получилось: Русификация темы Airkro/nginx-simple-index# Кстати, легко сделать так, чтобы язык выбирался в зависимости от локали
браузера. Для этого добавляем такой map: И в шаблоне указываем переменную из него: Конечно это не очень точный способ парсить заголовок Accept-Language, но в
первом приближении работает. Если заморочиться, то можно сделать лучше с помощью
js_set. Да и шаблон можно усовершенствовать так, чтобы тот выбирал нужную форму слова
«директория» или «директорий» в зависимости от их числа. А теперь посмотрим, что нам может предложить JSON с рендерингом на JavaScript. Попробуем для начала просто вывод JSON, для чего в location добавим директиву
autoindex_format json: Обновляем конфигурацию: И смотрим на ответ: Данный вывод JSON представляет из себя массив объектов, которые содержат следующие поля: name — строка, имя элемента в файловой системе; type — строка, тип элемента:
* file у файлов,
* directory у директорий,
* other у всех остальных (например, unix-сокет); mtime — строка, время модификации в HTTP-формате, который понимает JavaScript-функция Date(); size (только у файлов) — число, размер файла в байтах. А вот так выглядела бы настройка autoindex_format jsonp: Обратите внимание, что в качестве аргументов запроса я передал
?callback=my_func. Аргумент callback= передает имя функции, в вызов которой будет обернут
переданный JSON. Таким образом, его вывод может быть вставлен непосредственно в
HTML-тег <script>: При этом поле Content-Type заголовка ответа будет содержать подходящее
значение application/javascript вместо application/json. Разумеется, функция
my_func(), которую позовет этот скрипт, должна быть где-то определена. Если аргумент с названием функции не передавать, модуль вернет обычный JSON. В
наших дальнейших примерах его будет достаточно, поэтому настройка jsonp нам не
пригодится. Итак, попробуем первую тему на базе JavaScript и JSON. Репозиторий: EthraZa/NGINdeX.io Эта тема работает по принципу включения списка директорий в формате JSON внутрь
HTML-страницы, содержащей в себе JavaScript-код и CSS-стили для рендеринга.Для
этого используется модуль addition,
который умеет добавлять фрагменты перед телом ответа и после него. Таким
образом, HTML код разбит на две части, которые обрамляют JSON из модуля
autoindex. Создадим в /srv/www/public/ поддиректорию под названием autoindex, чтобы не мусорить: И скачаем в неё две странички, header.html и footer.html, которые
составляют заголовок и хвост шаблона соответственно: Теперь внесем следующие настройки в конфигурацию: Тут мы указали с помощью addition_types,
что модуль addition
должен срабатывать на ответ с типом application/json, который и ожидается в
данном случае из модуля autoindex,
когда autoindex_format
выставлен равным json. Далее с помощью директив add_before_body
и add_after_body
мы задали URI запросов для наших фрагментов, которые будут добавлены в начало и
конец соответственно. Важно! Обратите внимание, что эти директивы задают не путь к файлу, а
подзапросы в рамках Angie — эти подзапросы будут обработаны в рамках текущего
блока server,
поэтому, чтобы ответом на них стали скачанные нами файлы, мы добавили отдельный
location /autoindex/ и
прописали в нем директиву root. Таким
образом, на подзапросы /autoindex/header.html и /autoindex/footer.html будут
отданы файлы /srv/www/public/autoindex/header.html и
/srv/www/public/autoindex/footer.html соответственно (root + URI). Поскольку предполагается, что файлы внутри нашей директории autoindex будут
открываться только внутренними подзапросами, мы сделали их недоступными извне с
помощью директивы internal. И напоследок с помощью add_header
мы меняем поле заголовка ответа Content-Type на text/html, поскольку после
присоединения HTML фрагментов наш ответ будет представлять из себя валидную
HTML-страничку, которую браузер соответствующим образом должен обработать. Перезагружаем конфигурацию: И проверяем, сменилось ли поколение конфигурации: Если что-то пошло не так, конфигурация не обновилась или мы не увидели
ожидаемого результата, открыв страницу в браузере, смотрим ошибки в логе: А у меня все заработало с первого раза, и я увидел следующую картинку, обновив
страницу с исходниками Angie http://example.org/angie/: Тема для авто-индекса EthraZa/NGINdeX.io# Тут на нас обрушивается мощь JavaScript: сортировка по столбцам; фильтрация по имени; переключение цветовой палитры в выпадающем списке; вывод числа файлов, директорий и общего объема справа внизу; кнопки для скачивания файла либо просмотра прямо в браузере. Через параметры запроса можно также задать фоновое изображение или указать
локаль для формата отображения даты. Также можно менять используемую
CSS-библиотеку, раскомментировав желаемую в заголовке файла header.html. Очень навороченный шаблон. Попробуем что-нибудь еще. Репозиторий: ccarney16/nginx-autoindex На этот раз скачиваем и распаковываем все содержимое репозитория в виде
ZIP-архива (но можно воспользоваться и git clone): Настройка практически идентична предыдущему примеру, поэтому я не буду её
подробно разбирать ещё раз: Если что-то непонятно, посмотрите разбор конфигурации предыдущей темы. Отмечу лишь, что из location /autoindex/,
помимо смены пути в root, также
была убрана директива internal,
поскольку в данной директории ещё находятся CSS-стили и другие элементы
страницы, которые будут подгружаться уже внешними запросами от клиента. Производим перезагрузку конфигурации: И обязательно контролируем смену поколения у процессов: Если её не произошло или возникла какая-то другая проблема, смотрим ошибки в
логе: В моем случае новая конфигурация успешно загружена, и по адресу
http://example.org/angie/ я вижу новую тему: Тема для авто-индекса ccarney16/nginx-autoindex# Особо добавить нечего; очень простая тема. Идем дальше. Репозиторий: kstep/nginx-autoindex-js Как и в предыдущем случае, скачиваем и распаковываем содержимое репозитория: Хотя эта тема также работает на базе JavaScript и JSON, она принципиально
отличается от двух предыдущих. Здесь мы имеем дело с одностраничным приложением.
В директории nginx-autoindex-js-master, которую мы распаковали из архива с
репозиторием, находится index.html, а
скрипты на этой странице будут выполнять асинхронные AJAX-запросы, поэтому нам
больше не нужно добавлять результат работы авто-индекса непосредственно внутрь
страницы. Соответственно, конфигурация выглядит проще: Обратите также внимание, что я использовал alias вместо
root.
Директива alias подменяет собой часть пути из location, а
root добавляется к нему. В данном случае требуется именно подмена, т. к. я
хочу, чтобы по запросу /autoindex/ открывался файл
/srv/www/public/nginx-autoindex-js-master/index.html. А если бы там осталась
директива root, то сервер пытался бы вместо этого обратиться к несуществующему
файлу /srv/www/public/nginx-autoindex-js-master/autoindex/index.html и
возвращал ошибку 404. Кроме того, чтобы настроить эту тему и задать URI, к которому необходимо делать
AJAX-запросы для получения списка файлов, требуется, чтобы в директории
находился файл config.json. Пример этого файла уже расположен там под
названием config-example.json,
поэтому просто переименовываем его: И редактируем любым удобным вам редактором, я воспользуюсь nano: В нашем случае он должен принять следующий вид: Таким образом при открытии index.html, который в нашей конфигурации будет
располагаться по адресу http://example.org/autoindex/, будут выполняться
AJAX-запросы к http://example.org/angie/. На этом настройка закончена. Далее перезагружаем конфигурацию: Проверяем смену поколения: Если обновления не случилось или что-то не работает, обязательно смотрим ошибки
в логе: Я все настроил правильно, но обратите внимание, что на этот раз мы откроем
другую страницу. Это не location /angie/, где работает autoindex и
возвращает только JSON, а тот location, где находится само одностраничное
приложение, т. е. в нашем случае http://example.org/autoindex/: Тема для авто-индекса kstep/nginx-autoindex-js# Есть сортировка по столбцам и кнопка принудительного обновления. Что примечательно, как все быстро работает, просто летает! Все эксперименты я
провожу на удаленном сервере, который находится в другом городе, а ощущение,
будто перемещаешься по локальному диску. Видимо, сказывается то, что при
открытии очередной директории подгружаются только компактные данные в формате
JSON и страница не перезагружается полностью, за счет чего производится минимум
необходимых операций с DOM-деревом. У темы есть проблема, но она легко устранима:
kstep/nginx-autoindex-js#1 Нужно лишь слегка подправить код страницы, как предложено в данном тикете. Иначе
при текущей настройке пути к файлам оказываются неправильными и файлы не
открываются. Переходим к следующей теме. Репозиторий: spring-raining/pretty-autoindex Также скачиваем и распаковываем содержимое всего репозитория: Как и предыдущая тема, эта тоже работает по принципу одностраничного приложения.
Повторяться не буду; если что-то не ясно, читайте описание настроек у предыдущей
темы. В данном случае конфигурация будет такой: Тут отметим, что само одностраничное приложение в виде index.html
с зависимостями находится в поддиректории /dist/, куда и
указывает alias в
настройке. Также внутри этой директории располагается файл настроек config.js,
в который мы пропишем URI для запросов авто-индекса в поле address: Я специально указал тут /angie без слэша на конце, иначе приложение имеет
тенденцию добавлять туда слишком много слэшей, что не нарушает работу, но
визуально выглядит некрасиво. Перезагружаем нашу конфигурацию: И проверяем поколение: Смотрим в лог
ошибок, если нужно: Если все настройки корректны, то страница http://example.org/autoindex/ примет
следующий вид: Тема для авто-индекса spring-raining/pretty-autoindex# Простое оформление без каких-то дополнительных возможностей. Автор темы предлагает другую настройку с участием дополнительного блока
server,
слушающего отдельный порт, но я посчитал её избыточной. --- На этом у меня всё по данной теме. Если возникнут какие-то сложности или
остались вопросы, опишите их в комментариях к статье, либо у нас на форуме или Telegram-канале поддержки. Также, если вдруг вам попадались
какие-то другие интересные готовые темы оформления авто-индекса или вы хотите
поделиться своей, не стесняйтесь рассказать об этом. И было бы неплохо узнать, какие у вас ещё возникают сложности с настройками не
только авто-индекса, но и любых других модулей и сценариев. Эта информация
поможет в подготовке будущих статей и будет учтена при улучшении документации
веб-сервера Angie, над которой мы
непрерывно работаем. Спасибо за внимание!Способы улучшения авто-индекса#
1. sub- и addition-фильтры#
2. "Fancy Index" и другие сторонние модули#
3. XML + XSLT#
location / {
autoindex on;
autoindex_format xml;
xslt_stylesheet /path/to/template.xslt;
}
4. JSON(P) + JavaScript#
Готовые решения#
events {}
http {
server {
listen 80;
location /angie/ {
root /srv/www/public;
autoindex on;
}
}
}
# service angie start
Готовые XSLT-шаблоны для XML#
location /angie/ {
root /srv/www/public;
autoindex on;
autoindex_format xml;
}
# service angie reload
$ curl https://example.org/angie/
<?xml version="1.0"?>
<list>
<directory mtime="2025-03-09T18:59:03Z">auto</directory>
<directory mtime="2025-03-09T18:59:03Z">conf</directory>
<directory mtime="2025-03-09T18:59:03Z">contrib</directory>
<directory mtime="2025-03-09T18:59:03Z">html</directory>
<directory mtime="2025-03-09T18:59:03Z">man</directory>
<directory mtime="2025-02-13T11:02:48Z">src</directory>
<directory mtime="2025-03-09T18:59:03Z">tests</directory>
<file mtime="2025-02-13T04:40:13Z" size="22662">CHANGES</file>
<file mtime="2025-02-13T04:40:13Z" size="36858">CHANGES.ru</file>
<file mtime="2025-02-13T04:40:13Z" size="1358">LICENSE</file>
<file mtime="2025-02-13T04:40:13Z" size="570">README</file>
<file mtime="2025-02-13T04:40:13Z" size="2422">configure</file>
</list>
# apt install angie-module-xslt
...
Unpacking angie-module-xslt (1.8.2-1~noble) ...
Setting up angie-module-xslt (1.8.2-1~noble) ...
----------------------------------------------------------------------
The XSLT dynamic module for Angie has been installed.
To enable this module, add the following to /etc/angie/angie.conf
and reload angie:
load_module modules/ngx_http_xslt_filter_module.so;
Please refer to the modules documentation for further details:
https://en.angie.software/angie/docs/configuration/modules/http/http_xslt/
events {}
load_module modules/ngx_http_xslt_filter_module.so;
http {
...
}
EvilVir/Nginx-Autoindex#
$ cd /srv/www
$ wget https://raw.githubusercontent.com/EvilVir/Nginx-Autoindex/refs/heads/master/autoindex.xslt
location /angie/ {
root /srv/www/public;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/autoindex.xslt;
}
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
Loaded: loaded (/usr/lib/systemd/system/angie.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-03-13 09:53:51 MSK; 5min ago
Docs: https://en.angie.software/angie/docs/
Process: 1107393 ExecStart=/usr/sbin/angie -c /etc/angie/angie.conf (code=exited, status=0/SUCCESS)
Process: 1108004 ExecReload=/bin/sh -c /bin/kill -s HUP $(/bin/cat /run/angie.pid) (code=exited, status=0/SUCCESS)
Main PID: 1107395 (angie)
Tasks: 6 (limit: 4451)
Memory: 144.1M (peak: 230.1M)
CPU: 2.414s
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #3 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1107695 "angie: worker process is shutting down #2"
├─1108008 "angie: worker process #3"
├─1108009 "angie: worker process #3"
├─1108010 "angie: worker process #3"
└─1108011 "angie: worker process #3"
...
# cat /var/log/angie/error.log
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/autoindex.xslt;
dav_methods PUT;
client_max_body_size 10M;
}
$ cd /srv/www/public/angie/
$ mkdir upload
# chown angie:angie upload
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #4 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1108008 "angie: worker process is shutting down #3"
├─1108011 "angie: worker process is shutting down #3"
├─1108244 "angie: worker process #4"
├─1108245 "angie: worker process #4"
├─1108246 "angie: worker process #4"
└─1108247 "angie: worker process #4"
# cat /var/log/angie/error.log
$ ls -l upload
total 1640
-rw------- 1 angie angie 1677058 Mar 9 23:12 angie-1.8.2.tar.gz
gibatronic/ngx-superbindex#
$ cd /srv/www
$ wget https://github.com/gibatronic/ngx-superbindex/releases/download/v2.0.1/superbindex.xslt
location / {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/superbindex.xslt;
}
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #5 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1108247 "angie: worker process is shutting down #4"
├─1109361 "angie: worker process #5"
├─1109362 "angie: worker process #5"
├─1109363 "angie: worker process #5"
└─1109364 "angie: worker process #5"
...
# cat /var/log/angie/error.log
jbox-web/nginx-index-template#
$ cd /srv/www
$ wget https://raw.githubusercontent.com/jbox-web/nginx-index-template/refs/heads/master/nginx_template.xslt
location / {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/nginx_template.xslt path='$uri';
}
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #6 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1109362 "angie: worker process is shutting down #5"
├─1110286 "angie: worker process #6"
├─1110287 "angie: worker process #6"
├─1110288 "angie: worker process #6"
└─1110289 "angie: worker process #6"
...
# cat /var/log/angie/error.log
# grep "Debian Repository" nginx_template.xslt
<title>Debian Repository</title>
<h1 class="mt-5">Debian Repository</h1>
<span class="text-muted">Debian Repository</span>`
Airkro/nginx-simple-index#
$ cd /srv/www
$ wget https://raw.githubusercontent.com/Airkro/nginx-simple-index/refs/heads/master/template.xslt
location / {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/nginx_template.xslt path='$uri';
}
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #7 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1110929 "angie: worker process #7"
├─1110930 "angie: worker process #7"
├─1110931 "angie: worker process #7"
└─1110932 "angie: worker process #7"
...
# cat /var/log/angie/error.log
<i18n:zh-cn
folders=" 个目录,"
files=" 个文件"
timing="最近修改时间"
filename="文件名"
size="大小"
root="根目录"
/>
<i18n:en-us
folders=" folders, "
files=" files"
timing="Last modified"
filename="File name"
size="Size"
root="root"
/>
<i18n:ru-ru
folders=" директори(я/й), "
files=" файл(ов)"
timing="Дата"
filename="Имя"
size="Размер"
root="⌂"
/>
xslt_stylesheet /srv/www/nginx_template.xslt path='$uri' lang='ru-ru';
map $http_accept_language $autoindex_lang {
~ru ru-ru;
~zh zh-cn;
default en-us;
}
xslt_stylesheet /srv/www/template.xslt path='$uri' lang='$autoindex_lang';
Готовые решения на базе JSON#
location /angie/ {
root /srv/www/public;
autoindex on;
autoindex_format json;
}
# service angie reload
$ curl https://example.org/angie/
[
{ "name":"auto", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"conf", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"contrib", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"html", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"man", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"src", "type":"directory", "mtime":"Thu, 13 Feb 2025 11:02:48 GMT" },
{ "name":"tests", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"CHANGES", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":22662 },
{ "name":"CHANGES.ru", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":36858 },
{ "name":"LICENSE", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":1358 },
{ "name":"README", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":570 },
{ "name":"configure", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":2422 }
]
$ curl https://example.org/angie/?callback=my_func
/* callback */
my_func([
{ "name":"auto", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"conf", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"contrib", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"html", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"man", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"src", "type":"directory", "mtime":"Thu, 13 Feb 2025 11:02:48 GMT" },
{ "name":"tests", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"CHANGES", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":22662 },
{ "name":"CHANGES.ru", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":36858 },
{ "name":"LICENSE", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":1358 },
{ "name":"README", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":570 },
{ "name":"configure", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":2422 }
]);
`<script src="https://example.org/angie/?callback=my_func"></script>`
EthraZa/NGINdeX.io#
$ cd /srv/www/public/
$ mkdir autoindex
$ cd autoindex
$ wget https://raw.githubusercontent.com/EthraZa/NGINdeX.io/refs/heads/main/header.html
$ wget https://raw.githubusercontent.com/EthraZa/NGINdeX.io/refs/heads/main/footer.html
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
addition_types application/json;
add_before_body /autoindex/header.html;
add_after_body /autoindex/footer.html;
add_header Content-Type text/html;
}
location /autoindex/ {
internal;
root /srv/www/public;
}
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #11 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1112978 "angie: worker process is shutting down #10"
├─1114838 "angie: worker process #11"
├─1114839 "angie: worker process #11"
├─1114840 "angie: worker process #11"
└─1114841 "angie: worker process #11"
...
# cat /var/log/angie/error.log
ccarney16/nginx-autoindex#
$ cd /srv/www/public
$ wget https://github.com/ccarney16/nginx-autoindex/archive/refs/heads/master.zip
$ unzip master.zip
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
addition_types application/json;
add_before_body /autoindex/header.html;
add_after_body /autoindex/footer.html;
add_header Content-Type text/html;
}
location /autoindex/ {
root /srv/www/public/nginx-autoindex-master/;
}
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #12 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1115537 "angie: worker process #12"
├─1115538 "angie: worker process #12"
├─1115539 "angie: worker process #12"
└─1115540 "angie: worker process #12"
...
# cat /var/log/angie/error.log
kstep/nginx-autoindex-js#
$ cd /srv/www/public
$ wget https://github.com/kstep/nginx-autoindex-js/archive/refs/heads/master.zip
$ unzip master.zip
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
}
location /autoindex/ {
alias /srv/www/public/nginx-autoindex-js-master/;
}
$ cd /srv/www/public/nginx-autoindex-js-master/
$ mv config-example.json config.json
$ nano config.json
$ cat config.json
{
"base_index_url": "/angie/",
"tail_slash": false
}
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #13 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1115537 "angie: worker process is shutting down #12"
├─1115538 "angie: worker process is shutting down #12"
├─1115540 "angie: worker process is shutting down #12"
├─1118845 "angie: worker process #13"
├─1118846 "angie: worker process #13"
├─1118847 "angie: worker process #13"
└─1118848 "angie: worker process #13"
...
# cat /var/log/angie/error.log
spring-raining/pretty-autoindex#
$ cd /srv/www/public
$ wget https://github.com/spring-raining/pretty-autoindex/archive/refs/heads/master.zip
$ unzip master.zip
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
}
location /autoindex/ {
alias /srv/www/pretty-autoindex-master/dist/;
}
$ cd /srv/www/pretty-autoindex-master/dist/
$ cat config.js
var conf = {
name: 'pretty-autoindex',
address: '/angie',
visibilityOptions: {
size: {
use: true,
type: 'readable' //raw, readable, both
},
date: {
use: true,
type: 'moment' //raw, moment, both
}
}
};
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #14 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1118847 "angie: worker process is shutting down #13"
├─1119847 "angie: worker process #14"
├─1119848 "angie: worker process #14"
├─1119849 "angie: worker process #14"
└─1119850 "angie: worker process #14"
...
# cat /var/log/angie/error.log