幾乎在所有使用圖像的 Web 應用程式中,都需要建立這些圖像的小型副本,並且附加圖像通常有多種格式。
為現有應用程式新增維度也會造成一些麻煩。 因此任務是:
任務
讓我們表示一下要求清單:
- 在應用程式存在期間隨時產生任何格式的附加圖像,而無需在應用程式中引入附加功能;
- 不需要根據每個請求產生額外的圖像;
- 停用產生未指定格式的其他影像的功能。
我將解釋最後一點,因為它與第一點略有矛盾。 如果我們開放任何圖像的生成,那麼就有可能透過生成大量請求將圖像大小調整為無限多種格式來攻擊網站,因此需要關閉此漏洞。
nginx安裝設定
為了解決上述需求,我們需要以下一組 nginx 模組:
ngx_http_image_filter_module — 用於調整影像大小;ngx_http_proxy_模組 - 用於緩存;ngx_http_secure_link_module — 防止垃圾郵件;
模塊 ngx_http_image_filter_module и ngx_http_secure_link_module 預設不安裝,因此必須在安裝配置階段指定 nginx的:
phoinix@phoinix-work:~/src/nginx-0.8.29
$ ./configure --with-http_secure_link_module --with-http_image_filter_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;
}
# Возвращаем ошибку
location = /preview/404 {
internal;
default_type image/gif;
alias /www/myprojects/image/noimage.gif;
}
...
}
...
我們還在配置中新增一個新主機:
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; }
}
因此,可以使用以下連結獲取其他圖像:
myproject.ru/preview/i [md5]/[影像路徑]myproject.ru/preview/c [md5]/[大小]/[影像路徑]myproject.ru/預覽/r [md5]/[大小]/[影像路徑]
* 嘗試文件 - 對空格和俄語字元敏感,所以我不得不使用 別號.
在網路應用程式中使用
在 Web 應用程式級別,您可以執行下列程序 (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'
);
雖然我也建議計算尺寸 預習.
耙
當刪除原始影像時,預覽自然不會從快取中刪除,直到快取失效,而在我們的例子中,預覽在刪除後可以存在一天,但這是最長的時間。
來源: www.habr.com