Page 1 sur 1

Comment stocker de gros cookies efficacement ?

Posté : 06 mars 2006, 01:12
par Hubert Roksor
Je doute qu'il existe une solution à mon problème mais je profite d'avoir accès à de brillants cerveaux tels que les vôtres pour confirmer mon doute. :roll:

Postulat: je réfléchis à un système de forum (oui, le 125874ème projet de forum PHP) qui s'appuirait énormément sur le stockage d'informations dans des cookies. Notamment, les topics lus. Je n'ai pas encore profondément songé à l'implémentation, mais chaque topic lu demanderait entre 6 et 8 octets de stockage. Le stockage étant réparti sur plusieurs topics pour éviter d'atteindre la limite de taille par cookie. (par exemple, en basant le nom du cookie sur "topic_id % nb_cookies")

Mon problème est le suivant: même si on peut les délester périodiquement, ces cookies peuvent rapidement devenir relativement gros donc je suis à la recherche d'une solution qui me permettrait d'exploiter un cookie en javascript sans qu'il soit transmis dans la requête HTTP. Bon, à priori c'est impossible, mais je n'aime pas ce mot :( (non, je ne suis pas l'identité secrète de Super Dupont)

J'ai exploré différentes approches, pour l'instant la moins pire consiste à définir le "cookie path" sur l'adresse du script qui liste les topics. Par exemple, "Set-cookie: [...]; path=/viewforum.php". Étonnamment, ça fonctionne et l'en-tête "Cookie" n'est envoyé qu'à viewforum.php (qui d'ailleurs, ne s'appelle pas viewforum.php car on a également besoin de ces informations dans viewtopic.php, mais l'exemple reste valide). La prochaine étape pour moi est de ne pas envoyer ce Cookie même si la page demandée est viewforum.php... une idée ?

Une autre piste, explorée puis abandonnée, était de définir comme path l'adresse d'un script Javascript. L'idée était d'avoir un script qui s'occupe de changer les images des topics (lu/non-lu) et de limiter le scope des cookies à ce script uniquement. En définissant une date d'expiration lointaine, aucune requête ne part donc aucun transfert. J'ai trouvé cette idée tellement démoniaque que j'ai ri comme le Dr Evil pendant au moins deux minutes. Bon... après ça j'ai cherché comment récupérer le cookie à part du script et je me suis aperçu que le seul cookie auquel on pouvait accéder était document.cookie, donc impossible d'associer un cookie avec un javascript. Si j'ai tort, merci de me corriger, je vous en serai éternellement reconnaissant.

Il me reste encore une troisième piste à explorer, mais je me doute que si elle fonctionne ce ne sera que le hasard d'une faille d'implémentation de Firefox. Je me demande si en trichant avec un header "Content-location" ou "Content-base" on pourrait accéder à un cookie associé au même domaine mais avec un autre path. Auquel cas, il suffirait de définir un path inexistant (de ce fait, aucune requête ne l'enverra au serveur) et utiliser ce path dans un "Content-location" pour y accéder via document.cookie. Relativement tiré par les cheveux.

Tous les commentaires sont les bienvenus, merci. ;)

Posté : 06 mars 2006, 09:39
par Hubert Roksor
Sans surprise, Content-location ne permet apparament pas d'utiliser les cookies possédant ayant un rayon d'action (scope) différent de l'URL utilisées pour le document, même lorsqu'il s'agit du même domaine :(

Posté : 06 mars 2006, 15:22
par naholyr
Que je comprenne bien, tu veux manipuler ton cookie en Javascript (client-client) mais pas en PHP, et donc qu'il ne soit surtout pas transmis au serveur afin de limiter la bande passante ?

Posté : 06 mars 2006, 19:38
par Hubert Roksor
C'est exactement ça :)

Posté : 06 mars 2006, 20:28
par naholyr
En fait j'ai peur que ça ne soit pas possible, mais je ne suis pas sûr du fonctionnement des cookies.
Il me semble que tout se passe du côté du navigateur : si j'ai un cookie pour /domain/path alors je l'envoie en même temps que la requête.

Si c'est bien ça (et j'en ai peur), ça veut dire que du moment qu'un cookie existe, il est de toute façon envoyé.

Partant de là le seul moyen serait effectivement de tricher sur le path du cookie, et via javascript de lire un cookie se situant sur un "faux" path, mais c'est hélas (?) impossible.

Quelqu'un a le courage de lire la RFC du protocole HTTP concernant les cookies ? :D

Posté : 06 mars 2006, 23:19
par Hubert Roksor
J'ai lu beaucoup de RFCs ces derniers jours (j'ai même essayé de lire l'ECMA-262 mais je me suis endormi au premier paragraphe :lol:) et tout porte à croire que le design est suffisament "vérouillé" pour que ce que j'essaie d'accomplir soit impossible. D'ailleurs, durant mes recherches j'ai découvert que ma technique à base de Content-location était plus ou moins à l'origine d'une faille de sécurité d'IE (patchée depuis deux ans).

Il me reste encore plusieurs pistes à explorer, même si certaines n'en valent probablement pas la peine:
  • utiliser des (I?)frames pour stocker les infos dans l'une qui modifierait l'autre. Mais les frames ne sont pas DTD-Strict donc je n'essaierai pas (j'avais oublié de préciser que je voulais utiliser le DTD Strict... ;))
  • utiliser des xhr pour récupérer le contenu de la page et pouvoir clamer que mon forum est Web 2.0, mais dans ce cas on peut dire au revoir au bouton Back... donc non.
  • compresser les données. Je pense qu'on pourrait les compresser (je n'ai pas une connaissance pratique des méthodes de compression, mais je pense que ce qui me conviendrait serait une "prefix compression")
  • trouver un moyen de mieux compartimenter les cookies pour n'envoyer que le strict nécessaire. En fait le "strict nécessaire" est une utopie, mais je pourrais théoriquement réduire la quantité de données envoyée par un facteur de 5 à 10.
    • pour chaque topic, un timestamp correspondant à la dernière lecture est stocker dans un cookie dont le path est
      "lire" . ($forum_id % $nb_cookies) . ".php"
    • pour voir les topics du forum 3, ou les posts d'un topic du forum 3, l'URL serait "lire3.php?mode=...." et seules les données liées au forum #3 serait envoyées
    C'est super compliqué, il faut utiliser mod_rewrite (ou assimilé) et en plus ça pose probème lors du déplacement des topics. Je vais devoir réfléchir un peu pour savoir si le jeu en vaut la chandelle.
  • créer une RFC proposant la création de flags pour définir le scope d'un cookie: http et/ou document (possiblement d'autres scopes). Après tout, ça offrirait à tous les navigateurs l'équivalent du "httpOnly" d'Internet Explorer
Le bon côté c'est que tout n'est pas fini et que j'ai encore beaucoup d'options (pour la plupart vouées à l'échec :lol:)

Follow-up

Posté : 22 mai 2006, 23:00
par Hubert Roksor
Apparemment, ce que je recherche est en train d'être implémenté dans Firefox 2 (entre autres) sous l'appelation "DOMStorage". Voir le Web Applications 1.0 working draft @ WhatWG