Π ΠΏΠΎΡΡΠΈ Π²ΡΡΠΊΠΎ ΡΠ΅Π± ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΈΠΌΠ° Π½ΡΠΆΠ΄Π° ΠΎΡ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΌΠ°Π»ΠΊΠΈ ΠΊΠΎΠΏΠΈΡ Π½Π° ΡΠ΅Π·ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΠ΅ΡΡΠΎ ΠΈΠΌΠ° Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΠΎΡΠΌΠ°ΡΠ° Π·Π° Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ.
ΠΠΎΠ±Π°Π²ΡΠ½Π΅ΡΠΎ Π½Π° Π½ΠΎΠ²ΠΈ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΠΊΡΠΌ ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΡΠΎ ΠΏΡΠΈΡΠΈΠ½ΡΠ²Π° Π½ΡΠΊΠΎΠΈ Π³Π»Π°Π²ΠΎΠ±ΠΎΠ»ΠΈΡ. ΠΡΡΡΠΊ ΠΈ Π·Π°Π΄Π°ΡΠ°ΡΠ°:
ΠΠ°Π΄Π°ΡΠ°
ΠΠ΅ΠΊΠ° ΠΎΠ±ΠΎΠ·Π½Π°ΡΠΈΠΌ ΡΠΏΠΈΡΡΠΊΠ° Ρ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½ΠΈΡ:
- ΠΠ΅Π½Π΅ΡΠΈΡΠ°ΠΉΡΠ΅ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΎΡ Π²ΡΡΠΊΠ°ΠΊΡΠ² ΡΠΎΡΠΌΠ°Ρ Π² Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅, Π±Π΅Π· Π΄Π° Π²ΡΠ²Π΅ΠΆΠ΄Π°ΡΠ΅ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΏΠΎ Π²ΡΡΠΊΠΎ Π²ΡΠ΅ΠΌΠ΅ ΠΎΡ ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ;
- ΠΠ΅ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ°Ρ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΏΡΠΈ Π²ΡΡΠΊΠ° Π·Π°ΡΠ²ΠΊΠ°;
- ΠΠ΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΉΡΠ΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π·Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Ρ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ ΡΠΎΡΠΌΠ°ΡΠΈ.
Π©Π΅ ΠΎΠ±ΡΡΠ½Ρ ΠΏΠΎΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΠΎΡΠΊΠ°, Π·Π°ΡΠΎΡΠΎ ΡΡ Π»Π΅ΠΊΠΎ ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈ Π½Π° ΠΏΡΡΠ²Π°ΡΠ° ΡΠΎΡΠΊΠ°. ΠΠΊΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ ΠΎΡΠ²ΠΎΡΠ΅Π½ΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° Π²ΡΡΠΊΠ°ΠΊΠ²ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΡΠΎΠ³Π°Π²Π° ΠΈΠΌΠ° Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ Π·Π° Π°ΡΠ°ΠΊΠ° Π½Π° ΡΠ°ΠΉΡΠ° ΡΡΠ΅Π· Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° Π³ΠΎΠ»ΡΠΌ Π±ΡΠΎΠΉ Π·Π°ΡΠ²ΠΊΠΈ Π·Π° ΠΏΡΠ΅ΠΎΡΠ°Π·ΠΌΠ΅ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π² Π±Π΅Π·ΠΊΡΠ°Π΅Π½ Π±ΡΠΎΠΉ ΡΠΎΡΠΌΠ°ΡΠΈ, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΠ°Π·ΠΈ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ Π·Π°ΡΠ²ΠΎΡΠ΅Π½Π°.
ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π·Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° nginx
ΠΠ° Π΄Π° ΠΎΡΠ³ΠΎΠ²ΠΎΡΠΈΠΌ Π½Π° Π³ΠΎΡΠ½ΠΈΡΠ΅ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½ΠΈΡ, ΡΠ΅ Π½ΡΠΆΠ΄Π°Π΅ΠΌ ΠΎΡ ΡΠ»Π΅Π΄Π½ΠΈΡ Π½Π°Π±ΠΎΡ ΠΎΡ nginx ΠΌΠΎΠ΄ΡΠ»ΠΈ:
ngx_http_image_filter_module β Π·Π° ΠΏΡΠ΅ΠΎΡΠ°Π·ΠΌΠ΅ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ;ngx_http_ΠΏΡΠΎΠΊΡΠΈ_ΠΌΠΎΠ΄ΡΠ» - Π·Π° ΠΊΠ΅ΡΠΈΡΠ°Π½Π΅;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/preview/r [md5]/[ΡΠ°Π·ΠΌΠ΅Ρ]/[ΠΏΡΡ_ΠΊΡΠΌ_ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅]
* try_files β ΡΡΠ²ΡΡΠ²ΠΈΡΠ΅Π»Π΅Π½ ΠΊΡΠΌ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»ΠΈ ΠΈ ΡΡΡΠΊΠΈ Π·Π½Π°ΡΠΈ, ΡΠ°ΠΊΠ° ΡΠ΅ ΡΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° Π½Π°ΠΏΡΠ°Π²Ρ ΠΏΠ°ΡΠ΅ΡΠΈΡΠ° ΠΏΡΠ΅Π²Π΄ΠΎΠ½ΠΈΠΌ.
ΠΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡΠ΅ Π² ΡΠ΅Π± ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
ΠΠ° Π½ΠΈΠ²ΠΎ ΡΠ΅Π± ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΡΠ»Π΅Π΄Π½Π°ΡΠ° ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ° (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