| |
mar 06
Nous allons voir comment déporter le système de géo-localisation IP sur Varnish.
L’objectif final est de permettre à vos backends de récupérer le Pays de l’utilisateur au sein de la requête HTTP.
Par défault, Varnish n’intègre pas de système de géo-localisation par IP, en revanche il existe quelques plugins qui permettent l’utilisation de GeoIP de MaxMind.
Voici les parties de l’article :
- Installation de Varnish
- Installation de GeoIP pour Varnish
- Configuration du Varnish Module
- Configuration de SELinux
A noter que nous avons opter pour le VMOD Geoip-vmod par leed25d. Contrairement aux autres plugins, celui-ci ne travail pas le header HTTP de manière autonome. Ce sera à vous de le faire, et grâce à cela vous allez pouvoir choisir comment…
Varnish
Pour compiler le VMOD, il vous faudra récupérer les sources de Varnish et les compiler même si vous choisissez l’installation par YUM.
De mon coté, je n’utilise pas en production la version que je compile mais la version provenant du dépot varnish-cache.org. A vous de voir.
Commençons par l’installation de Varnish via YUM (cf. Doc officielle):
rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release-3.0-1.noarch.rpm
yum install varnish
Pour compiler Varnish nous allons avoir besoin de quelques outils et des sources.
yum install pcre-devel make
cd && curl -o varnish-source.tar.gz http://repo.varnish-cache.org/source/varnish-3.0.2.tar.gz
tar -xvzf varnish-source.tar.gz
On lance la compilation de Varnish.
cd varnish-3.0.2/
./configure
make
Normalement, Varnish a été compilé dans votre repertoire $HOME/varnish-3.0.2/.
GeoIP VMOD
On récupère les sources sur github.
Après l’installation de quelques outils dont GeoIP, on lance la compilation du VMOD.
Attention, pour les version 32Bits utiliser VMODDIR=/usr/lib/varnish/vmods/.
yum install unzip automake autoinstall libtool geoip geoip-devel
unzip leed25d-geoip-vmod-[REVISION].zip
cd leed25d-geoip-vmod-[REVISION]
./autogen.sh
./configure VARNISHSRC=$HOME/varnish-3.0.2/ VMODDIR=/usr/lib64/varnish/vmods/
make
make install
Suite à l’installation Varnish, penser à ouvrir votre firewall.
#/etc/sysconfig/iptables
-A INPUT -m tcp -p tcp --dport 80 -j ACCEPT
De même, il faut configurer Varnish pour écouter sur le port 80 à la place du 6081.
#/etc/sysconfig/varnish</strong>
VARNISH_LISTEN_PORT=80
Ensuite, on va vérifier que l’on peut lancer Varnish en chargeant le plugin GeoIP.
#/etc/varnish/default.vcl
#Top of file.
import geoip;
On va lancer le processus en debug pour voir si tout se passe bien :
varnishd -d -f /etc/varnish/default.vcl
start
Si vous n’avez pas d’erreur, c’est une bonne chose. Sinon, vérifier les étapes ci-dessus.
On va donc pouvoir inclure le pays de l’utilisateur dans le Header HTTP en suivant l’exemple de l’auteur du VMOD
#/etc/varnish/default.vcl
import geoip;
sub vcl_recv {
set req.http.X-Forwarded-For = client.ip;
set req.http.X-GeoIP = geoip.country(req.http.X-Forwarded-For)
}
Maintenant on va pouvoir mettre Varnish en démarrage automatique.
chkconfig varnish on
service varnish start
Attention:
Sachant que vous êtes sous CentOS, SELinux est surement activé et bloquera l’access au fichier de données /usr/share/GeoIP/GeoIP.dat. Vous pouvez le désactiver ou aller voir à la fin de l’article comment le configurer aux petits oignons.
Et pour finir, un peu de ménage.
cd && rm -Rf varnish-* && rm -Rf leed25d-*
yum remove pcre-devel make unzip automake autoinstall geoip-devel
Pour aller plus loin
Avec la configuration ci-dessus,
Si un client de France se connecte directement à Varnish, lorsqu’une requête sera générée pour atteindre vos backends elle contiendra : X-GeoIP: FR
Vous pourrez donc récupérer le pays de l’utilisateur en analysant le contenu de la requête HTTP.
Il est à noter que GeoIP retourne le code pays « AA » lorsqu’il ne parvient pas à faire la détection.
Voici comment vous pouvez exploiter le contenu du header en PHP :
$headers = apache_request_headers();
$code = null;
if ($headers && is_array($headers) && array_key_exists("X-GeoIP", $headers)) {
$code = $headers["X-GeoIP"];
}
if ((null == $code)||("AA" == $code)) {
$code = $this->getDefaultCountry();
}
$code = strtoupper($code);
Retournons du coté de Varnish.
Comment les choses vont se passer si vous ajoutez un Proxy en amont de Varnish. Par exemple, Pound pour gérer le protocole HTTPS.
La detection du pays ne fonctionnera plus normalement car la valeur contenu dans le script VCL ‘client.ip‘ correspondra à l’IP de votre serveur Pound.
Nous allons donc devoir travailler avec un autre Header HTTP: X-Forwarded-For. Celui-ci permet de conserver l’historique des différents point de passage d’une requête HTTP et contient l’IP du client qui a initié la connection HTTP.
Lorsque les différents Proxy implementent correctement ce standard, le champs X-Forwarded-For contient l’IP du client, le proxy A, le proxy B, etc.. le tout séparé avec des virgules.
Voici comment en tenir compte au sein de votre configuration VCL :
sub vcl_recv {
//...
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
set req.http.X-GeoIP = geoip.country(regsub (req.http.X-Forwarded-For, "(,.*)", ""));
//...
}
Maintenant parlons un peu du système de cache de Varnish.
Si vous avez besoin de connaitre le pays de l’utilisateur, il y a donc fort à parier que le contenu retourné à l’utilisateur sera different en fonction de son Pays.
En résumé, pour une URL : /mon-url, en fonction du Pays utilisateur le contenu sera different.
Si on conserve la spécification par défaut de Varnish qui consiste à mettre en cache les données provenant d’une même URL, vous allez avoir quelques mauvaises surprises.
Voici comment tenir compte du pays de l’utilisateur pour gérer les données qui sont mises en cache.
sub vcl_hash {
//...
hash_data(req.url);
hash_data(req.http.X-GeoIP);
//...
return (hash);
}
SELinux
Sous Centos, il y a SELinux.
Si vous n’êtes pas un expert en sécurité Linux. Voici comment faire fonctionner Varnish & GeoIP sans désactiver SELinux.
Le processus Varnish fait parti d’un contexte SELinux different du fichier GetIP.dat qui est installé avec GeoIP.
Du coup, nous allons faire un module pour SELinux afin d’autoriser varnish_t à lire les contextes de type usr_t.
mkdir ~/myvarnish; cd ~/myvarnish;
echo "policy_module(myvarnish, 1.0.0) optional_policy(\` gen_require(\` type varnishd_t; ') files_read_usr_files(varnishd_t) ')" > myvarnish.te
make -f /usr/share/selinux/devel/Makefile myvarnish.pp
semodule -i myvarnish.pp
Pour le coup, cette partie provient d’une discussion avec une personne sur #SELinux on freenode.
Mots-clefs : Astuce, CentOS, Compilation, Debian, GeoIP, Header, HTTP, HTTPS, Infrastructure, Module, Pays, Sécurité, Système, Varnish
juin 20
Mise en situation :
- Application_A.swf est une application autonome qui utilise les Flashvar.
- Application_Preloader.swf est un preloader qui va charger Application_A.swf.
L’objectif c’est de pouvoir utiliser les Flashvar avec Application_Preloader.swf pour qu’elles soient transmises à Application_A.swf.
Pour cela, nous allons utiliser une instance de URLVariables que l’on passera à URLRequest.
var _urlRequest : URLRequest = new URLRequest ( "http://www.domain.tld/Application_A.swf" );
var _urlVariables : URLVariables = new URLVariables ();
var _loader : Loader = new Loader ();
for (var property : String in loaderInfo.parameters )
{
_urlVariables[property] = loaderInfo.parameters[property];
}
_urlRequest.method = URLRequestMethod.GET;
_urlRequest.data = _urlVariables;
_loader = new Loader ();
_loader.load ( _urlRequest );
Mots-clefs : ActionScript, Adobe, Application, Astuce, Flash, Flashvar, Paramètre
juin 01

