Di hampir semua aplikasi web yang menggunakan gambar, ada kebutuhan untuk membuat salinan kecil dari gambar tersebut, dan seringkali terdapat beberapa format untuk gambar tambahan.
Menambahkan dimensi baru ke aplikasi yang sudah ada juga menyebabkan beberapa masalah. Oleh karena itu tugasnya:
Tugas
Mari kita tentukan daftar persyaratannya:
- Menghasilkan gambar tambahan dalam format apa pun dengan cepat tanpa memasukkan fungsionalitas tambahan ke dalam aplikasi kapan pun selama keberadaan aplikasi;
- Gambar tambahan tidak perlu dibuat pada setiap permintaan;
- Nonaktifkan kemampuan untuk menghasilkan gambar tambahan dengan format yang tidak ditentukan.
Poin terakhir akan saya jelaskan, karena sedikit bertentangan dengan poin pertama. Jika kita membuat pembuatan gambar apa pun terbuka, maka ada kemungkinan serangan terhadap situs dengan menghasilkan permintaan dalam jumlah besar untuk mengubah ukuran gambar ke dalam format yang jumlahnya tidak terbatas, sehingga kerentanan ini perlu ditutup.
konfigurasi instalasi nginx
Untuk mengatasi persyaratan di atas kita memerlukan kumpulan modul nginx berikut:
ngx_http_image_filter_module β untuk mengubah ukuran gambar;ngx_http_proxy_module - untuk cache;ngx_http_secure_link_module β untuk melindungi dari spam;
Modul ngx_http_image_filter_module ΠΈ ngx_http_secure_link_module tidak diinstal secara default, sehingga harus ditentukan pada tahap konfigurasi instalasi nginx:
phoinix@phoinix-work:~/src/nginx-0.8.29
$ ./configure --with-http_secure_link_module --with-http_image_filter_module
konfigurasi nginx
Kami menambahkan yang baru ke konfigurasi host kami tempat dan parameter cache umum:
...
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;
}
...
}
...
Kami juga menambahkan host baru ke konfigurasi:
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; }
}
Hasilnya, gambar tambahan dapat diperoleh melalui tautan berikut:
proyeksaya.ru/preview/i [md5]/[jalur_ke_gambar]proyeksaya.ru/preview/c [md5]/[ukuran]/[path_to_image]proyeksaya.ru/preview/r [md5]/[ukuran]/[path_to_image]
* coba_files β peka terhadap spasi dan karakter Rusia, jadi saya harus membuat tongkat penyangga alias.
Gunakan dalam aplikasi web
Di tingkat aplikasi web, Anda dapat melakukan prosedur berikut (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'
);
Meskipun saya juga merekomendasikan menghitung ukurannya pratinjau.
Menyapu
Saat menghapus gambar asli, pratinjau, tentu saja, tidak akan dihapus dari cache sampai cache tidak valid, dan dalam kasus kami, pratinjau mungkin ada selama sehari setelah penghapusan, tetapi ini adalah waktu maksimum.
Sumber: www.habr.com