Piltide suuruse muutmine reaalajas

Peaaegu igas veebirakenduses, mis kasutab pilte, on vajadus luua nende piltide väiksemaid koopiaid, sageli mitmes erinevas formaadis.
Samuti tekitab natuke peavalu uute suuruste lisamine olemasolevasse rakendusse. Seega on ülesanne:

Ülesanne

Määratleme nõudmiste loetelu:

  • Luua lisapilte mis tahes formaatides jooksvalt, ilma et oleks vaja rakendusse täiendavaid funktsioone igal rakenduse olemasolu hetkel;
  • Lisapilte ei tohi luua iga päringu puhul;
  • Sulge võimalus luua lisapilte mittepaikapandud formaatides.

Selgitan viimast punkti, kuna see on veidi vastuolus esimese punktiga. Kui teeme piltide loomise avatud, on võimalus rünnakuks veebisaidile, tekitades suure hulga päringute seotakse pildi suuruse muutmiseks lõpmatu hulga formaatides, seega peab see haavatavus olema suletud.

Nginx'i paigalduse konfiguratsioon

Ülaltoodud nõudmiste täitmiseks vajame järgmist komplekti nginx'i mooduleid:

Moodulid ngx_http_image_filter_module ja ngx_http_secure_link_module ei paigaldata vaikimisi, seetõttu peavad need olema paigaldamise konfigureerimise etapis toodud nginx:

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

Nginx'i konfiguratsioon

Lisa meie hosti konfiguratsiooni uus asukoht ja üldised vahemälu parameetrid:

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

Lisa samuti uus host konfiguratsiooni:

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

Lõpuks saab lisapilte saada linkide kaudu:

* try_files — tundlik ruumide ja vene sümbolite suhtes, seetõttu tuli teha kihlvedu alias.

Kasutamine veebirakenduses

Veebirakenduse tasandil saab teha järgmist protseduuri (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'
                );

Kuigi soovitaksin veel arvutada suurused preview.

Kühveldused

Kui algne pilt eemaldatakse, ei eemaldata eelvaateid vahemälust, kuni vahemälu ei invalideerita, ja meie puhul võivad eelvaated eksisteerida kuni päeva pärast kustutamist, kuid see on maksimaalne aeg.

originaal

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster