Archive for the ‘web’ Category

De plus en plus de navigateurs ont un mode de navigation privée. C’est le cas pour Chrome, Firefox, Safari et Internet Explorer (inPrivate) en autres. Ces modes permettent de surfer anonymement sur Internet. Enfin anonymement…

Concrètement : la navigation privée, ça change quoi ?

Le principe de base, enoncé dans une publicité pour le système d’exploitation de Microsoft Window 7, et son navigateur internet associé IE8, est le suivant : vous pouvez acheter un cadeau sur l’ordinateur commun en mode privé, et quand vous avez fini il ne reste plus aucune trace de votre passage dans votre navigateur. Ceci est correct pour la majorité des navigateurs.

Lorsque vous entrez en mode de navigation privée, le navigateur n’enregistrera rien de ce que vous faîtes : tout est stocké dans un répertoire à part, qui vous permet de garder votre historique et vos cookies (nécessaires sur presque tous les sites où vous avez un compte). A la fin, lorsque vous fermez le navigateur ou que vous choisissez d’arrêter votre session de navigation privée, tout est supprimé et vous retrouvez un navigateur comme si vous n’aviez jamais rien fait.

Voici les principales applications de la navigation privée :

  • Pour faire un cadeau à quelqu’un, comme énoncé plus haut ;
  • Pour aller sur des sites adultes (soyons honnêtes : sans doute la principale utilisation faite de ce mode de navigation)
  • Pour prêter son ordinateur à quelqu’un (de confiance) temporairement : si cette personne se connecte à son compte Google par exemple, à la fin de la session vous serez toujours connecté à votre propre compte et non à celui de la personne à qui vous avez prêté votre ordinateur.

Question plus technique : les cookies

J’ai eu l’occasion d’effectuer différents tests sur Firefox 3.6, Chrome 5.0 et Internet Explorer 8 en utilisant cet outil. J’ai testé les cookies locaux et les cookies tièces. Pour les cookies tièrces, j’ai utilisé un script javascript distant pour lire et écrire les cookies. Les cookies distribués avaient une durée de vie de 1 journée (86400 secondes).

  • Sans navigation privée : les cookies locaux et tièrces sont correctement stockés et redistribués aux sites ;
  • Passage à la navigation privée : les cookies stockés sont perdus ;
  • Pendant la navigation privée : le navigateur se comporte normalement, avec lecture et écriture des cookies locaux et tièrces ;
  • A la fin de la navigation privée : les anciens cookies présents sont restaurés.

Le point qui me semble le plus important et le moins facile à deviner est donc la perte de toutes les cookies existant lors du passage en navigation privée.

L’anonymat sur Internet

Il existe bien des manières d’identifier une personne sur Internet. La méthode la plus sûre, et utilisée dans tous les cas (ou presque, j’imagine), c’est le cookie. Il permet vraiment d’identifier une personne derrière un écran. Mais il y a d’autres informations particulières qui, en dépit de ce que pourra faire votre navigateur, restent imprégnées sur la toile.

L’adresse IP : cette adresse est unique par foyer, et fixe dans la majorité des cas. Si vous n’avez qu’un seul ordinateur derrière une adresse IP, alors on peut aisément vous reconnaître, quel que soit l’ordinateur ou le navigateur que vous utilisez : vous êtes la même personne. De plus, il est facile de savoir si vous êtes seuls derrière : il suffit d’étudier le comportement de votre IP sur une petite attaque réseau bénigne lancée avec nmap par exemple.

Le User-Agent : si vous êtes plusieurs derrière une IP, on peut utiliser le User-Agent. Le User-Agent est une ligne de texte envoyée à tous les serveurs sur Internet qui permet de définir si vous êtes sous Mac ou PC, si vous utilisez Firefox ou Internet Explorer, si vous êtes sous Windows Vista ou Mac OS 10.4, ou encore sous iPhone ou Android… Comme deux ordinateurs dans une même maison sont rarement identiques (Système d’exploitation, Navigateur, et leur version associée), on peut reconnaître par exemple monsieur sous Windows XP et Madame sous Mac OS.

L’expérience de navigation : l’adresse IP pourrait tout de même être suffisante. Si vous êtes plusieurs derrière votre accès Internet à la maison, il n’en reste pas moins que chacun va sur les sites qui l’intéresse : Madame va lire Marmiton tandis que Monsieur va lire les Echos.