Prenons le schéma ci-dessus.
Au niveau de la définition, nous avons deux entités : Bureau ( rooms ) et Utilisateur ( users ). Ces deux entités sont liées par une relation manyToMany car un utilisateur peut avoir plusieurs bureaux, et un bureau peut avoir plusieurs utilisateurs.
Pour pouvoir intégrer l’ordonnancement des utilisateurs au sein d’une pièce, nous avons ajouté le champs « index » sur la table de liaison.
Grâce à cette définition, nous pouvons avoir les cas suivants :
- Robert est à la place #2 dans le bureau d’accueil
- Robert est à la place #1 dans le bureau du président
- Annie est à la place #1 dans le bureau du président
Définition des Domain Model Object

Nous allons maintenant définir les liaisons Doctrine entre ces objets.
Je n’utiliserai pas la définition YAML.
abstract class Model_Base_Room extends Model_Base
{
public function setTableDefinition()
{
$this->setTableName('rooms');
$this->hasColumn('id_room as idRoom', 'integer', 4, array(
'type' => 'integer',
'fixed' => 0,
'unsigned' => false,
'primary' => true,
'autoincrement' => true,
'length' => '4',
));
$this->hasColumn('title', 'string', 80, array(
'type' => 'string',
'fixed' => 0,
'unsigned' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
'length' => '80',
));
}
public function setUp()
{
parent::setUp();
$this->hasMany('Model_User as users', array(
'refClass' => 'Model_CompoRoomsUsers',
'local' => 'id_room',
'foreign' => 'id_user'));
}
}
abstract class Model_Base_User extends Model_Base
{
public function setTableDefinition()
{
$this->setTableName('users');
$this->hasColumn('id_user as idUser', 'integer', 4, array(
'type' => 'integer',
'fixed' => 0,
'unsigned' => false,
'primary' => true,
'autoincrement' => true,
'length' => '4',
));
$this->hasColumn('firstname', 'string', 80, array(
'type' => 'string',
'fixed' => 0,
'unsigned' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
'length' => '80',
));
}
public function setUp()
{
parent::setUp();
$this->hasMany('Model_Room as rooms', array(
'refClass' => 'Model_CompoRoomsUsers',
'local' => 'id_user',
'foreign' => 'id_room'));
}
}
abstract class Model_Base_CompoRoomsUsers extends Model_Base
{
public function setTableDefinition()
{
$this->setTableName('compo_rooms_users');
$this->hasColumn('id_room as idRoom', 'integer', 4, array(
'type' => 'integer',
'fixed' => 0,
'unsigned' => false,
'primary' => true,
'autoincrement' => false,
'length' => '4',
));
$this->hasColumn('id_user as idUser', 'integer', 4, array(
'type' => 'integer',
'fixed' => 0,
'unsigned' => false,
'primary' => true,
'autoincrement' => false,
'length' => '4',
));
$this->hasColumn('index', 'integer', 4, array(
'type' => 'integer',
'fixed' => 0,
'unsigned' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
'length' => '4',
));
}
public function setUp()
{
$this->hasOne('Model_User as user', array(
'local' => 'id_user',
'foreign' => 'id_user'));
$this->hasOne('Model_Room as room', array(
'local' => 'id_room',
'foreign' => 'id_room'));
}
}
Ordonner avec DQL
Après cette longue définition, nous pouvons passer au code DQL qui permettra d’ordonner les résultats en fonction de l’index de notre table de liaison.
$query = Doctrine_Query::create ()
->select ("room.*, users.*")
->from ("Model_Room room")
->leftJoin ("room.users users")
->orderBy ("room.id_room, users.Model_CompoRoomsUsers.index ASC");
Prenez note du fait que nous trions dans un premier temps par identifiant de bureau et ensuite par index. Si nous n’utilisions qu’un tri par index, l’ordre des bureaux serai incohérent.
Pour aller plus loin
Nous avons décrit le fonctionnement pour ordonner des résultats à partir d’une table de liaison.
Mais vous pouvez aussi utiliser cette méthode pour conditionner le résultat.
Mots-clefs : Astuce, Doctrine, DOM, DQL, Ordre
mar 18
Toujours has been, la balise iframe peut se révéler pratique dans certains cas.
L’exemple d’utilisation qui me vient à l’esprit, c’est l’affichage d’un fichier PDF.
Personnellement, cela me sert pour afficher mon CV sur thomas.tourlourat.com
Pour que le PDF utilise toute la zone du navigateur, il faut utiliser la petite astuce CSS suivante :
<style type="text/css">
html,body
{
width:100%;
height:100%;
margin:0px;
padding:0px;
}
</style>
Afficher ensuite votre iFrame
<iframe
src="http://tourlourat.com/documents/cv_tourlourat_thomas.pdf"
id="cv"
width="100%"
height="100%"
scrolling="auto"
frameborder="0" >
</iframe>
Mots-clefs : Astuce, CSS, CV, html, iFrame, Ingénieur Informatique, PDF
nov 17
Suite au commentaire de webstorming sur l’article : Flash – Restreindre l’instanciation d’une classe par un seul objet.
Voici l’implémentation du pattern singleton en Flash.
public class PatternSingleton
{
private static var _instance : Object;
public function PatternSingleton () : void
{
if (_instance)
throw new Error ("Pattern Singleton : only one instance is permit");
_instance = this;
}
public function sayHello () : String
{
return "Hello World";
}
public static function get instance () : PatternSingleton
{
if (!_instance)
new PatternSingleton ();
return PatternSingleton (_instance);
}
}
Nous avons donc une class ne pouvant être instanciée qu’une seule fois, et accessible de n’importe où au sein de notre application.
trace (PatternSingleton.instance.sayHello ());
Wikipédia
L’implémentation que l’on trouve sur Wikipédia est différente de celle ci-dessus.
En effet, elle utilise la définition d’une constante globale sans modification du constructeur.
Le problème induit, c’est que l’instanciation multiple n’est pas interdite au sein de l’application. Et la compréhension par un débutant est moins aisée.
Mots-clefs : ActionScript, Astuce, Code, Flash, Pattern, Singleton
nov 12
Pourquoi a t-on un site où l’on s’investit ? Il existe autant de raison que de webmestre, mais tout le monde à la même pré-occupation : être visible, et se démarquer.
Ici, nous ne ferons aucune analyse technique, nous verrons par contre quels sont les points qu’il ne faut pas négliger et ceux que vous pouvez approfondir pour aller un peu plus loin.
Malgré une volonté de généricité, WordPress sera le support de cet article, mais les conseils restent de mises pour tout type de CMS. De même que Google servira de référence.
Les balises meta : title, keyword, description
Elles sont souvent mises de coté, et beaucoup de professionnels ne les considèrent pas comme « importante ».
Il faut en fait savoir deux choses avant de dire qu’elles ne sont pas nécessaire.
- Les balises Title et Description seront les représentant de votre site lorsque les utilisateurs utiliseront un moteur de recherche. A noter aussi, que si la description n’est pas définit explicitement, Google prendra un extrait de la page qu’il analyse. A vous de faire des introductions pertinentes
- Concernant keyword, personne n’est en mesure de dire si elle est encore utilisée, en effet les algorithmes qui analysent vos pages sont de plus en plus évolués et permettent de ressortir les idées importantes.
Deux constats, un point important :
Premièrement, Title et Description sont des balises très importantes pour l’accroche du visiteur à partir des moteurs de recherche.
Le titre d’une page est aussi utilisé pour connaitre le contenu d’une page, penser donc à y mettre des mots « clés » et à faire ressortir une idée. Sur annuaire-info vous trouverez une page plus exhaustive contenant des conseils d’utilisation.
Deuxièmement, même si l’on est pas sur de l’intérêt de title, description et keyword sur le positionnement de votre page par rapport à vos concurrents: dans le doute… Il vaux mieux les remplir avec qualité.
Sous WordPress, les titres sont formatés par défaut : « Nom du blog > Date > Titre ». Si vous pensez que le nom de votre site, et la date sont importants pour votre référencement, passer directement à la partie suivante…
Pour modifier cette aspect, vous pouvez modifier le fichier header.php de votre theme, ou mieux, utiliser un plugin : SEO Title Tag
Le plan du site : sitemap.xml ?
Le sitemap est utilisé par une grande partie des moteurs de recherche.
Son utilité est simple, permettre de donner des informations relatives à une page: date de modification, importance par rapport aux autres pages.
La priorité permet de « forcer » un peu la main à Google concernant la pertinence d’une page par rapport à une autre.
Ce fichier est généré automatiquement grâce à des plugins si vous utilisez un CMS. Mais par défaut, il n’est pas installé sur le plupart de ces systèmes.
Vous trouverez le plugin pour WordPress ici.
Un autre meta / attribut : nofollow
Dans un précédent article, j’expliquais – succinctement – le nofollow.
Cette balise peut-être utilisée dans le header de votre page, ou en simple attribut pour un lien spécifique.
Il est utilisé pour empêcher les moteurs de recherche de suivre vos liens.
C’est un point important à vérifier lorsque vous venez de terminer l’installation de votre site.
Sous WordPress, le nofollow est activé par défaut pour l’ensemble de votre site. Ce qui est dommage car cela signifie que le moteur de recherche s’arrêtera à votre page d’accueil.
Pour autoriser le parcours de votre site : Aller dans la partie d’administration -> Réglage -> Vie privée, et cocher : « Je souhaite que mon blog soit visible pour tous… »
URL de votre page
Étroitement lié à votre titre de page, l’URL permet aux moteurs de recherche d’en savoir un peu plus sur le contenu de votre page.
Comme pour le titre et la description, il faut donc le traiter avec soin.
Personnellement, j’essaie de reprendre les mots constituants mon titre de page en supprimant les articles indéfinis et autre conjonction.
Si vous avez construit un titre pertinent, votre URL contiendra des mots qui définissent de très près votre page.
Sous WordPress, lorsque vous tapez votre titre, l’url se construit dynamiquement lorsque vous changez de case. Vous pouvez le modifier très facilement grâce à un lien se situant juste en dessous.
D’ailleurs, lorsque vous travaillez avec des brouillons, si vous changez le titre, il faudra modifier l’URL à la main. Sinon, vous pouvez vous retrouver avec un titre « Toto à la plage » et une url « mes_vacances_sur_un_bateau ».
Penser aussi à utiliser des liens simplifiés, en série sur la majorité des CMS, sous WordPress, vous trouverez la configuration dans l’administration -> réglage -> permaliens.
J’utilise en structure personnalisé
Edit 21/11/08 :
Modification de la structure personnalisée.
Afficher la catégorie de l’article alors que les titres intègrent des titres explicites me semble un peu inutile vis-à-vis du référencement.
Par contre, il va y avoir un impact sur l’ensemble de mes backlinks… Mais comme il y a une page 404 de la mort, il n’y a aucune d’avoir peur des répercutions :p
Les outils à votre disposition
Voici une liste qui est loin – très loin – d’être exhaustive des outils que vous pouvez – devez ? – utiliser.
De même, inscrivez-vous sur un maximum d’annuaire, et penser à enregistrer vos flux RSS.
Pour aller plus loin
Nous avons vu les principes de bases à mettre en place pour l’optimisation de votre référencement.
Ensuite, c’est à vous de faire un travail de fond, par exemple, n’hésiter pas à réagir sur d’autres sites, et même à intervenir pour la création d’article.
Penser à faire des échanges de lien, car si un visiteur se plait sur un site qui correspond au votre, il aimera surement découvrir vos articles.
Noter que nous n’avons nullement parler du PageRank et d’autres données inutiles. En effet, si vous arrivez à plaire à vos visiteurs, vous n’aurez pas besoin d’avoir un PR de 5 pour qu’ils reviennent, car ils le feront d’eux même; alors que l’inverse n’est pas vrai.
Vous trouverez énormément d’information sur le net concernant l’écritures d’un article et le maintient d’un blog qui feront de vos visiteurs des gens heureux.
Mais rendre la visite plaisante n’est pas le sujet de l’article, juste une suite logique que vous devez avoir aborder.
PS : Cette article est trop long, manque d’image et de pause. Heureusement qu’il n’est pas la pour rendre accro :p
Mots-clefs : Astuce, CMS, google, Référencement, Yahoo
|
|
Commentaires récents