αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž‘αŸ†αž αŸ†αžšαžΌαž”αž—αžΆαž–αž—αŸ’αž›αžΆαž˜αŸ—

αž“αŸ…αž€αŸ’αž“αž»αž„αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž‚αŸαž αž‘αŸ†αž–αŸαžšαžŸαŸ’αž‘αžΎαžšαžαŸ‚αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αžŠαŸ‚αž›αž”αŸ’αžšαžΎαžšαžΌαž”αž—αžΆαž– αž…αžΆαŸ†αž”αžΆαž…αŸ‹αžαŸ’αžšαžΌαžœαž”αž„αŸ’αž€αžΎαžαž…αŸ’αž”αžΆαž”αŸ‹αž…αž˜αŸ’αž›αž„αžαžΌαž…αŸ—αž“αŸƒαžšαžΌαž”αž—αžΆαž–αž‘αžΆαŸ†αž„αž“αŸαŸ‡ αž αžΎαž™αž‡αžΆαžšαžΏαž™αŸ—αž˜αžΆαž“αž‘αž˜αŸ’αžšαž„αŸ‹αž‡αžΆαž…αŸ’αžšαžΎαž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžšαžΌαž”αž—αžΆαž–αž”αž“αŸ’αžαŸ‚αž˜αŸ”
αž€αžΆαžšαž”αž“αŸ’αžαŸ‚αž˜αžœαž·αž˜αžΆαžαŸ’αžšαžαŸ’αž˜αžΈαž‘αŸ…αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ‚αž›αž˜αžΆαž“αžŸαŸ’αžšαžΆαž”αŸ‹αž€αŸαž”αžŽαŸ’αžαžΆαž›αž±αŸ’αž™αžˆαžΊαž€αŸ’αž”αžΆαž›αžαŸ’αž›αŸ‡αžŠαŸ‚αžšαŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž—αžΆαžšαž€αž·αž…αŸ’αž…αŸ–

αž‚αŸ„αž›αž”αŸ†αžŽαž„

αž…αžΌαžšαžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αž”αž‰αŸ’αž‡αžΈαž“αŸƒαžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαŸ–

  • αž”αž„αŸ’αž€αžΎαžαžšαžΌαž”αž—αžΆαž–αž”αž“αŸ’αžαŸ‚αž˜αž“αŸƒαž‘αž˜αŸ’αžšαž„αŸ‹αžŽαžΆαž˜αž½αž™αž—αŸ’αž›αžΆαž˜αŸ—αžŠαŸ„αž™αž˜αž·αž“αž”αž„αŸ’αž αžΆαž‰αž˜αž»αžαž„αžΆαžšαž”αž“αŸ’αžαŸ‚αž˜αž‘αŸ…αž€αŸ’αž“αž»αž„αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž‚αŸ’αžšαž”αŸ‹αž–αŸαž› αž€αŸ†αž‘αž»αž„αž–αŸαž›αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž˜αžΆαž“αŸ”
  • αžšαžΌαž”αž—αžΆαž–αž”αž“αŸ’αžαŸ‚αž˜αž˜αž·αž“αž…αžΆαŸ†αž”αžΆαž…αŸ‹αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αž„αŸ’αž€αžΎαžαž“αŸ…αž›αžΎαžšαžΆαž›αŸ‹αž€αžΆαžšαžŸαŸ’αž“αžΎαžŸαž»αŸ†αž‘αŸαŸ”
  • αž”αž·αž‘αžŸαž˜αžαŸ’αžαž—αžΆαž–αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžšαžΌαž”αž—αžΆαž–αž”αž“αŸ’αžαŸ‚αž˜αž“αŸƒαž‘αž˜αŸ’αžšαž„αŸ‹αžŠαŸ‚αž›αž˜αž·αž“αž”αžΆαž“αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αŸ”

αžαŸ’αž‰αž»αŸ†β€‹αž“αžΉαž„β€‹αž–αž“αŸ’αž™αž›αŸ‹β€‹αž…αŸ†αžŽαž»αž…β€‹αž…αž»αž„β€‹αž€αŸ’αžšαŸ„αž™ αž–αŸ’αžšαŸ„αŸ‡β€‹αžœαžΆβ€‹αž•αŸ’αž‘αž»αž™β€‹αž“αžΉαž„β€‹αž…αŸ†αžŽαž»αž…β€‹αžŠαŸ†αž”αžΌαž„β€‹αž”αž“αŸ’αžαž·αž…αŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž™αžΎαž„αž”αž„αŸ’αž€αžΎαžαžšαžΌαž”αž—αžΆαž–αžŽαžΆαž˜αž½αž™αž”αžΎαž€αž…αŸ†αž  αž“αŸ„αŸ‡αž˜αžΆαž“αž›αž‘αŸ’αž’αž—αžΆαž–αž“αŸƒαž€αžΆαžšαžœαžΆαž™αž”αŸ’αžšαž αžΆαžšαž“αŸ…αž›αžΎαž‚αŸαž αž‘αŸ†αž–αŸαžšαžŠαŸ„αž™αž”αž„αŸ’αž€αžΎαžαžŸαŸ†αžŽαžΎαž˜αž½αž™αž…αŸ†αž“αž½αž“αž’αŸ†αžŠαžΎαž˜αŸ’αž”αžΈαž”αŸ’αžαžΌαžšαž‘αŸ†αž αŸ†αžšαžΌαž”αž—αžΆαž–αž‘αŸ…αž‡αžΆαž‘αž˜αŸ’αžšαž„αŸ‹αž‚αŸ’αž˜αžΆαž“αž€αŸ†αžŽαžαŸ‹ αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž—αžΆαž–αž„αžΆαž™αžšαž„αž‚αŸ’αžšαŸ„αŸ‡αž“αŸαŸ‡αž…αžΆαŸ†αž”αžΆαž…αŸ‹αžαŸ’αžšαžΌαžœαž”αž·αž‘αŸ”

αž€αžΆαžšαž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž€αžΆαžšαžŠαŸ†αž‘αžΎαž„ 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;
        }
...
    }
...

αž™αžΎαž„αž€αŸαž”αž“αŸ’αžαŸ‚αž˜αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αžαŸ’αž˜αžΈαž‘αŸ… configαŸ–

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

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