рдлреНрд▓рд╛рдп рд╡рд░ рдкреНрд░рддрд┐рдорд╛ рдЖрдХрд╛рд░ рдмрджрд▓рдгреЗ

рдкреНрд░рддрд┐рдорд╛ рд╡рд╛рдкрд░рдгрд╛рд░реНтАНрдпрд╛ рдЬрд╡рд│рдЬрд╡рд│ рдХреЛрдгрддреНрдпрд╛рд╣реА рд╡реЗрдм рдНрдкреНрд▓рд┐рдХреЗрд╢рдирдордзреНрдпреЗ, рдпрд╛ рдкреНрд░рддрд┐рдорд╛рдВрдЪреНрдпрд╛ рдЫреЛрдЯреНрдпрд╛ рдкреНрд░рддреА рддрдпрд╛рд░ рдХрд░рд╛рд╡реНрдпрд╛ рд▓рд╛рдЧрддрд╛рдд рдЖрдгрд┐ рдмрд░реНтАНрдпрд╛рдЪрджрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рддрд┐рдорд╛рдВрд╕рд╛рдареА рдЕрдиреЗрдХ рд╕реНрд╡рд░реВрдк рдЕрд╕рддрд╛рдд.
рд╡рд┐рджреНрдпрдорд╛рди рдНрдкреНрд▓рд┐рдХреЗрд╢рдирдордзреНрдпреЗ рдирд╡реАрди рдЖрдпрд╛рдо рдЬреЛрдбрд▓реНрдпрд╛рдиреЗ рдХрд╛рд╣реА рдбреЛрдХреЗрджреБрдЦреА рджреЗрдЦреАрд▓ рд╣реЛрддреЗ. рдореНрд╣рдгреВрди рдХрд╛рд░реНрдп:

рдЙрджреНрджрд┐рд╖реНрдЯ

рдЪрд▓рд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдВрдЪреА рдпрд╛рджреА рджрд░реНрд╢рд╡реВ:

  • рдНрдкреНрд▓рд┐рдХреЗрд╢рдирдЪреНрдпрд╛ рдЕрд╕реНрддрд┐рддреНрд╡рд╛рджрд░рдореНрдпрд╛рди рдХреЛрдгрддреНрдпрд╛рд╣реА рд╡реЗрд│реА рдНрдкреНрд▓рд┐рдХреЗрд╢рдирдордзреНрдпреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╕рд╛рджрд░ рди рдХрд░рддрд╛ рдлреНрд▓рд╛рдпрд╡рд░ рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕реНрд╡рд░реВрдкрд╛рдЪреНрдпрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рддрд┐рдорд╛ рддрдпрд╛рд░ рдХрд░рд╛;
  • рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдирдВрддреАрд╡рд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рддрд┐рдорд╛ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдирд╛рд╣реА;
  • рдЕрдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕реНрд╡рд░реВрдкрд╛рдВрдЪреНрдпрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рддрд┐рдорд╛ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рдгреНрдпрд╛рдЪреА рдХреНрд╖рдорддрд╛ рдЕрдХреНрд╖рдо рдХрд░рд╛.

рдореА рд╢реЗрд╡рдЯрдЪрд╛ рдореБрджреНрджрд╛ рд╕реНрдкрд╖реНрдЯ рдХрд░реЗрди, рдХрд╛рд░рдг рддреЛ рдкрд╣рд┐рд▓реНрдпрд╛ рдореБрджреНрджреНрдпрд╛рд╢реА рдереЛрдбрд╛рд╕рд╛ рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕ рдХрд░рддреЛ. рдЬрд░ рдЖрдореНрд╣реА рдХреЛрдгрддреНрдпрд╛рд╣реА рдкреНрд░рддрд┐рдорд╛рдВрдЪреА рдирд┐рд░реНрдорд┐рддреА рдЦреБрд▓реА рдХреЗрд▓реА, рддрд░ рдкреНрд░рддрд┐рдореЗрдЪрд╛ рдЖрдХрд╛рд░ рдЕрдорд░реНрдпрд╛рджрд┐рдд рд╕реНрд╡рд░реВрдкрд╛рдд рдмрджрд▓рдгреНрдпрд╛рд╕рд╛рдареА рдореЛрдареНрдпрд╛ рд╕рдВрдЦреНрдпреЗрдиреЗ рд╡рд┐рдирдВрддреНрдпрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реВрди рд╕рд╛рдЗрдЯрд╡рд░ рдЖрдХреНрд░рдордг рд╣реЛрдгреНрдпрд╛рдЪреА рд╢рдХреНрдпрддрд╛ рдЕрд╕рддреЗ, рдореНрд╣рдгреВрди рд╣реА рднреЗрджреНрдпрддрд╛ рдмрдВрдж рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.

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

рдкрд░рд┐рдгрд╛рдореА, рдЦрд╛рд▓реАрд▓ рджреБрд╡реЗ рд╡рд╛рдкрд░реВрди рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рддрд┐рдорд╛ рдорд┐рд│реВ рд╢рдХрддрд╛рдд:

* try_files тАФ рдореЛрдХрд│реА рдЬрд╛рдЧрд╛ рдЖрдгрд┐ рд░рд╢рд┐рдпрди рд╡рд░реНрдгрд╛рдВрдмрджреНрджрд▓ рд╕рдВрд╡реЗрджрдирд╢реАрд▓, рдореНрд╣рдгреВрди рдорд▓рд╛ рдПрдХ рдХреНрд░реЕрдЪ рдмрдирд╡рд╛рд╡реА рд▓рд╛рдЧрд▓реА рдКрд░реНрдл.

рд╡реЗрдм рдНрдкреНрд▓рд┐рдХреЗрд╢рдирдордзреНрдпреЗ рд╡рд╛рдкрд░рд╛

рд╡реЗрдм рдНрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрддрд░рд╛рд╡рд░, рддреБрдореНрд╣реА рдЦрд╛рд▓реАрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░реВ рд╢рдХрддрд╛ (рдкрд░реНрд▓):

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