Π Π΅ΡΠΈΡΠΈ Π²ΠΎ ΡΠ΅ΠΊΠΎΡΠ° Π²Π΅Π±-Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ° ΠΊΠΎΡΠ° ΠΊΠΎΡΠΈΡΡΠΈ ΡΠ»ΠΈΠΊΠΈ, ΠΈΠΌΠ° ΠΏΠΎΡΡΠ΅Π±Π° Π΄Π° ΡΠ΅ ΡΠΎΠ·Π΄Π°Π²Π°Π°Ρ ΠΌΠ°Π»ΠΈ ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ΄ ΠΎΠ²ΠΈΠ΅ ΡΠ»ΠΈΠΊΠΈ, Π° ΡΠ΅ΡΡΠΎ ΠΈΠΌΠ° ΠΈ Π½Π΅ΠΊΠΎΠ»ΠΊΡ ΡΠΎΡΠΌΠ°ΡΠΈ Π·Π° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΠ»ΠΈΠΊΠΈ.
ΠΠΎΠ΄Π°Π²Π°ΡΠ΅ΡΠΎ Π½ΠΎΠ²ΠΈ Π΄ΠΈΠΌΠ΅Π½Π·ΠΈΠΈ Π½Π° ΠΏΠΎΡΡΠΎΠ΅ΡΠΊΠ° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ°, ΠΈΡΡΠΎ ΡΠ°ΠΊΠ°, ΠΏΡΠ΅Π΄ΠΈΠ·Π²ΠΈΠΊΡΠ²Π° Π½Π΅ΠΊΠΎΠΈ Π³Π»Π°Π²ΠΎΠ±ΠΎΠ»ΠΊΠΈ. ΠΡΡΡΠΊΠ° ΠΈ Π·Π°Π΄Π°ΡΠ°ΡΠ°:
ΠΠ°Π΄Π°ΡΠ°
ΠΠ° ΡΠ° ΠΎΠ·Π½Π°ΡΠΈΠΌΠ΅ Π»ΠΈΡΡΠ°ΡΠ° Π½Π° Π±Π°ΡΠ°ΡΠ°:
- ΠΠ΅Π½Π΅ΡΠΈΡΠ°ΡΡΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΠ»ΠΈΠΊΠΈ ΠΎΠ΄ ΠΊΠ°ΠΊΠ²ΠΈ Π±ΠΈΠ»ΠΎ ΡΠΎΡΠΌΠ°ΡΠΈ Π²ΠΎ Π»Π΅Ρ Π±Π΅Π· Π²ΠΎΠ²Π΅Π΄ΡΠ²Π°ΡΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Π½Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡ Π²ΠΎ Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ°ΡΠ° Π²ΠΎ ΡΠ΅ΠΊΠΎΠ΅ Π²ΡΠ΅ΠΌΠ΅ ΠΎΠ΄ ΠΏΠΎΡΡΠΎΠ΅ΡΠ΅ΡΠΎ Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°ΡΠΈΡΠ°ΡΠ°;
- ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΠ»ΠΈΠΊΠΈ Π½Π΅ ΡΡΠ΅Π±Π° Π΄Π° ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ°Π°Ρ Π½Π° ΡΠ΅ΠΊΠΎΠ΅ Π±Π°ΡΠ°ΡΠ΅;
- ΠΠ½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ° ΠΌΠΎΠΆΠ½ΠΎΡΡΠ° Π·Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°ΡΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΠ»ΠΈΠΊΠΈ ΠΎΠ΄ Π½Π΅ΠΎΠ΄ΡΠ΅Π΄Π΅Π½ΠΈ ΡΠΎΡΠΌΠ°ΡΠΈ.
ΠΠ΅ ΡΠ° ΠΎΠ±ΡΠ°ΡΠ½Π°ΠΌ ΠΏΠΎΡΠ»Π΅Π΄Π½Π°ΡΠ° ΡΠΎΡΠΊΠ°, Π±ΠΈΠ΄Π΅ΡΡΠΈ ΡΠ°Π° ΠΌΠ°Π»ΠΊΡ Π΅ Π²ΠΎ ΡΠΏΡΠΎΡΠΈΠ²Π½ΠΎΡΡ ΡΠΎ ΠΏΡΠ²Π°ΡΠ° ΡΠΎΡΠΊΠ°. ΠΠΊΠΎ Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΠΌΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ°ΡΠ΅ΡΠΎ Π½Π° ΠΊΠ°ΠΊΠ²ΠΈ Π±ΠΈΠ»ΠΎ ΡΠ»ΠΈΠΊΠΈ ΠΎΡΠ²ΠΎΡΠ΅Π½ΠΈ, ΡΠΎΠ³Π°Ρ ΠΏΠΎΡΡΠΎΠΈ ΠΌΠΎΠΆΠ½ΠΎΡΡ Π·Π° Π½Π°ΠΏΠ°Π΄ Π½Π° ΡΡΡΠ°Π½ΠΈΡΠ°ΡΠ° ΡΠΎ Π³Π΅Π½Π΅ΡΠΈΡΠ°ΡΠ΅ Π½Π° Π³ΠΎΠ»Π΅ΠΌ Π±ΡΠΎΡ Π±Π°ΡΠ°ΡΠ° Π·Π° ΠΏΡΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°ΡΠ° Π½Π° ΡΠ»ΠΈΠΊΠ°ΡΠ° Π²ΠΎ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ΅Π½ Π±ΡΠΎΡ ΡΠΎΡΠΌΠ°ΡΠΈ, ΡΠ°ΠΊΠ° ΡΡΠΎ ΠΎΠ²Π°Π° ΡΠ°Π½Π»ΠΈΠ²ΠΎΡΡ ΡΡΠ΅Π±Π° Π΄Π° ΡΠ΅ Π·Π°ΡΠ²ΠΎΡΠΈ.
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 ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΠ°
ΠΠΎΠ΄Π°Π²Π°ΠΌΠ΅ Π½ΠΎΠ² Π²ΠΎ Π½Π°ΡΠ°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΠ° Π½Π° Π΄ΠΎΠΌΠ°ΡΠΈΠ½ΠΎΡ ΠΠΎΠΊΠ°ΡΠΈΡΠ° ΠΈ ΠΎΠΏΡΡΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ Π½Π° ΠΊΠ΅ΡΠΎΡ:
...
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]/[Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°]/[ΠΏΠ°Ρ_Π΄ΠΎ_ΡΠ»ΠΈΠΊΠ°]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