Conclusion

L’adresse IP est donc bien suffisante dans la majorité des cas pour identifier une personne,. En fait, l’anonymat sur Internet, vous pouvez l’oublier. Tout de même, il faudrait aller sur des sites peu scrupuleux pour avoir affaire à ce genre de pratiques (sites pornographiques, de Peer-to-Peer, …). Pour les autres, les systèmes de navigation privée proposés par les navigateurs sont bien suffisants.

Lien : outil de test utilisé pour afficher, écrire et supprimer des cookies

J’ai lu pas mal d’articles sur comment créer un cluster de session en PHP, afin de pouvoir utiliser plusieurs serveurs web en front tout en conservant les sessions entres les différents serveurs. Finalement, je vais expliquer la solution de repcached.

Memcached

Memcached est un serveur qui sert à enregistrer et redélivrer des valeurs diverses et variées directement dans la RAM d’un ordinateur.

Avantages : la rapidité d’éxecution des commandes et le support dans PHP en installant une simple extension PECL.
Inconvénient : perte des données en cas de reboot

Dans notre cas, pour stocker des sessions, c’est parfait : un accès rapide à des données, et plusieurs serveurs peuvent accéder à cette base de donnée en même temps.

Repcached

Repcached permet de pallier l’inconvénient de memcached : il s’agit simplement d’un patch qui permet de gérer la réplication entre deux serveurs. En effet, toute commande d’écriture sur un serveur est directement reportée sur l’autre serveur. Ainsi, si l’un des deux tombe, l’autre est à jour et peut prendre le relai. De plus, lors du reboot, toutes les données seront automatiquement récupérées auprès du premier serveur.

Cette solution permet du coup de gérer la redondance de l’information.

Puis-je mettre plus de 2 serveurs ?
Certainement, mais je ne sais pas trop comment… On pourrait mettre 3 serveurs en cycle, mais si l’un tombe, la chaîne est rompue. Il faudrait automatiquement adapter le routage des paquets non plus vers le serveur qui est tombé, mais vers le serveur survivant (en redirigeant les paquets par iptables par exemple).

Installation sous Gentoo

J’ai mis à disposition le serveur memcached 1.2.8 avec repcached 2.2 en ebuild à disposition ici :
http://cyril.me/ebuild/net-misc/memcached/

Cet ebuild se base sur la version 2.1-1.2.6 disponible dans l’overlay wolf32o1.

Consécutivement à l’article sur les notifications HTML 5, voici un article qui donne un exemple de fonctionnement des notifications.

La démo

Avant de pouvoir afficher une notification, vous devez autoriser le site à vous en présenter :
Il y a parfois des limitations qui empêchent le site de lancer une autorisation au chargement de la page : vous êtes parfois obligé de faire cliquer l’utilisateur sur un bouton pour voir apparaître l’avertissement d’autorisation.

Ensuite, vous pouvez afficher des notifications (avec ou sans bouton) :

Programmer une notification dans 3 secondes

Sources de l’exemple

Code HTML :

  1. <button onclick="showNotification()">Afficher la notification</button>
  2. <button onclick="p297_showNotification()">Afficher la notification</button>
  3. <a onclick="window.setTimeout(showNotification, 3000);" href="javascript:;">Programmer une notification dans 3 secondes</a>

Code javascript :

  1. <script type="text/javascript">
  2. /** Demande la permission d’afficher des notifications */
  3. function allowNotification()
  4. {
  5.   if("webkitNotifications" in window)
  6.   {
  7.     // Demande la permission. En cas de succès, afficher la notification
  8.     webkitNotifications.requestPermission(p297_showNotification);
  9.   }
  10. }
  11.  
  12. /** Affiche la notification */
  13. function showNotification()
  14. {
  15.   if("webkitNotifications" in window)
  16.   {
  17.     // Crée une notification à partir d’une image, d’un titre
  18.     // et d’une description (pas d’HTML possible).
  19.     // Pour créer une notification avec de l’HTML
  20.     // (pour le formatage), utiliser createHTMLNotification()
  21.     var notification = webkitNotifications.createNotification(
  22.       "http://www.google.fr/favicon.ico",
  23.       "Titre : cyril.me",
  24.       "Ceci est une notification"
  25.     );
  26.     // Afficher la notification
  27.     notification.show();
  28.     // N’afficher la notification que 5 secondes
  29.     window.setTimeout(function() {notification.cancel();}, 5000);
  30.   }
  31. }
  32. </script>

