Is “if” really evil ?

Tags: , ,
Add comments

Hier, FRLinux me demande innocemment d’ajouter le module WPtouch, un chouette plugin pour WordPress, qui permet aux mobiles de visualiser le site sous forme d’application, bien plus lisible que le blog dans sa forme classique.
Ni une ni deux je m’execute… et m’aperçois que l’affichage d’iMil.net ne change pas d’un iota sur mes devices mobiles. Je me rappelle alors que le nginx placé devant l’Apache qui sert ce site cache la homepage pendant 10 minutes. Ceci explique cela.

Après quelques minutes de recherche, j’ai résolu le problème en plaçant ces quelques règles supplémentaires dans mon nginx.conf:

location / {
    set $mobile_ua '0';

    if ($http_user_agent ~* '(iPhone|iPod|mobile|Android|2.0\ MMP|240x320|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|hiptop|IEMobile)') {
        set $mobile_ua '1';
    }
    # ...directives proxypass...
    proxy_cache_key imil.net$request_uri$mobile_ua;
    # ...plein d'autres trucs...
}

Explication: on initialise une variable $mobile_ua à 0, si le User Agent match l’une des chaînes de caractères listées dans la condition if, la variable $mobile_ua est placée à 1.
La clé de cache étant maintenant composée également de cette variable, nous disposons de deux espaces de cache distincts, un pour les mobiles, l’autre pour le reste.

mmmmm nginx.

4 Responses to “Is “if” really evil ?”

  1. hellvinz Says:

    dans le même genre tu peux aussi utiliser HttpMapModule

    et faire ce genre de choses:

    map $http_user_agent $mobile_ua {
    default mobile;
    ~iPhone ios;
    ~iPod ios;
    ~IEMobile sale;
    }

    proxy_cache_key imil.net$request_uri$mobile_ua;

  2. iMil Says:

    rhooo, très booon ! Merci pour cette astuce !

  3. hr Says:

    Attention parce qu’avec la map tu match n’importe quel user agent, il faut donc aussi coller les UA de clients desktop classique.
    Je pense que default devrait avoir un mobile_ua plus generique qui match tout et des clés différentes pour les UA mobile. My 2 cents.

  4. bouquetin Says:

    Sinon, avec Varnish, ça tient en 3 lignes :

    if(req.http.user-agent ~ “(iphone|ipod|aspen|dream|android|cupcake|blackberry|blazer|cellphone|danger|docomo|iemobile|opera\ mini|webos|incognito|webmate)”) {
    set req.http.host = “m.domain.tld”;
    }

    L’explication est que Varnish tient un cache séparé par Host HTTP. Évidemment, faut avoir configuré son daemon web derrière pour qu’il réponde aussi à m.domain.tld.

Leave a Reply

WP Theme & Icons based on GlossyBlue by N.Design Studio
Banner from www.trynthlas.com
Entries RSS Comments RSS Log in
Performance Optimization WordPress Plugins by W3 EDGE