Mainiet attēlu izmērus uzreiz

Gandrīz jebkurā tīmekļa lietojumprogrammā, kas izmanto attēlus, ir nepieciešams izveidot nelielas šo attēlu kopijas, un bieži vien ir vairāki papildu attēlu formāti.
Jaunu dimensiju pievienošana esošai lietojumprogrammai arī rada zināmas galvassāpes. Tāpēc uzdevums:

Uzdevums

Apzīmēsim prasību sarakstu:

  • ģenerējiet jebkura formāta papildu attēlus lidojumā, neieviešot lietojumprogrammā papildu funkcionalitāti jebkurā lietojumprogrammas pastāvēšanas laikā;
  • Papildu attēli nav jāģenerē pēc katra pieprasījuma;
  • Atspējojiet iespēju ģenerēt papildu attēlus nenoteiktā formātā.

Es paskaidrošu pēdējo punktu, jo tas ir nedaudz pretrunā ar pirmo punktu. Ja jebkuru attēlu ģenerēšanu padarām atvērtu, tad vietnei ir iespējams uzbrukums, ģenerējot lielu skaitu pieprasījumu mainīt attēla izmēru bezgalīgā formātu skaitā, tāpēc šī ievainojamība ir jāaizver.

nginx instalācijas konfigurācija

Lai atrisinātu iepriekš minētās prasības, mums ir nepieciešams šāds nginx moduļu komplekts:

Moduļi ngx_http_image_filter_module и ngx_http_secure_link_module nav instalēti pēc noklusējuma, tāpēc tie ir jānorāda instalēšanas konfigurācijas stadijā nginx:

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

nginx konfigurācija

Mēs pievienojam jaunu mūsu saimniekdatora konfigurācijai vieta un vispārīgie kešatmiņas parametri:

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

Mēs arī pievienojam konfigurācijai jaunu saimniekdatoru:

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

Rezultātā papildu attēlus var iegūt, izmantojot šādas saites:

* try_files — jūtīgs pret atstarpēm un krievu rakstzīmēm, tāpēc nācās taisīt kruķi ar aizstājvārds.

Izmantot tīmekļa lietojumprogrammā

Tīmekļa lietojumprogrammas līmenī varat veikt šādu procedūru (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'
                );

Lai gan es ieteiktu arī parēķināt izmērus priekšskatījums.

Grābeklis

Dzēšot sākotnējo attēlu, priekšskatījumi, protams, netiks dzēsti no kešatmiņas, kamēr kešatmiņa nav atzīta par nederīgu, un mūsu gadījumā priekšskatījumi var pastāvēt dienu pēc dzēšanas, taču tas ir maksimālais laiks.

oriģinālu

Avots: www.habr.com

Pievieno komentāru