ΠΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π² Π»ΡΠ±ΠΎΠΌ Π²Π΅Π±-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ΅ΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎΡΡΡ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ ΡΠΌΠ΅Π½ΡΡΠ΅Π½Π½ΡΠ΅ ΠΊΠΎΠΏΠΈΠΈ ΡΡΠΈΡ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, ΠΏΡΠΈΡΠ΅ΠΌ Π·Π°ΡΠ°ΡΡΡΡ, ΡΠΎΡΠΌΠ°ΡΠΎΠ² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ
ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ.
Π’Π°ΠΊ ΠΆΠ΅ Π²ΡΠ·ΡΠ²Π°Π΅Ρ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ Π³ΠΎΠ»ΠΎΠ²Π½ΡΡ Π±ΠΎΠ»Ρ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΡΡ
ΡΠ°Π·ΠΌΠ΅ΡΠΎΠ² Π½Π° ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ. ΠΡΡΡΠ΄Π° Π·Π°Π΄Π°ΡΠ°:
ΠΠ°Π΄Π°ΡΠ°
ΠΠ±ΠΎΠ·Π½Π°ΡΠΈΠΌ ΡΠΏΠΈΡΠΎΠΊ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ:
- Π€ΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π»ΡΠ±ΡΡ ΡΠΎΡΠΌΠ°ΡΠΎΠ² Π½Π° Π»Π΅ΡΡ Π±Π΅Π· Π²Π½Π΅ΡΠ΅Π½ΠΈΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π° Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Π»ΡΠ±ΠΎΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ;
- ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΏΡΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π·Π°ΠΏΡΠΎΡΠ΅;
- ΠΠ°ΠΊΡΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π½Π΅ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΡΡ ΡΠΎΡΠΌΠ°ΡΠΎΠ².
ΠΠ±ΡΡΡΠ½Ρ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΠΏΡΠ½ΠΊΡ, ΠΈΠ±ΠΎ ΠΎΠ½ ΡΠ»Π΅Π³ΠΊΠ° ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΡ ΠΏΠ΅ΡΠ²ΠΎΠΌΡ ΠΏΡΠ½ΠΊΡΡ. ΠΡΠ»ΠΈ ΠΌΡ ΡΠ΄Π΅Π»Π°Π΅ΠΌ ΠΎΡΠΊΡΡΡΡΠΌ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π»ΡΠ±ΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, ΡΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π°ΡΠ°ΠΊΠΈ Π½Π° ΡΠ°ΠΉΡ ΠΏΡΡΠ΅ΠΌ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π±ΠΎΠ»ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ΅ΡΠ°ΠΉΠ· ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΎΡΠΌΠ°ΡΠΎΠ², ΠΏΠΎΡΡΠΎΠΌΡ ΡΡΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π°ΠΊΡΡΡΡ.
ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ nginx
ΠΠ»Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π²ΡΡΠ΅ΡΠΊΠ°Π·Π°Π½Π½ΡΡ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ Π½Π°ΠΌ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ Π½Π°Π±ΠΎΡ ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ nginx:
ngx_http_image_filter_module β Π΄Π»Ρ ΡΠ΅ΡΠ°ΠΉΠ·Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ;ngx_http_proxy_module β Π΄Π»Ρ ΠΊΠ΅ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ;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
Π ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π½Π°ΡΠ΅Π³ΠΎ Ρ ΠΎΡΡΠ° Π΄ΠΎΠ±Π°Π»ΡΠ΅ΠΌ Π½ΠΎΠ²ΡΠΉ location ΠΈ ΠΎΠ±ΡΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΊΠ΅ΡΠ°:
...
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]/[path_to_image]myproject.ru/preview/c [md5]/[size]/[path_to_image]myproject.ru/preview/r [md5]/[size]/[path_to_image]
* try_files β ΡΡΠ²ΡΡΠ²ΠΈΡΠ΅Π»Π΅Π½ ΠΊ ΠΏΡΠΎΠ±Π΅Π»Π°ΠΌ ΠΈ ΡΡΡΡΠΊΠΈΠΌ ΡΠΈΠΌΠ²ΠΎΠ»Π°ΠΌ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΡΠΈΡΠ»ΠΎΡΡ ΡΠ΄Π΅Π»Π°ΡΡ ΠΊΠΎΡΡΡΠ»Ρ Ρ alias.
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Π²Π΅Π±-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ
ΠΠ° ΡΡΠΎΠ²Π½Π΅ Π²Π΅Π±-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΡ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ (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'
);
Π₯ΠΎΡΡ Ρ Π±Ρ Π΅ΡΠ΅ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π» ΡΠ°ΡΡΡΠΈΡΡΠ²Π°ΡΡ ΡΠ°Π·ΠΌΠ΅ΡΡ preview.
ΠΡΠ°Π±Π»ΠΈ
ΠΡΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΠΈ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΏΡΠ΅Π²ΡΡ, Π΅ΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎ, ΡΠ΄Π°Π»ΡΡΡΡ ΠΈΠ· ΠΊΠ΅ΡΠ° Π½Π΅ Π±ΡΠ΄ΡΡ ΠΏΠΎΠΊΠ° ΠΊΠ΅Ρ Π½Π΅ ΠΈΠ½Π²Π°Π»ΠΈΠ΄ΠΈΡΡΠ΅ΡΡΡ, Π° Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠ΅Π²ΡΡ ΠΌΠΎΠ³ΡΡ ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°ΡΡ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΡΡΡΠΎΠΊ ΠΏΠΎΡΠ»Π΅ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ, Π½ΠΎ ΡΡΠΎ ΠΌΠ°ΠΊΡΠΈΠΌΡΠΌ ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com