IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Modules Perl Discussion :

Problème étrange avec Mail::Sender


Sujet :

Modules Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 605
    Par défaut Problème étrange avec Mail::Sender
    Bonjour,

    j'utilise depuis plus de 3 ans un script Perl sous Linux exploitant le package Mail::Sender pour l'envoi de mails groupés.

    Mon script jusqu'alors gère parfaitement les mails sans pièces jointes ou avec pièces jointes (zip, html).

    Dans la console, j'affiche pour chaque mail le calcul en secondes entre l'envoi du précédent mail et l'envoi du mail en cours. Dans le log (canal STDERR redirigé vers un fichier log), j'ai activé le mode DEBUG de Mail::Sender, lequel m'affiche tous les détails de l'envoi d'un mail (ID du mail, si le serveur SMTP a répondu OK, etc).

    Ce script d'envoi de mails fonctionne 2 fois par week end et envoie à chaque fois une cinquantaine de mails avec des fichiers zip en pièces jointes.

    Habituellement, il gère à peu près 2 envois de mails à la seconde sauf que cette fois, après en avoir envoyé une 15aine normalement, il a envoyé tous les autres en 1 seconde

    Bien entendu, les mails partis trop vite n'ont pas été reçus par les destinataires concernés.

    Le DEBUG de Mail::Sender ne dit strictement rien d'anormal, le contenu du log affiche des infos classiques.

    Mon log à moi (STDERR) ne dit rien d'anormal non plus.

    On dirait qu'il y a eu comme une sorte de time out à distance ???

    J'ai regardé les logs dans /var/logs, je n'ai rien vu d'anormal non plus.

    Quelqu'un a une idée ???

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 605
    Par défaut
    Avec Mail::Sender, il y a un moyen pour vérifier qu'on est bien en liaison avec le serveur SMTP distant (celui de mon provider).

    Le pire, c'est que je pensais que je testais cette instance (ref($Instance)) une seule fois au lancement du script. Mais non : l'instance est contrôlée avant chaque envoi de mail !!!

    Je ne comprend pas.

  3. #3
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 605
    Par défaut
    Voici ci-dessous le script Perl que j'utilise (et qui fonctionnait parfaitement jusqu'à hier matin) depuis plus de 3 ans.

    Pour schématiser un peu le processus :

    - le script utilise Mail::Sender pour l'envoi des mails (je crois qu'il utilise en interne sendmail)

    - le package PmOutils est un package perso contenant diverses fonctions existantes en Perl mais personnalisées (comme Die ou Warn)

    - les infos des mails à envoyer sont logées dans un fichier d'entrée nommé "mailto.txt". Le formatage d'un mail est fort simple :
    une ligne commence par TO: ? elle contient l'adresse mail
    une ligne commence par SUJET: ? le sujet d'un mail
    une ligne commence par MESSAGE: ? 1ère ligne du contenu du mail et toutes les lignes suivantes constituent la suite du mail (sauf si FICHIER: ou TO: rencontré de nouveau)
    une ligne commence par FICHIER: ? contient l'adresse en local du fichier à envoyer

    - le script lit au fur et à mesure le fichier d'entrée des mails puis, lorsqu'il a chargé en mémoire (dans le hash %Mail) la totalité d'un mail à envoyer, il passe la main à la fonction TraiteMail, laquelle utilisera la méthode de Mail::Sender adéquate pour l'envoi du mail (méthode MailFile si mail avec pièce jointe, méthode MailMsg pour les mails sans pièce jointe).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    # LIBRAIRIES
    use strict;
    use warnings;
    use Mail::Sender;
    use PmOutils;
     
    # VARIABLES GLOBALES
    my $SMTP = "mail.mon_provider.fr";
    my $FROM = 'user@mon_provider.fr';
    my $REPLYTO = $FROM;
    my $SIGNATURE;
    my $DEBUG = 0;
     
    # VARIABLES
    my $FicMailto = "mailto.txt";
    my $FicMailDebug = "MailDebug.log";
    my $Instance;
    my %Mail;
     
    # PROGRAMME PRINCIPAL
    # Récupération du paramètre fourni au programme
    if (! $ARGV[0] || $ARGV[0] !~ /^[on]$/i)
    {
    	print "Usage : Nom_du_programme <option1>\n\n";
    	print "\t<option1> o = mode DEBUG actif (mode verbose)\n";
    	print "\t          n = mode DEBUG inactif (pas de mode verbose)\n\n";
    	exit();
    }
    $DEBUG = ($ARGV[0] =~ /o/i ? 1 : 0);
     
    open(STDERR, ">log.log") or die();
     
    # On ouvre le fichier des mails en lecture et on crée la nouvelle instance
    open(MAILTO, "$FicMailto") or PmOutils::Die("Lecture de $FicMailto impossible : $!\n");
    if ($DEBUG)		# si mode DEBUG actif, on garde une trace des conversations avec serveur SMTP dans un log
    {
    	# création du log
    	open(DEBUG, ">>$FicMailDebug") or PmOutils::Die("Mise à jour de $FicMailDebug impossible : $!\n");
     
    	# création de l'instance avec mode verbose
    	$Instance = new Mail::Sender
    	{
    		smtp  => $SMTP,
    		from  => $FROM,
    		replyto	=> $REPLYTO,
    		debug => \*DEBUG
    	};
    }
    else
    {
    	# création de l'instance SANS mode verbose
    	$Instance = new Mail::Sender
    	{
    		smtp => $SMTP,
    		from => $FROM,
    		replyto	=> $REPLYTO,
    	};
    }
    if (! ref $Instance)	# si la connection distante a échoué
    {
    	PmOutils::Die("La connection au serveur $SMTP a échoué : $Mail::Sender::Error\n");
    }
     
    # On compose la signature à inclure automatiquement dans les mails
    $SIGNATURE = <<END_OF_SIGNATURE;
     
    -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
     
        E-mail : $REPLYTO
        Site   : mon site perso
        Forum  : mon forum
     
        Merci d'indiquer votre n° de compte joueur dans toute correspondance.
     
    -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
    END_OF_SIGNATURE
     
     
    # Traitement des mails à envoyer
    while(<MAILTO>)
    {
    	if (/^TO:(.+)\n$/)
    	{
    		if (%Mail)
    		{
    			if (! TraiteMail(%Mail))
    			{
    				PmOutils::Warn(1, "Le mail en cours n'a pu etre envoyé !\n");
    			}
    			%Mail = ();
    		}
    		@{$Mail{TO}} = split(/,/, $1);
    		PmOutils::Warn(0, "Nouveau mail destiné à : '", join("', '", @{$Mail{TO}}), "'\n");
    	}
    	elsif (/^SUJET:(.+)\n$/)
    	{
    		$Mail{SUJET} = $1;
    		print STDERR "\tsujet trouvé pour mail en cours ligne $.\n" if ($DEBUG);
    	}
    	elsif (/^MESSAGE:(.+)$/)
    	{
    		$Mail{MESSAGE} = $1;
    		print STDERR "\tdébut de message trouvé pour mail en cours ligne $.\n" if ($DEBUG);
    	}
    	elsif (/^FICHIER:(.+)\n*$/)
    	{
    		@{$Mail{FICHIER}} = split(/,/, $1);
    	}
    	else
    	{
    		# on vérifie que le mail en cours est constitué correctement avant de s'assurer que la ligne en cours
    		# corresponde à une ligne du message du mail
    		if ( ! defined(@{$Mail{TO}}) || ! $Mail{SUJET} || ! $Mail{MESSAGE} || defined(@{$Mail{FICHIER}}) )
    		{
    			PmOutils::Warn(1, "La ligne $. dans fichier $FicMailto ne semble appartenir à aucun mail !\n");
    		}
    		else	# il s'agit bien de la suite du message
    		{
    			$Mail{MESSAGE} .= "$_";
    			print STDERR "\tsuite du message trouvé pour mail en cours ligne $.\n" if ($DEBUG);
    		}
    	}
    }
    close(MAILTO);
     
    # S'il restait un mail à envoyer (le dernier)
    if (%Mail)		# on envoie le mail précédemment reconstitué (s'il existe)
    {
    	if (! TraiteMail(%Mail))
    	{
    		PmOutils::Warn(1, "Le mail en cours n'a pu etre envoyé !\n");
    	}
    }
     
    # Fin de traitement
    exit();
     
     
    sub TraiteMail
    {
    	my %NewMail = (@_);			# le mail à envoyer
    	my $Destinataire;			# destinataires du mail
    	my $TempsDebut = time();	# pour compter le temps de traitement d'envoi du mail
    	my $TempsFin;
     
    	# on vérifie que le mail soit bien complet
    	if ( ! defined(@{$NewMail{TO}}) || ! $NewMail{SUJET} || ! $NewMail{MESSAGE})
    	{
    		print STDERR "Pas de destinataires pour mail en cours !\n" if (! defined(@{$NewMail{TO}}));
    		print STDERR "Pas de sujet pour mail en cours !\n" if (! $NewMail{SUJET});
    		print STDERR "Pas de message pour mail en cours !\n" if (! $NewMail{MESSAGE});
    		return 0;
    	}
     
    	# composition de la liste des destinataires du mail
    	$Destinataire = join(",", @{$NewMail{TO}});
     
    	# ajout de la signature dans le message
    	$NewMail{MESSAGE} .= $SIGNATURE;
     
    	# on détermine la méthode à appliquer au mail en fonction des pièces jointes ou non
    	if (defined @{$NewMail{FICHIER}})
    	{
    		PmOutils::Warn(0, "\tNbre de pièces jointes : ", scalar(@{$NewMail{FICHIER}}), "\n");
    		# on applique la méthode MailFile ici
    		$Instance->MailFile(
    		{
    			to		=> $Destinataire,
    			subject => $NewMail{SUJET},
    			msg		=> $NewMail{MESSAGE},
    			file	=> \@{$NewMail{FICHIER}}
    		});
    		# on vérifie que le mail était bien ok
    		if (! ref $Instance)	# si la connection distante a échoué
    		{
    			PmOutils::Warn(0, "L'envoi du mail via méthode MailFile a échoué : $Mail::Sender::Error\n");
    			return 0;
    		}
    	}
    	else
    	{
    		PmOutils::Warn(0, "\tNbre de pièces jointes : 0\n");
    		# méthode MailMsg ici (pas de pièces jointes)
    		$Instance->MailMsg(
    		{
    			to		=> $Destinataire,
    			subject => $NewMail{SUJET},
    			msg		=> $NewMail{MESSAGE},
    		});
    		if (! ref $Instance)	# si la connection distante a échoué
    		{
    			PmOutils::Warn(0, "L'envoi du mail via méthode MailMsg a échoué : $Mail::Sender::Error\n");
    			return 0;
    		}		
    	}
     
    	# le mail a correctement été envoyé, on calcule le temps de l'envoi
    	$TempsFin = time();
    	PmOutils::Warn(0, "Mail envoyé en ", int($TempsFin - $TempsDebut + 0.5), " seconde(s)\n");
     
    	return 1;
    }
    Ce matin encore, ce script a rencontré des soucis pour envoyer à la queu-leu-leu 43 mails. Il a envoyé les 10 premiers environ sans encombre (environ 1 seconde normalement par envoi) puis a traité les 33 autres en un temps record mais sans qu'ils ne soient partis !

    J'ai été obligé de faire l'envoi total en 4 fois pour parvenir à mes fins.

    J'ai regardé les logs dans /var/spool et dans /var/logs et n'ai absolument rien trouvé d'anormal.

    Le mode DEBUG activé de Mail::Sender n'indique aucune anomalie lui non plus.

    En résumé : heu,

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 605
    Par défaut
    Personne n'a d'idée ?

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 605
    Par défaut
    Bon et sinon, une proposition comme ça : a priori, mon provider a mis en place un système anti-spams sur son serveur SMTP et il doit toper les 50 et qq mails que j'envoie à la suite comme du spam. Je ne vois que cette explication car sur mon PC, absolument rien n'a été changé ni modifié depuis des mois.

    Je mettrai bien en place un système qui, tous les 10 ou 15 mails environs :
    - fermerait la connection au serveur SMTP
    - p'tite pause de 2-3 secondes
    - réouverture de connection au SMTP distant
    - envoi des 15 mails suivants

    Je crains juste que le serveur SMTP trouve louche ces connexions/déconnexions successives.

    Qu'en pensez-vous ?

  6. #6
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Citation Envoyé par Arioch Voir le message
    Bon et sinon, une proposition comme ça : a priori, mon provider a mis en place un système anti-spams sur son serveur SMTP et il doit toper les 50 et qq mails que j'envoie à la suite comme du spam. Je ne vois que cette explication car sur mon PC, absolument rien n'a été changé ni modifié depuis des mois.

    Je mettrai bien en place un système qui, tous les 10 ou 15 mails environs :
    - fermerait la connection au serveur SMTP
    - p'tite pause de 2-3 secondes
    - réouverture de connection au SMTP distant
    - envoi des 15 mails suivants

    Je crains juste que le serveur SMTP trouve louche ces connexions/déconnexions successives.

    Qu'en pensez-vous ?
    J'en pense que ton explication est très probablement la bonne (surtout si ce script a fonctionné pendant longtemps), peut-être devrais tu faire des pauses un peu plus longues (avec un petit peu d'aléatoire peut-être, ça m'étonnerait que ça change quelque chose mais on sait jamais).

    --
    Jedaï

  7. #7
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 605
    Par défaut
    Citation Envoyé par Jedai Voir le message
    J'en pense que ton explication est très probablement la bonne (surtout si ce script a fonctionné pendant longtemps), peut-être devrais tu faire des pauses un peu plus longues (avec un petit peu d'aléatoire peut-être, ça m'étonnerait que ça change quelque chose mais on sait jamais).

    --
    Jedaï
    Faire des pauses de combien à ton avis ?

    Ce soir, j'ai modifié mon script et désormais, celui-ci envoie les mails par groupe de 15, puis ferme la connexion distante, attend 2 secondes, se reconnecte, envoie les mails suivants.

    10 secondes ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/03/2008, 18h38
  2. [Mail] Problème étrange avec PHP en ligne de commande
    Par jojosbiz dans le forum Langage
    Réponses: 3
    Dernier message: 21/05/2007, 14h04
  3. Problème étrange avec DecimalSeparator ?
    Par MaTHieU_ dans le forum Delphi
    Réponses: 2
    Dernier message: 13/07/2006, 09h14
  4. problème étrange avec excel
    Par lanfeust42 dans le forum Modules
    Réponses: 1
    Dernier message: 15/06/2006, 10h57
  5. [FLASH MX2004 PRO] Problème étrange avec LoadClip...
    Par josemoroide dans le forum Flash
    Réponses: 6
    Dernier message: 04/08/2004, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo