Практично в будь-якій веб-додатку, що використовує зображення, існує потреба формувати зменшені копії цих зображень, причому часто, форматів додаткових зображень кілька.
Також викликає деякий головний біль додавання нових розмірів на існуючому додатку. Звідси завдання:
Завдання
Позначимо перелік вимог:
Формувати додаткові зображення будь-яких форматів на льоту без внесення додаткового функціоналу додатку у будь-який момент існування програми;
Додаткові зображення не повинні формуватись при кожному запиті;
Закрити можливість створення додаткових зображень невстановлених форматів.
Поясню останній пункт, бо він трохи суперечить першому пункту. Якщо ми зробимо відкритим формування будь-яких зображень, існує можливість атаки на сайт шляхом формування великої кількості запитів на ресайз зображення в нескінченну кількість форматів, тому цю вразливість потрібно закрити.
Конфігурація установки nginx
Для вирішення вищезгаданих вимог нам знадобиться наступний набір модулів nginx:
Модулі ngx_http_image_filter_module и ngx_http_secure_link_module за замовчуванням не ставляться, тому їх потрібно вказати на етапі конфігурації установки Nginx:
У конфігурацію нашого хоста додаємо новий розташування та загальні параметри кешу:
...
proxy_cache_path /www/myprojects/cache levels=1:2 keys_zone=image-preview:10m;
...
server {
...
location ~ ^/preview/([cir])/(.+) {
# Тип операции
set $oper $1;
# Параметры изображения и путь к файлу
set $remn $2;
# Проксируем на отдельный хост
proxy_pass http://myproject.ru:81/$oper/$remn;
proxy_intercept_errors on;
error_page 404 = /preview/404;
# Кеширование
proxy_cache image-preview;
proxy_cache_key "$host$document_uri";
# 200 ответы кешируем на 1 день
proxy_cache_valid 200 1d;
# остальные ответы кешируем на 1 минуту
proxy_cache_valid any 1m;
}
Хоча я ще рекомендував би розраховувати розміри попередній перегляд.
Граблі
При видаленні вихідного зображення, прев'ю, природно, видаляться з кешу не будуть поки кеш не інвалідизується, а в нашому випадку прев'ю можуть існувати протягом доби після видалення, але це максимум за часом.