ΠŸΡ€Π΅ΠΎΡ€Π°Π·ΠΌΠ΅Ρ€ΡΠ²Π°Π½Π΅ Π½Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π² Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅

Π’ ΠΏΠΎΡ‡Ρ‚ΠΈ всяко ΡƒΠ΅Π± ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° изобраТСния, ΠΈΠΌΠ° Π½ΡƒΠΆΠ΄Π° ΠΎΡ‚ създаванС Π½Π° ΠΌΠ°Π»ΠΊΠΈ копия Π½Π° Ρ‚Π΅Π·ΠΈ изобраТСния ΠΈ чСсто ΠΈΠΌΠ° няколко Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π·Π° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ изобраТСния.
ДобавянСто Π½Π° Π½ΠΎΠ²ΠΈ измСрСния към ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡŠΡ‰ΠΎ причинява някои главоболия. ΠžΡ‚Ρ‚ΡƒΠΊ ΠΈ Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π°:

Π—Π°Π΄Π°Ρ‡Π°

НСка ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡ΠΈΠΌ списъка с изисквания:

  • Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΠΉΡ‚Π΅ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ изобраТСния ΠΎΡ‚ всякакъв Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π² Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅, Π±Π΅Π· Π΄Π° Π²ΡŠΠ²Π΅ΠΆΠ΄Π°Ρ‚Π΅ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½Π° функционалност Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΏΠΎ всяко Π²Ρ€Π΅ΠΌΠ΅ ΠΎΡ‚ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ;
  • НС Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ‚ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ изобраТСния ΠΏΡ€ΠΈ всяка заявка;
  • Π”Π΅Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°ΠΉΡ‚Π΅ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚Ρ‚Π° Π·Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ изобраТСния с Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈ.

Π©Π΅ обясня послСдната Ρ‚ΠΎΡ‡ΠΊΠ°, Π·Π°Ρ‰ΠΎΡ‚ΠΎ тя Π»Π΅ΠΊΠΎ ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈ Π½Π° ΠΏΡŠΡ€Π²Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ°. Ако Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° всякакви изобраТСния, Ρ‚ΠΎΠ³Π°Π²Π° ΠΈΠΌΠ° Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° Π°Ρ‚Π°ΠΊΠ° Π½Π° сайта Ρ‡Ρ€Π΅Π· Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° голям Π±Ρ€ΠΎΠΉ заявки Π·Π° прСоразмСряванС Π½Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π² Π±Π΅Π·ΠΊΡ€Π°Π΅Π½ Π±Ρ€ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈ, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‚Π°Π·ΠΈ уязвимост трябва Π΄Π° бъдС Π·Π°Ρ‚Π²ΠΎΡ€Π΅Π½Π°.

конфигурация Π·Π° инсталиранС Π½Π° nginx

Π—Π° Π΄Π° ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π½Π° Π³ΠΎΡ€Π½ΠΈΡ‚Π΅ изисквания, сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ ΠΎΡ‚ слСдния Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ nginx ΠΌΠΎΠ΄ΡƒΠ»ΠΈ:

ΠœΠΎΠ΄ΡƒΠ»ΠΈ 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

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€