V prakticky každé webové aplikaci, která používá obrázky, existuje potřeba vytvářet zmenšené kopie těchto obrázků, přičemž často existuje několik formátů dalších obrázků.
Také přidání nových velikostí do existující aplikace vyvolává určité potíže. Odtud vyvstává úkol:
Úkol
Určíme seznam požadavků:
- Vytvářet další obrázky jakýchkoli formátů za běhu bez přidávání dalšího funkčního vybavení do aplikace v jakémkoli okamžiku existence aplikace;
- Další obrázky by neměly být vytvářeny při každém požadavku;
- Zabránit možnosti vytváření dalších obrázků nevyhovujících formátů.
Vysvětlím poslední bod, neboť je trochu v rozporu s prvním bodem. Pokud umožníme vytváření jakýchkoli obrázků, existuje možnost útoku na web vytvořením velkého množství požadavků na změnu velikosti obrázku do nekonečného počtu formátů, proto je třeba tuto zranitelnost uzavřít.
Konfigurace instalace nginx
Pro splnění výše uvedených požadavků budeme potřebovat následující sadu modulů nginx:
- — pro změnu velikosti obrázků;
- — pro caching;
- — pro ochranu proti spamu;
Moduly ngx_http_image_filter_module a ngx_http_secure_link_module defaultně nejsou instalovány, proto je třeba je uvést v průběhu konfigurace instalace nginx:
phoinix@phoinix-work:~\/src\/nginx-0.8.29
$ .\/configure --with-http_secure_link_module --with-http_image_filter_module
Konfigurace nginx
Do konfigurace našeho hostitele přidáme nový location a obecné parametry cache:
...
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;
}
# Возвращаем ошибку
location = /preview/404 {
internal;
default_type image/gif;
alias /www/myprojects/image/noimage.gif;
}
...
}
...
Také přidáme nový host do konfigurace:
server {
server_name myproject.ru;
listen 81;
access_log /www/myproject.ru/logs/nginx.preview.access_log;
error_log /www/myproject.ru/logs/nginx.preview.error_log info;
# Указываем секретное слово для md5
secure_link_secret secret;
# Ошибки отправляем она отдельный location
error_page 403 404 415 500 502 503 504 = @404;
# location Для фильтра size
location ~ ^/i/[^/]+/(.+) {
# грязный хак от Игоря Сысоева *
alias /www/myproject.ru/images/$1;
try_files "" @404;
# Проверяем правильность ссылки и md5
if ($secure_link = "") { return 404; }
# Используем соответсвующий фильтр
image_filter size;
}
# По аналогии остальные location для других фильтров
location ~ ^/c/[^/]+/(d+|-)x(d+|-)/(.) {
set $width $1;
set $height $2;
alias /www/myproject.ru/images/$3;
try_files "" @404;
if ($secure_link = "") { return 404; }
image_filter crop $width $height;
}
location ~ ^/r/[^/]+/(d+|-)x(d+|-)/(.) {
set $width $1;
set $height $2;
alias /www/myproject.ru/images/$3;
try_files "" @404;
if ($secure_link = "") { return 404; }
image_filter resize $width $height;
}
location @404 { return 404; }
}
V důsledku toho lze další obrázky získat na odkazy:
- [md5]/[path_to_image]
- [md5]/[size]/[path_to_image]
- [md5]/[size]/[path_to_image]
* try_files — citlivý na mezery a ruské znaky, proto bylo nutné udělat workaround s Spravovat aliasy obrazů.
Použití ve webové aplikaci
Na úrovni webové aplikace lze provést následující proceduru (Perl):
sub proxy_image {
use Digest::MD5 qw /md5_hex/;
my %params = @_;
my $filter = {
size => 'i',
resize => 'r',
crop => 'c'
}->{$params{filter}} || 'r';
my $path = ($filter ne 'i' ?
( $params{height} || '_' ) . 'x' . ( $params{width} || '_' ) . '\/ ' :
()
) . $params{source};
my $md5 = md5_hex( $path . 'secret' );
$path = '\/preview\/ ' . $filter . '\/ ' . $md5 . '\/ ' . $path;
return $path;
}
my $preview_path = &proxy_image(
source => 'image1.jpg',
height => 100,
width => 100,
filter => 'resize'
);
I když bych také doporučil počítat velikosti náhled.
Hřebíky
Při odstranění původního obrázku se náhledy přirozeně neodstraní z cache, dokud nebude cache invalidována, v našem případě však náhledy mohou existovat po dobu jednoho dne po odstranění, ale to je maximum.
Zdroj: habr.com