Match et non-match…

En cette période de coupe du monde de football 2010, quoi de plus naturel que de parler de match ? … Hum.

Problématique

Mon problème aujourd’hui, c’est de sélectionner les listes qui contiennent une certaines expression régulière, mais pas une autre. Plus exactement, et pour faire dans les anglicismes, je cherche « foo.* », mais pas « foobar ».

La solution

Il faut utiliser la forme suivante : (?!regexp) pour choisir quelque chose qui ne match pas la regexp en question.

Mon exemple en pratique :

$ echo -e 'foo\nfoobar\nfoofighting' | grep -P 'foo(?!bar)'
foo
foofighting

Plus d’informations disponible avec perldoc perlre, en particulier le chapitre sur les expressions régulières étendues (Extended Patterns)

Parce qu’on n’a pas toujours le document au format qui nous convient, ou parce qu’on a parfois besoin de repasser par des chaînes de caractères pour passer des arguments ou stocker des variables, différents outils de conversion sont mis à disposition du développeur.

Conversion en passant par JSON

Certains types peuvent être convertis en passant par JSON : le texte, les objets, les tableaux, les nombres…

Du type javascript au texte : il faut utiliser JSON.stringify
Exemple : JSON.stringify([1,2,3]) => « [1,2,3] »

Du texte vers un type javascript : il faut utiliser JSON.parse
Exemple : JSON.parse(« [1,2,3] ») => [1,2,3] (où 1, 2 et 3 sont des entiers)

Conversion d’un document DOMDocument ou XMLDocument

Deux outils sont à disposition : XMLSerializer (du document vers string) et DOMParser (de string vers un document).

XMLSerializer : DOMDocument vers une chaîne de caractères
Exemple : s = new XMLSerializer(); var documentString = s.serializeToString(document);

DOMParser : Conversion d’une chaîne de caractères vers un objet DOMDocument
Exemple : p = new DOMParser(); var doc = p.parseFromString(‘<html><body>coucou</body></html>’, ‘text/xml’);

Compatibilité

Ces APIs sont compatibles avec, entre autres, Safari 4.0+, Chrome, Firefox 3.5+, et peut-être IE… 😉

Il peut être parfois nécessaire d’utiliser une iframe, pour accéder par exemple à des cookies sur un autre site, se logguer, etc. Le problème est que si vous utilisez une iframe sur un domaine différent, le navigateur va vous renvoyer une erreur.

iframe et sécurité

Lorsque les domaine ou port diffèrent entre les deux frames, le navigateur va refuser la communication. En effet, imaginez que vous puissiez afficher une iframe cachée dans votre page, pour ensuite y récupérer des informations sensibles.

Exemple : dans mon site example.org, je mets une iframe vers mabanque.com et je récupère les informations bancaires de l’utilisateur de mon site (si celui-ci est déjà loggué sur le site de la banque).

La solution

Pour autoriser la communication entre les frames, il faut utiliser le protocole de communication entre les fenêtres.

Cette communication se fait par évènement : une fenêtre envoie à l’autre un objet1, qui le reçoit en ajoutant un handler sur l’évènement « message ».

Exemple

Dans notre exemple, l’iframe enverra un message à la fenêtre principale.

Fenêtre principale :

  1. // On rajoute un handler d'évènement
  2. function onMessage(e)
  3. {
  4.   // Vous pouvez vérifier l'origine de la fenêtre avec e.origin
  5.   document.getElementById('div-test').innerHTML = "Réception du message " + JSON.stringify(e.data);
  6. }
  7. window.addEventListener("message", onMessage, true);

Fenêtre iframe

  1. var dstWindow = window.parent;
  2. // Vous pouvez choisir le domaine vers lequel vous acceptez d'envoyer un message (ici, tous les domaines)
  3. dstWindow.postMessage([1,2,3], '*');

div-test pour la réception du message


