Hackeando o Nginx: condicionais múltiplas


Ontem tirei o dia para otimizar o desempenho de meu blog, e obtive resultados deveras animadores, ao conseguir fazer com que o código dele fosse totalmente compatível com o HHVM.

Porém, descobri um problema que talvez estivesse impedindo algumas pessoas de, sob determinadas circunstâncias, visualizar corretamente as imagens dos posts.

Acontece que uso o Nginx para servir conteúdo via HTTP, e uso o plugin EWWW Image Optimizer (leia mais sobre ele aqui) para produzir versões mais leves das imagens que subo para cá. Este plugin permite converter imagens .jpg e .png comuns para o formato super otimizado .webp, que por enquanto é suportado apenas pelo Chrome, pelo Opera e pelos navegadores padrão dos dispositivos Android.

Eu tinha um código de detecção de habilidade do navegador para exibir imagens .webp (é fácil, o próprio navegador anuncia essa capacidade ao fazer uma requisição), caso uma imagen .webp com o mesmo nome da original existisse (que é precisamente o que o plugin faz).

Porém, em alguns casos a detecção parecia não estar funcionando, pois visitantes usando o Firefox eram solicitados a fazer download da imagem .webp, e visitantes usando o Chrome visualizavam a imagem .jpg normal. Deduzi que o problema estava no cache, uma vez que a imagem .webp era servida com a extensão original.

A solução para o problema é simples: o Nginx deve garantir que duas condições sejam aceitas para só então servir a imagem .webp: ela tem que existir no servidor, e o visitante tem que ter um navegador capaz de exibir o .webp.

Entretanto, o Nginx não permite utilizar nenhum operador lógico and nas suas condicionais, tampouco permite estruturas if aninhadas. Isso poderia ser um problema para quem faz questão de resolver as coisas de maneira elegante. Para mim, apenas oportunidade de testar um conceito, e aplicar um hack no Nginx.

O código abaixo faz a mágica:

O segredo está na variável $red (não sou muito criativo com nomes de variáveis). Ela é inicializada com um valor arbitrário “Z”.

Em seguida eu testo se o navegador aceita imagens .webp. Se sim, troco o valor de $red para “A”.

Depois verifico se a imagem .webp existe para ser servida ao visitante; caso exista, a variável $red é alterada para o valor dela mesma, mais um “B” ao final.

Nesse ponto, $red pode contar uma combinação de valores, mas o único que realmente importa é “AB” (“A” de que o navegador suporta o formato e “B” de que o arquivo existe para ser servido), caso em que é feito o redirecionamento da imagem original para a imagem .webp otimizada.

Justamente este redirecionamento que é transparente para o visitante é que impede os conflitos com o cache de que falei no início.

Compartilhe

Avalie este conteúdo!

Avaliação média: 4.42
Total de Votos: 12
Hackeando o Nginx: condicionais múltiplas

Janio Sarmento
Administrador de sistemas, humanista, progressista, apreciador de computadores e bugigangas eletrônicas, acredita que os blogs nunca morrerão, por mais que as redes sociais pareçam cada vez mais sedutoras para as grandes massas.

3 comentários

  • osgregs:

    gostei da solucao, se possivel exibir o restante do codigo excluindo dados sigilosos, agradeceria.

    Responder
    • Janio Sarmento:

      Como assim “o restante do código?”

      O código acima está completo, e faz exatamente o que eu quero que faça. Do que foi que esqueci? 😀

      Responder
      • osgregs:

        realmente… falha minha, nao tinha visto setado o valor Z

        Responder

Comente!

This site uses Akismet to reduce spam. Learn how your comment data is processed.