Blog technique sur mes expériences de développeur.
9 août 2022
Vous le savez déjà, il existe deux protocoles pour consulter les e-mails présents sur un serveur : POP3 et IMAP.
Je vous propose de commencer par le protocole POP3, et de garder le protocole IMAP pour le prochain chapitre.
Une nouvelle fois, nous allons utiliser un module issu de la bibliothèque libnet : Net::POP3.
Au cours ce chapitre, il sera question de référence. Si vous n’êtes pas à l’aise avec les références, n’hésitez pas à jeter un coup d’œil à l’annexe de ce tutoriel !
Ce cours était originalement publié sur la plateforme OpenClassrooms. La plateforme OpenClassrooms ayant supprimée ce tutoriel en 2020 et le tutoriel étant sous licence CC BY-SA 4.0, je vous propose de le (re)découvrir ici.
Tout comme pour l’envoi d’un e-mail, la consultation de son courrier nécessite un travail ordonné. Une nouvelle fois, je vous propose de découper ce travail en quelques étapes. Elles sont au nombre de 4 :
Afin d’implémenter ces 4 étapes, nous allons utiliser le module Net::POP3. Ce module va nous permettre en fait de faire l’intermédiaire entre notre programme et le serveur avec lequel nous souhaitons communiquer.
Je vous propose de regarder immédiatement les quelques méthodes et fonctions qui nous serviront par la suite.
new()
: instancier un objetTout comme pour le module Net::SMTP, le module Net::POP3 est un module orienté objet. Cette méthode est donc le constructeur de la classe Net::POP3.
Si la Programmation Orienté Objet ne vous parle vraiment pas, je vous conseille de jeter un œil sur un des tutoriels de M@téo21 expliquant simplement le principe des objets et la POO de manière générale.
Cette méthode peut prendre plusieurs paramètres comme par exemple :
login()
: s’identifierCette fonction permet de s’identifier auprès du serveur auquel on souhaite se connecter. Elle prend généralement 2 paramètres à savoir le nom d’utilisateur et un mot de passe. Si l’authentification se passe bien, cette méthode retourne le nombre de messages présents dans la boite de réception.
Cette méthode envoie les informations (login et mot de passe) en clair sur le réseau !
apop()
: s’identifier de manière sécuriséeTout comme la méthode login()
, apop()
permet de s’identifier auprès du serveur auquel on souhaite se connecter, à ceci près qu’elle hache le mot de passe grâce à l’algorithme MD5. La conséquence est donc que vos identifiants ne sont pas envoyés en clair sur réseau, et permet de sécuriser un minimum le protocole.
L’utilisation de cette méthode nécessite d’inclure le moduleDigest::MD5dans vos scripts.
list()
: lister les messagesSans argument, cette méthode renvoie une référence à une table de hachage dont les clefs sont les numéros des messages sur le serveur et les valeurs représentent la taille en octets du message.
Appelée avec un numéro de message en argument, cette méthode renvoie la taille du message en octets.
top()
: obtenir l’en-tête d’un messageCette méthode permet de récupérer l’en-tête du message dont le numéro est passé en paramètre.
Grâce à cette fonction, il est également possible de récupérer les premières lignes d’un message. Pour ce faire, il suffit d’ajouter un second paramètre correspondant au nombre de ligne que l’on souhaite récupérer.
Quelque soit le nombre de paramètre, cette méthode renvoie le texte demandé sous la forme d’une référence à un tableau.
get()
: obtenir le contenu d’un messageCette méthode permet de récupérer le texte (en-tête et corps) du message dont le numéro est passé en paramètre. Le texte est alors retourné sous la forme d’une référence à un tableau.
Il est également possible d’indiquer un second paramètre correspondant à un descripteur de fichier. Dans ce cas, les lignes seront directement écrites dans le fichier.
delete()
: supprimer un messageCette méthode permet de marquer le message dont le numéro est passé en paramètre comme étant à effacer. La suppression des messages marqués s’effectue seulement si la connexion avec le serveur est fermée proprement.
reset()
: remettre le serveur en étatCette méthode permet de remettre le serveur dans l’état où il se trouvait au moment de notre connexion. Cette méthode est très utile si l’on veut supprimer les marqueurs de suppressions attribués à certains messages via la méthode delete()
. Cette fonction ne prend pas de paramètre.
quit()
: se déconnecter du serveurCette fonction permet de fermer proprement la connexion avec le serveur. Elle ne prend pas de paramètre.
Maintenant que vous avez fait connaissance avec le module Net::POP3, nous allons voir ensemble comment implémenter en Perl les 4 étapes décrites un plus haut.
Pour rappel, voici les 4 étapes que nous allons implémenter au cours de ce chapitre :
C’est parti !
La première étape consiste donc à indiquer à notre programme Perl l’adresse du serveur auquel on souhaite se connecter. Si vous vous souvenez bien, c’est la méthode new()
qui nous le permet. Pour rappel, voici quelques paramètres que peut prendre cette fonction :
Dans l’exemple suivant, nous allons nous connecter au serveur POP3 de Wanadoo.
#!/usr/bin/perl -w
use strict;
use Net::POP3;
#Étape 1
my $pop = Net::POP3->new('pop.wanadoo.fr') or die 'Impossible de se connecter au serveur : '.$!;
Comme à chaque fois, le or die
permet de gérer les éventuelles exceptions renvoyées par notre programme. La variable $!
nous indique la source exacte du problème.
Il est possible de faire passer d’autres paramètres à la méthode new()
comme par exemple le mode débogage ou un temps limite de connexion. Le passage de ces nouveaux paramètres se fait sous la forme d’un tableau associatif.
Voyons tout de suite un exemple dans lequel les paramètres de débug et de limitation de temps sont présents.
#!/usr/bin/perl -w
use strict;
use Net::POP3;
#Étape 1
my $pop = Net::POP3->new('pop.wanadoo.fr', Debug => 1, Timeout => 10) or die 'Impossible de se connecter au serveur : '.$!;
Par défaut, le mode débogage est désactivé. Le mettre à 1 permet donc son activation. Ainsi, il est possible d’afficher à l’écran le détail du dialogue qui s’opère entre le serveur et votre programme.
Le temps limite de connexion se donne en seconde. Ainsi, dans mon exemple, si au bout de 10 secondes le programme n’a pas réussi à se connecter au serveur, une exception sera levée, et la variable $!
contiendra le message “Connexion terminée par expiration du délai d’attente”.
Il existe 2 méthodes pour ce connecter. L’une étant théoriquement plus sécurisée que l’autre. Dans notre exemple, nous allons utiliser la façon la plus basique (et donc la moins sécurisée). Nous allons donc nous identifier grâce à la fonction login()
. Puisque cette méthode renvoie le nombre de messages présents dans la boite de réception, nous allons en profiter pour afficher l’information à l’écran.
#Étape 2
my $nbmsg = $pop->login('*****@wanadoo.fr', '*****') or die 'Erreur d\'identification !';
print 'Vous avez '.$nbmsg.' messages !';
Vous devriez alors obtenir quelque chose comme ça à l’écran :
> perl pop3.pl
Vous avez 125 messages !
C’est dans cette étape que vous allez pouvoir lire vos mails et pourquoi pas en supprimer certains du serveur.
Nous allons voir ici un exemple qui permet d’afficher à l’écran tous les e-mails que nous avons sur le serveur. Pour ça, nous allons dans un premier temps utiliser la méthode list()
afin d’obtenir l’identifiant de chacun des messages. Enfin, nous utiliserons la méthode get()
afin de récupérer le contenu du message (en-tête et corps) puis nous l’afficherons à l’écran. Pour afficher tous les messages, il conviendra de boucler sur les clefs contenues dans la table hachage renvoyée par la fonction list()
.
Pour rappel, la fonction list()
renvoie une référence vers une table de hachage, tandis que get()
renvoie une référence à un tableau !
#Étape 3
#On récupère la liste des messages
my $index = $pop->list() or die 'Impossible de lister les messages !';
#On affiche les messages
foreach my $msgnum (keys %$index) {
my $msg = $pop->get($msgnum) or die 'Impossible de récupérer le message n°'.$msgnum.' !';
print @$msg."\n\n";
}
Comme à chaque fois, j’essaye de rendre le code aussi clair que possible afin de ne pas rendre la syntaxe de Perl indigeste. Cependant, si vous êtes vraiment à l’aise, vous pouvez bien évidemment afficher le message directement en utilisant :
print @{$pop->get($msgnum)};
Nous voilà enfin à la dernière étape qui consiste à fermer proprement la connexion avec le serveur grâce à la méthode quit()
.
#Étape 4
$pop->quit() or die 'Un problème est survenu avec la méthode quit() !';
Voici le code complet de ce que nous avons vu ensemble sur la consultation d’un e-mail en Perl via le module Net::POP3 :
#!/usr/bin/perl -w
use strict;
use Net::POP3;
#Étape 1
my $pop = Net::POP3->new('pop.wanadoo.fr') or die 'Impossible de se connecter au serveur : '.$!;
#Étape 2
my $nbmsg = $pop->login('*****@wanadoo.fr', '*****') or die 'Erreur d\'identification !';
print 'Vous avez '.$nbmsg." messages !\n\n";
#Étape 3
my $index = $pop->list() or die 'Impossible de lister les messages !';
foreach my $msgnum (keys %$index) {
my $msg = $pop->get($msgnum) or die 'Impossible de récupérer le message n°'.$msgnum.' !';
print @$msg."\n\n";
}
#Étape 4
$pop->quit() or die 'Un problème est survenu avec la méthode quit() !';
La liste des méthodes données au cours de ce chapitre n’est évidemment pas une liste exhaustive ! S’il vous manque quelque chose, je vous encourage fortement à jeter un œil à la documentation officielle !
Maintenant que vous savez exploiter le protocole POP3 en Perl, je vous propose de faire une petite pause avec un TP !