1 : en fonction du navigateur, vous ne pourrez passer que des chaînes de caractères (Firefox 3.6 par exemple – Chrome supportant les objets). Pour pallier ce défaut, vous pouvez utiliser JSON.stringify et JSON.parse pour passer des objets comme des chaines ou des variables. Pour tout ce qui est DOM, ce n’est pas possible de faire passer les handler d’évènement définis dans la fenêtre source.

La question du jour : comment copier du texte en javascript.

En théorie

On va utiliser les objets suivants : la sélection DOM, et un Range.

La sélection DOM consiste en un objet, présent dans HTML5, qui permet de gérer les sélections de texte à l’intérieur d’un document.

Le range est un intervalle, qui permet de définir une zone continue dans un document.

En pratique, mis bout à bout

En pratique : on crée un range, on fait pointer la sélection dessus (en veillant à supprimer la sélection actuelle), et on exécute la commande « copy » pour copier la sélection dans le presse-papier.

  1. var r = document.createRange();
  2. r.selectNode(mon_element_a_selectionner);
  3. var s = window.getSelection();
  4. s.empty();
  5. s.addRange(r);
  6. document.execCommand('Copy');

Exemple : copier le code javascript (ne fonctionne qu’avec un navigateur compatible HTML5)

Les notifications

Introduit parmi les nouvelles fonctionnalités de l’HTML5, les notifications permettent aux sites web (que vous autorisez) de vous informer d’une activité sur un site. C’est comme les notifications de MSN messenger, quand une fenêtre apparaît en bas à droite de l’écran.

L’API supporte deux fonctions pour créer des notifications : soit à partir d’une URL, soit à partir d’une icône, d’un titre et d’une description. Utiliser une URL d’un fichier HTML permet d’avoir beaucoup plus de possibilités, au niveau de l’interaction comme au niveau de l’affichage (gras, images, liens, etc).

Utilisation dans chrome

Pour l’instant, chrome est le seul navigateur à supporter ce standard (sous Linux, hein !).

Voici un petit exemple de script (plus de détails dans la doc de chrome) :

  1. function showNotification()
  2. {
  3.   // Création de l'objet, puis affichage
  4.   var notification = webkitNotifications.createHTMLNotification('http://monurldenotification.com/');
  5.   notification.show();
  6. }
  7.  
  8. function sendNotification()
  9. {
  10.   var auth = webkitNotifications.checkPermission();
  11.   if (auth == 0) showNotification(); // Autorisé
  12.   else if(auth == 1) webkitNotifications.requestPermission(sendNotification); // Demande la permission
  13.   else { } // Refusé
  14. }
  15.  

Les limites

Malheureusement, il n’est pas possible de faire tout ce qu’on veut . Voici quelques limitations encore valables à ce jour :

  • Impossible de dialoguer entre la desktop notification et le script qui l’a ouverte ;
  • Impossible de spécifier une adresse du type data:text/html,<h1>test</h1>

A améliorer donc, afin d’avoir une réelle possibilité d’intégration dans des applications (type chat, …).

Problème

Lorsque l’on parse des fichiers, surtout les fichiers HTML, on a parfois besoin d’extraire un texte compris entre deux balises. Voici donc un moyen d’y parvenir avec les expressions régulières.

Considérations techniques

Je parlerais ici des expressions régulières perl (et par extension : grep -P et preg_* de php).

Par défaut, un /.*/ ou toute autre expression sera « gourmand » : ça matche tant que ça peut encore matcher. Par exemple, /a*/ appliqué à la chaîne "aaa" va matcher "aaa", et non pas "".

Dans mon cas pratique, j’ai une balise <td id="identifier"> et j’en cherche le contenu. Donc si la regexp utilisée est /<td id="identifier">(.*)<\/td>/ alors je vais matcher ce qu’il y a entre mon td ouvrant, et le dernier td fermant.

La solution

La solution consiste à dire au moteur d’expression régulière de prendre le moins possible, et ça se code comme suit : /<td id="identifier">(.*?)<\/td>/.

Bibliographie : http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/ab975ba5-31dd-4e6d-b72f-5cd6bf374b02 (et oui, parfois on trouve des choses utiles sur les forums de microsoft).

Voici une vidéo d’un Barack O. qui s’amuse avec des billets. C’est délirant!

Barack O. Rafle Tout