Promenite veličinu slika u hodu

U gotovo svakoj web aplikaciji koja koristi slike postoji potreba za kreiranjem malih kopija ovih slika, a često postoji nekoliko formata za dodatne slike.
Dodavanje novih dimenzija postojećoj aplikaciji također uzrokuje neke glavobolje. Otuda i zadatak:

Cilj

Označimo listu zahtjeva:

  • Generirajte dodatne slike bilo kojeg formata u hodu bez uvođenja dodatne funkcionalnosti u aplikaciju u bilo kojem trenutku tijekom postojanja aplikacije;
  • Dodatne slike ne moraju biti generirane na svaki zahtjev;
  • Onemogućite mogućnost generiranja dodatnih slika nespecificiranih formata.

Objasniću poslednju tačku, jer je malo u suprotnosti sa prvom tačkom. Ako generisanje bilo koje slike učinimo otvorenim, postoji mogućnost napada na sajt generisanjem velikog broja zahteva za promenu veličine slike u beskonačan broj formata, pa ovu ranjivost treba zatvoriti.

nginx instalacijska konfiguracija

Za rješavanje gore navedenih zahtjeva potreban nam je sljedeći set nginx modula:

Moduli ngx_http_image_filter_module и ngx_http_secure_link_module nisu instalirani prema zadanim postavkama, tako da moraju biti specificirani u fazi konfiguracije instalacije nginx:

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

nginx konfiguracija

Dodamo novi u našu konfiguraciju hosta lokacija i opći parametri keša:

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

Također dodajemo novi host u konfiguraciju:

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

Kao rezultat toga, dodatne slike se mogu dobiti pomoću sljedećih veza:

* try_files — osetljiv na razmake i ruske znakove, pa sam morao da napravim štaku pseudonim.

Koristite u web aplikaciji

Na nivou web aplikacije možete uraditi sljedeću proceduru (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'
                );

Iako bih također preporučio izračunavanje veličina preview.

Rake

Prilikom brisanja originalne slike, pregledi, naravno, neće biti obrisani iz keša dok se keš ne poništi, au našem slučaju pregledi mogu postojati dan nakon brisanja, ali ovo je maksimalno vrijeme.

original

izvor: www.habr.com

Dodajte komentar