Onmiddellijk het formaat van afbeeldingen aanpassen

In vrijwel elke webtoepassing die afbeeldingen gebruikt, is het nodig om kleine kopieën van deze afbeeldingen te maken, en vaak zijn er verschillende formaten voor extra afbeeldingen.
Het toevoegen van nieuwe dimensies aan een bestaande applicatie levert ook wat kopzorgen op. Vandaar de opgave:

Taak

Laten we de lijst met vereisten aanduiden:

  • Genereer direct extra afbeeldingen van elk formaat zonder op enig moment tijdens het bestaan ​​van de applicatie extra functionaliteit in de applicatie te introduceren;
  • Er hoeven niet bij elke aanvraag extra afbeeldingen te worden gegenereerd;
  • Schakel de mogelijkheid uit om extra afbeeldingen van niet-gespecificeerde formaten te genereren.

Ik zal het laatste punt toelichten, omdat het enigszins in tegenspraak is met het eerste punt. Als we het genereren van afbeeldingen open maken, bestaat de mogelijkheid van een aanval op de site door een groot aantal verzoeken te genereren om het formaat van de afbeelding in een oneindig aantal formaten te wijzigen. Deze kwetsbaarheid moet dus worden gesloten.

nginx-installatieconfiguratie

Om aan de bovenstaande vereisten te voldoen, hebben we de volgende set nginx-modules nodig:

modules ngx_http_image_filter_module и ngx_http_secure_link_module worden niet standaard geïnstalleerd, dus moeten ze worden opgegeven tijdens de installatieconfiguratiefase nginx:

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

nginx-configuratie

We voegen een nieuwe toe aan onze hostconfiguratie plaats en algemene cacheparameters:

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

We voegen ook een nieuwe host toe aan de configuratie:

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

Als gevolg hiervan kunnen aanvullende afbeeldingen worden verkregen via de volgende links:

* probeer_bestanden — gevoelig voor spaties en Russische karakters, dus ik moest er een kruk mee maken alias.

Gebruik in een webapplicatie

Op webapplicatieniveau kunt u de volgende procedure uitvoeren (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'
                );

Al zou ik ook aanraden om de maten te berekenen Preview.

hark

Bij het verwijderen van de originele afbeelding worden de voorbeelden uiteraard niet uit de cache verwijderd totdat de cache ongeldig is gemaakt, en in ons geval kunnen de voorbeelden nog een dag na het verwijderen bestaan, maar dit is de maximale tijd.

оригинал

Bron: www.habr.com

Voeg een reactie