Weserv Images#

Модуль weserv изменяет размер, обрезает и преобразует изображения на лету. Он входит в проект weserv/images, на коде которого работает сервис wsrv.nl. Модуль работает в одном из двух режимов:

  • proxy — загружает изображение с удаленного сервера, указанного в параметре запроса url;

  • filter — обрабатывает изображения в ответах других обработчиков, например в статических файлах.

В обоих режимах обработку задает строка запроса: w и h задают целевую ширину и высоту, fit — способ вписать в них изображение, output — выходной формат и так далее. Полный список параметров приведен в документации wsrv.nl.

Установка#

Для установки модуля используйте один из следующих пакетов:

  • Angie: angie-module-weserv-images;

  • Angie PRO: angie-pro-module-weserv-images.

Директивы#

Основные директивы модуля:

  • weserv — включает модуль в блоке location и выбирает режим: proxy или filter;

  • weserv_deny_ip — запрещает загрузку изображений с указанных адресов или диапазонов CIDR; действует только на IP-адреса, записанные в параметре url напрямую, но не на имена хостов;

  • weserv_connect_timeout, weserv_send_timeout, weserv_read_timeout — задают таймауты на установку соединения с удаленным сервером, передачу ему запроса и чтение его ответа;

  • weserv_max_size — ограничивает размер обрабатываемого изображения;

  • weserv_limit_input_pixels, weserv_limit_output_pixels — ограничивают число пикселей во входном и выходном изображениях;

  • weserv_savers — перечисляет выходные форматы, которые можно запросить параметром output;

  • weserv_quality — задает качество выходного изображения по умолчанию; директивы вроде weserv_jpeg_quality и weserv_webp_quality переопределяют его для отдельного формата.

В режиме proxy переменная $weserv_response_length содержит размер загруженного исходного изображения в байтах; в режиме filter переменная не задается.

Все директивы и их значения по умолчанию описаны в документации модуля.

Загрузка модуля#

Для работы с модулем необходимо загрузить его в контексте main{}:

load_module modules/ngx_weserv_module.so;

Пример конфигурации#

server {
    listen 80;

    server_name images.weserv.local;

    root /var/www/imagesweserv/public;

    location / {
        weserv proxy;

        add_header X-Upstream-Response-Length $weserv_response_length;
    }

    location /static/ {
        weserv filter;

        alias /var/www/imagesweserv/public/;
    }
}

Здесь запросы с параметром url обрабатываются в режиме proxy, а для запросов к /static/ модуль обрабатывает файлы из каталога /var/www/imagesweserv/public/ в режиме filter. Запрос к / без url модуль не обрабатывает, и такой запрос получает статический файл из root.

Имена хостов в url Angie разрешает собственным резолвером; по умолчанию он обращается к DNS-серверам, перечисленным в /etc/resolv.conf, а файл /etc/hosts не учитывается. Чтобы использовать другие DNS-серверы, задайте директиву resolver. IP-адреса в url разрешать не нужно.

Демонстрация работы#

Допустим, сервер по адресу 127.0.0.1:8081 отдает исходное изображение sample.png размером 400 × 300 пикселей (2351 байт), а тот же файл лежит в каталоге /var/www/imagesweserv/public/.

В режиме proxy модуль загружает изображение, указанное в url, и масштабирует его до ширины w с сохранением пропорций:

$ curl -s -D - -o out.png 'http://localhost/?url=127.0.0.1:8081/sample.png&w=100'
HTTP/1.1 200 OK
...
Content-Type: image/png
Content-Length: 15633
Content-Disposition: inline; filename=image.png
Link: <http://127.0.0.1:8081/sample.png>; rel="canonical"
...
X-Upstream-Response-Length: 2351

$ file out.png
out.png: PNG image data, 100 x 75, 8-bit/color RGB, non-interlaced

Заголовок Link указывает на исходное изображение, а X-Upstream-Response-Length передает его размер; этот заголовок пример конфигурации добавляет из $weserv_response_length. Префикс http:// в url можно не указывать; если добавить к тому же запросу &output=jpg, ответом будет изображение JPEG.

В режиме filter те же параметры применяются к локальному файлу; здесь изображение обрезается до квадрата 50 × 50 и преобразуется в WebP:

$ curl -s -D - -o small.webp 'http://localhost/static/sample.png?w=50&h=50&fit=cover&output=webp'
HTTP/1.1 200 OK
...
Content-Type: image/webp
Content-Length: 250
...

Файл small.webp — изображение WebP размером 50 × 50 пикселей. Заголовка X-Upstream-Response-Length в ответе нет: location /static/ его не добавляет, а в режиме filter переменная $weserv_response_length не задается.

Если модуль не может вернуть изображение, он отвечает ошибкой в формате JSON:

$ curl -s 'http://localhost/?url=127.0.0.1:8081/missing.png'
{"status":"error","code":404,"message":"The requested URL returned error: 404"}

Дополнительная информация#

Версия: v5.1.0

Подробная документация и исходный код доступны по ссылке: weserv/images