Lecture de cookies

Généralités

Nous allons à présent utiliser un autre moyen pour échanger des données entre le navigateur web et le serveur : les cookies.

Les formulaires permettent de transmettre au serveur des informations qui seront utilisables dans la page suivante. Mais si après cette nouvelle page, on a encore besoin d'une donnée du formulaire dans d'autres pages, il faudra continuer à transmettre cette donnée de page en page, soit au moyen de nouveaux formulaires dans lesquels la donnée pourra être dans un champ caché, soit dans l'URL des pages qui suivront.

On peut faire plus simple avec les cookies qui sont des fichiers stockés par le navigateur web afin de mémoriser des données qui pourront être utilisées plus tard ... ou jamais.

Une utilisation connue des cookies dont l'utilité est très contestable pour ceux qui consultent un site web consiste à enregistrer des informations sur ce que font les utilisateurs du site afin de leur envoyer plus tard des publicités ciblées ou des suggestions d'achats.

Un forum de discussion, une documentation en ligne (wiki) lorsqu'on veut en modifier le contenu, un site marchand dont on est client, une boîte de courrier électronique à laquelle on veut accéder depuis un navigateur web, un site bancaire sur lequel on a un compte, demandent aux utilisateurs de s'identifier. Cette identification est conservée par le navigateur sous la forme d'un cookie.

Mais les cookies peuvent contenir des informations de nature très variées. Il suffit que le contenu du cookie soit du texte. Le site web http://apertiumtrad.tuxfamily.org par exemple est un site qui utilise jusqu'à 26 cookies distincts et indique à quoi ils servent.

Habituellement, c'est le serveur web qui crée un cookie qui sera envoyé au navigateur. Toutefois, au moyen de javascript, on peut aussi créer des cookies coté navigateur pour transmettre au serveur des informations qui ne le sont pas automatiquement. Par exemple, les dimensions de la zone d'affichage de la page web ou l'heure de l'ordinateur qui la consulte.

C'est ce genre de cookie qu'on va utiliser dans ce programme d'exemple.

Ce qui fait le site web

Ce site web est constitué d'une page unique dont le code source est le suivant :



L'entête de la page contient 3 lignes de javascript qui récupèrent chacune une information et l'enregistrent dans un cookie.

Le corps de la page contient à la fois :
Sans traitement coté serveur, la page affichée dans une fenêtre de 700 x 500 pixels donnera ce genre de résultat :



Pour voir le résultat avec d'autres tailles de fenêtre de navigateur, vous pouvez cliquer ici.

Fonctionnement du programme Arduino

Pour téléverser le programme sur la carte Arduino, il faut d'abord mettre dans un répertoire les 3 fichiers suivants :
Sur la carte SD, on mettra les fichiers :
On supposera que l'adresse MAC et l'adresse IP de la carte Ethernet ont été configurées conformément à ce qui est dit dans la page Généralités

Examinons maintenant la partie intéressante du programme Arduino.



Comme pour tous les autres programmes d'exemple fournis sur ce site, à l'exception du compteur de passages, une première variable va contenir le nom de la page HTML utilisée :
    // Nom du fichier à récupérer
    char url [14];
Ce programme ne récupère pas d'information par la méthode GET. La taille optimale pour la variable url est donc de 14 caractères, comme expliqué dans "Site statique multi pages".

Une autre variable est nécessaire pour mémoriser les différents cookies :
    // Cookies récupérés
    char cookies [50];
Le nombre de caractères de cette variable doit être suffisant pour mémoriser les noms et tous les cookies et leur valeurs.

La fonction loop () utilise aussi plusieurs autres variables locales :
    char valhaut [6], vallarg [6], valtime [15];
    long timesec, hloc;
    int  heure, min, sec;
    char heure_aff [10];
Ces variables permettront de récupérer séparément les valeurs des différents cookies et de calculer l'heure à partir du nombre contenu dans le cookie concerné.

Lorsque la carte Arduino détecte une demande de page, comme pour tous les autres programmes, la fonction lire_trame_client (...) est appelée.

Cette fois-ci, elle l'est avec 7 paramètres :
    lire_trame_client (client, url, sizeof (url), 0, 0, cookies, sizeof (cookies));
Ces paramètres sont :
  1. Identifiant du client web.
  2. Nom de la variable qui contiendra le nom de la page demandée par le navigateur.
  3. Taille de la variable précédente.
  4. 0 : pas de récupération de paramètres par la méthode POST.
  5. 0 : pas de mémoire réservée pour une variable post.
  6. Nom de la variable qui contiendra les cookies.
  7. Taille de la variable précédente.
