Echtzeit-Bildgrößenänderung.

In fast jeder Webanwendung, die Bilder verwendet, besteht die Notwendigkeit, kleinere Versionen dieser Bilder zu erstellen, wobei oft mehrere zusätzliche Bildformate erforderlich sind.
Ebenfalls etwas problematisch ist das Hinzufügen neuer Größen zu einer bestehenden Anwendung. Daraus ergibt sich die Aufgabe:

Ziel

Lassen Sie uns eine Liste der Anforderungen festlegen:

  • Zusätzliche Bilder in beliebigen Formaten sollen dynamisch erstellt werden können, ohne dass während der gesamten Lebensdauer der Anwendung zusätzliche Funktionen in die Anwendung integriert werden müssen;
  • Zusätzliche Bilder dürfen nicht bei jeder Anfrage erstellt werden;
  • Die Möglichkeit zur Erstellung zusätzlicher Bilder in nicht festgelegten Formaten muss geschlossen werden.

Ich erkläre den letzten Punkt, da er dem ersten Punkt etwas widerspricht. Wenn wir die Erstellung beliebiger Bilder öffnen, besteht die Möglichkeit, die Website anzugreifen, indem eine große Menge an Anfragen zur Größenänderung von Bildern in unendlich vielen Formaten erstellt wird, weshalb diese Sicherheitsanfälligkeit geschlossen werden muss.

Nginx-Installationskonfiguration

Um die oben genannten Anforderungen zu erfüllen, benötigen wir das folgende Set an nginx-Modulen:

Module ngx_http_image_filter_module und ngx_http_secure_link_module sind standardmäßig nicht enthalten, daher müssen sie während der Konfiguration angegeben werden. nginx:

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

nginx-Konfiguration

Fügen Sie in die Konfiguration unseres Hosts einen neuen location und allgemeine Cache-Einstellungen hinzu:

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

Fügen Sie auch einen neuen Host zur Konfiguration hinzu:

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

Die zusätzlichen Bilder können schließlich über die Links abgerufen werden:

* try_files — ist empfindlich gegenüber Leerzeichen und russischen Zeichen, daher musste ein Workaround geschaffen werden alias.

Verwendung in der Webanwendung

Auf der Ebene der Webanwendung kann folgendes Verfahren (Perl) durchgeführt werden:

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'
                );

Obwohl ich empfehlen würde, die Größen zu berechnen Vorschau.

Rätsel

Wenn das Originalbild gelöscht wird, werden die Vorschaubilder selbstverständlich nicht aus dem Cache gelöscht, bis der Cache invalidiert wird. In unserem Fall können Previews bis zu einem Tag nach der Löschung existieren, aber das ist das Maximum.

Original

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster