Zmeňte veľkosť obrázkov za behu

Takmer v každej webovej aplikácii, ktorá používa obrázky, je potrebné vytvárať malé kópie týchto obrázkov a často existuje niekoľko formátov pre ďalšie obrázky.
Pridávanie nových dimenzií do existujúcej aplikácie tiež spôsobuje bolesti hlavy. Preto úloha:

Úloha

Označme zoznam požiadaviek:

  • generovať ďalšie obrázky akéhokoľvek formátu za behu bez zavádzania dodatočných funkcií do aplikácie kedykoľvek počas existencie aplikácie;
  • Pri každej požiadavke nie je potrebné generovať ďalšie obrázky;
  • Zakázať možnosť generovania ďalších obrázkov nešpecifikovaných formátov.

Vysvetlím posledný bod, pretože mierne odporuje prvému bodu. Ak sprístupníme generovanie akýchkoľvek obrázkov, potom existuje možnosť útoku na stránku generovaním veľkého počtu požiadaviek na zmenu veľkosti obrázka do nekonečného množstva formátov, takže túto zraniteľnosť je potrebné uzavrieť.

konfigurácia inštalácie nginx

Na vyriešenie vyššie uvedených požiadaviek potrebujeme nasledujúcu sadu modulov nginx:

moduly ngx_http_image_filter_module и ngx_http_secure_link_module nie sú predvolene nainštalované, takže musia byť špecifikované vo fáze konfigurácie inštalácie nginx:

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

konfigurácia nginx

Do našej konfigurácie hostiteľa pridáme nový umiestnenie a všeobecné parametre vyrovnávacej pamäte:

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

Do konfigurácie tiež pridáme nového hostiteľa:

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

V dôsledku toho je možné získať ďalšie obrázky pomocou nasledujúcich odkazov:

* try_files — citlivý na medzery a ruské znaky, takže som si musel urobiť barličku prezývka.

Použitie vo webovej aplikácii

Na úrovni webovej aplikácie môžete vykonať nasledujúci postup (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'
                );

Aj keď by som tiež odporučil vypočítať veľkosti Náhľad.

hrable

Pri odstraňovaní pôvodného obrázka sa náhľady, prirodzene, z vyrovnávacej pamäte nevymažú, kým nebude vyrovnávacia pamäť zneplatnená, a v našom prípade môžu náhľady existovať aj deň po vymazaní, ale toto je maximálny čas.

originálu

Zdroj: hab.com

Pridať komentár