Si la page du site a déjà été affiché une fois, en cliquant sur le lien Relancer on aura forcément le nom du bon fichier dans la variable url. Mais si au début, on tape juste l'adresse IP de la carte Arduino, ce ne sera pas le cas.

Un test permet de sélectionner la bonne page si aucune page n'a été choisie :
    // si aucun nom de fichier ne figure dans l'url
    if (! url [1])
        // mettre le nom du fichier d'accueil
        strcpy (url, "cookies.htm");
Une fois que c'est fait, un peut récupérer la valeur des 3 cookies :
    // récupérer la valeur des cookies, mettre un ? s'il n'y en a pas
    if (! lecval_cookie ("hauteur", cookies, valhaut))
        strcpy (valhaut, "?");

    if (! lecval_cookie ("largeur", cookies, vallarg))
        strcpy (vallarg, "?");

    if (! lecval_cookie ("secondes", cookies, valtime))
        strcpy (valtime, "?");
La fonction lecval_cookie (...) utilise les mêmes types de paramètres que les fonctions lecvar_get (...) et lecvar_post (...) vues précédemment :
  1. Le nom du cookie dont on veut récupérer la valeur.
  2. La variable contenant la liste des cookies avec leurs valeurs.
  3. La variable qui va stocker la valeur trouvée.
La première fois que le serveur envoie la page, les cookies n'existent pas encore. C'est lorsque le navigateur web affiche la pages qu'ils sont créés.

Pour traiter ce cas, on teste le code de retour de la fonction lecval_cookie (...) et on initialise la variable contenant le résultat de la lecture avec "?" si le cookie n'a pas été trouvé.

Remarque : De la même manière, dans le programme getpost il aurait été possible de tester le code de retour des fonctions lecvar_get (...) et lecvar_post (...), mais comme on fait le même traitement pour les 2 modes de transmission des données du formulaire, un test commun est réalisé un peu plus tard.

Maintenant qu'on a récupéré ou initialisé la valeur des 3 cookies, on peut afficher le contenu de la page web.

Pour les 3 premiers affichages, le traitement est très simple :
    // afficher jusqu'à la taille de la fenêtre vue des cookies
    coprep_chaine (descfic, client, "XXXLARG", vallarg);
    coprep_chaine (descfic, client, "XXXHAUT", valhaut);

    // puis l'heure locale du client vue du cookie
    coprep_chaine (descfic, client, "XXXTIME", valtime);
Toutes les lignes du début du fichier HTML sont envoyées sans modification jusqu'à ce qu'on trouve dans une ligne la chaine de caractères XXXLARG qui est remplacée par la valeur du premier cookie.

Ensuite, à partir de la ligne suivante du chier HTML, on procède de même pour remplacer XXXHAUT et XXXXTIME par d'autres valeurs de cookies.

Pour le dernier affichage, on doit convertir la valeur valtime qui correspond au nombre de secondes écoulées depuis la création de l'univers (ou en tout cas, depuis l'origine des temps sur le système d'exploitation UNIX et ses dérivés comme GNU/linux), c'est à dire depuis le 1er janvier 1970 à 0 heures UTC, en une heure locale compréhensible pour des humains.
    // extraire l'heure locale
    timesec = atol (valtime);
    hloc = (timesec + 3600) % 86400;
    heure = hloc / 3600;
    min = (hloc / 60) % 60;
    sec = hloc % 60;

    // mise en forme
    sprintf (heure_aff, "%2d:%02d:%02d", heure, min, sec);
Le calcul est simplifié : on considère que l'heure est calculée de la même façon tout au long de l'année, ce qui devrait être bientôt le cas en europe. Le calcul est fait pour le fuseau horaire UTC + 1.
Pour les pays qui ont un fuseau horaire différent, il suffit de changer la valeur à rajouter ou à enlever à timesec (la plupart du temps un multiple de 3600).

On peut maintenant compléter la page web avec l'heure locale :
    // afficher l'heure locale vue du cookie
    coprep_chaine (descfic, client, "XXXHLOC", heure_aff);
Il ne reste plus qu'à envoyer la fin de la page web au navigateur :
    // envoi de la page ou de la fin de page
    copie_jusque_fin (descfic, client);
Remarque : Il sera intéressant d'afficher plusieurs fois la page en utilisant le lien Relancer. On pourra faire varier la taille de la fenêtre du navigateur entre 2 affichages.

On pourra constater que les données envoyées par le serveur à partir des cookies ont un affichage de retard par rapport à celles affichées en temps réel à partir du code javascript exécuté par le navigateur.