ΠŸΡ€ΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°Ρ‚Π° Π½Π° сликата Π²ΠΎ Π»Π΅Ρ‚

РСчиси Π²ΠΎ сСкоја Π²Π΅Π±-Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° која користи слики, ΠΈΠΌΠ° ΠΏΠΎΡ‚Ρ€Π΅Π±Π° Π΄Π° сС создаваат ΠΌΠ°Π»ΠΈ ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ΄ ΠΎΠ²ΠΈΠ΅ слики, Π° чСсто ΠΈΠΌΠ° ΠΈ Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈ Π·Π° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ слики.
Π”ΠΎΠ΄Π°Π²Π°ΡšΠ΅Ρ‚ΠΎ Π½ΠΎΠ²ΠΈ Π΄ΠΈΠΌΠ΅Π½Π·ΠΈΠΈ Π½Π° постоСчка Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°, исто Ρ‚Π°ΠΊΠ°, ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΡƒΠ²Π° Π½Π΅ΠΊΠΎΠΈ Π³Π»Π°Π²ΠΎΠ±ΠΎΠ»ΠΊΠΈ. ΠžΡ‚Ρ‚ΡƒΠΊΠ° ΠΈ Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π°:

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

Π”Π° ја ΠΎΠ·Π½Π°Ρ‡ΠΈΠΌΠ΅ листата Π½Π° Π±Π°Ρ€Π°ΡšΠ°:

  • Π“Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ˜Ρ‚Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ слики ΠΎΠ΄ ΠΊΠ°ΠΊΠ²ΠΈ Π±ΠΈΠ»ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈ Π²ΠΎ Π»Π΅Ρ‚ Π±Π΅Π· Π²ΠΎΠ²Π΅Π΄ΡƒΠ²Π°ΡšΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π½Π° функционалност Π²ΠΎ Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°Ρ‚Π° Π²ΠΎ сСкоС Π²Ρ€Π΅ΠΌΠ΅ ΠΎΠ΄ ΠΏΠΎΡΡ‚ΠΎΠ΅ΡšΠ΅Ρ‚ΠΎ Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°Ρ‚Π°;
  • Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ слики Π½Π΅ Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π°Ρ‚ Π½Π° сСкоС Π±Π°Ρ€Π°ΡšΠ΅;
  • ΠžΠ½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ја моТноста Π·Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ слики ΠΎΠ΄ Π½Π΅ΠΎΠ΄Ρ€Π΅Π΄Π΅Π½ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈ.

ЌС ја објаснам послСдната Ρ‚ΠΎΡ‡ΠΊΠ°, бидСјќи Ρ‚Π°Π° ΠΌΠ°Π»ΠΊΡƒ Π΅ Π²ΠΎ спротивност со ΠΏΡ€Π²Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ°. Ако Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΊΠ°ΠΊΠ²ΠΈ Π±ΠΈΠ»ΠΎ слики ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ΠΈ, Ρ‚ΠΎΠ³Π°Ρˆ постои моТност Π·Π° Π½Π°ΠΏΠ°Π΄ Π½Π° страницата со Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ Π½Π° Π³ΠΎΠ»Π΅ΠΌ Π±Ρ€ΠΎΡ˜ Π±Π°Ρ€Π°ΡšΠ° Π·Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°Ρ‚Π° Π½Π° сликата Π²ΠΎ бСсконСчСн Π±Ρ€ΠΎΡ˜ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈ, Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ ΠΎΠ²Π°Π° ранливост Ρ‚Ρ€Π΅Π±Π° Π΄Π° сС Π·Π°Ρ‚Π²ΠΎΡ€ΠΈ.

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; }
}

Како Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° Ρ‚ΠΎΠ°, Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ слики ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π΄ΠΎΠ±ΠΈΡ˜Π°Ρ‚ со помош Π½Π° слСднитС врски:

* 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

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€