Ndryshimi i madhësisë së imazheve në fluturim

Pothuajse në çdo aplikacion ueb që përdor imazhe, ekziston nevoja për të krijuar kopje të vogla të këtyre imazheve dhe shpesh ka disa formate për imazhe shtesë.
Shtimi i dimensioneve të reja në një aplikacion ekzistues gjithashtu shkakton disa dhimbje koke. Prandaj detyra:

Detyrë

Le të shënojmë listën e kërkesave:

  • Gjeneroni imazhe shtesë të çdo formati në fluturim pa futur funksione shtesë në aplikacion në çdo kohë gjatë ekzistencës së aplikacionit;
  • Nuk ka nevojë të krijohen imazhe shtesë në çdo kërkesë;
  • Çaktivizoni aftësinë për të gjeneruar imazhe shtesë të formateve të paspecifikuara.

Unë do të shpjegoj pikën e fundit, sepse ajo bie pak në kundërshtim me pikën e parë. Nëse e bëjmë të hapur gjenerimin e ndonjë imazhi, atëherë ekziston mundësia e një sulmi në sajt duke gjeneruar një numër të madh kërkesash për të ndryshuar madhësinë e imazhit në një numër të pafund formatesh, kështu që kjo dobësi duhet të mbyllet.

Konfigurimi i instalimit nginx

Për të zgjidhur kërkesat e mësipërme, ne kemi nevojë për grupin e mëposhtëm të moduleve nginx:

Модули ngx_http_image_filter_module и ngx_http_secure_link_module nuk janë instaluar si parazgjedhje, kështu që ato duhet të specifikohen në fazën e konfigurimit të instalimit nginx:

phoinix@phoinix-work:~/src/nginx-0.8.29
$ ./configure --with-http_secure_link_module --with-http_image_filter_module

konfigurimin nginx

Ne shtojmë një të re në konfigurimin tonë të hostit vend dhe parametrat e përgjithshëm të cache:

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

Ne gjithashtu shtojmë një host të ri në konfigurim:

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

Si rezultat, imazhe shtesë mund të merren duke përdorur lidhjet e mëposhtme:

* provoni_skedarët — i ndjeshëm ndaj hapësirave dhe karaktereve ruse, ndaj më duhej të bëja një patericë me të pseudonim.

Përdorni në një aplikacion ueb

Në nivelin e aplikacionit në ueb, mund të bëni procedurën e mëposhtme (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'
                );

Edhe pse unë do të rekomandoja gjithashtu llogaritjen e madhësive preview.

grabujë

Kur fshini imazhin origjinal, pamjet paraprake, natyrisht, nuk do të fshihen nga cache derisa cache të zhvlerësohet, dhe në rastin tonë, pamjet paraprake mund të ekzistojnë për një ditë pas fshirjes, por kjo është koha maksimale.

origjinale

Burimi: www.habr.com

Shto një koment