17. Listes de diffusion¶
17.1. Ce sous-système est une réimplémentation de GNU Mailman 3¶
Avant toute chose, et avant le premier exemple de configuration, la dette doit être énoncée clairement, car elle est grande.
Le sous-système de listes de diffusion de Pepsi est une réimplémentation de GNU Mailman 3. Son modèle de données, son architecture rule/chain et handler/pipeline, son API REST, son vocabulaire de commandes par e-mail et les noms de ses modèles de notification sont la conception du projet GNU Mailman et non la nôtre. Le projet GNU Mailman et la Free Software Foundation détiennent les droits sur l’original. Pepsi existe pour être compatible avec lui : un mailmanclient, un Postorius ou un HyperKitty non modifié doit pouvoir piloter cette implémentation, ce qui est le test d’acceptation autour duquel toute la conception est bâtie.
La documentation d’amont, à l’adresse <https://docs.mailman3.org>, décrit des notions qui s’appliquent directement à l’implémentation de Pepsi et mérite d’être lue en parallèle de ce manuel. Là où ce chapitre dit « l’action hold » ou « le modèle list:user:notice:welcome », il veut dire exactement ce que Mailman veut dire.
Certains fichiers de Pepsi n’ont pas été écrits par nous du tout. Les modèles de notification, les explications des réglages et un certain nombre de jeux de test viennent de GNU Mailman, Postorius et HyperKitty ; ils portent leurs mentions d’origine de droits et de licence, ils demeurent sous la GNU General Public License version 3 ou ultérieure, et ils sont recensés dans vendor/PEPSI-VENDORING.md. L’article 13 de la GPL version 3 autorise à combiner une telle œuvre avec l’AGPLv3+ de Pepsi ; il n’autorise rien quant à un changement de licence, et Pepsi n’en a pas fait. COPYING dit la même chose à qui vérifie les licences plutôt que de lire le manuel.
Pourquoi réutiliser ce texte au lieu d’écrire le nôtre : ces notifications ont été lues, critiquées et corrigées par de vrais membres de listes pendant deux décennies, en trente-quatre langues. Les réécrire de zéro aurait représenté des semaines de travail dont le meilleur résultat possible aurait été de revenir là où amont est déjà, en moins de langues.
17.2. Ce qu’est une liste¶
Une liste de diffusion appartient à un domaine et se désigne de deux façons, qui ne sont pas interchangeables :
- name
@domain L”adresse d’envoi, celle que les gens saisissent et qui apparaît dans le
To:.- name
.domain L”identifiant de liste, avec un point. C’est ce que l’API REST emploie comme identifiant de ressource.
pepsi-list accepte les deux graphies partout où une liste est nommée. La distinction compte lorsqu’on parle directement à l’API, et elle vient d’amont.
Chaque liste répond à neuf adresses : l’adresse d’envoi elle-même et huit sous-adresses – -request, -join, -leave, -subscribe, -unsubscribe, -owner, -bounces et -confirm+token. Contrairement à GNU Mailman, Pepsi ne produit aucun fichier d’alias. Mailman doit écrire des tables d’alias et de transport Postfix ou Exim pour ces neuf adresses de chaque liste et demander au MTA de recharger ; Pepsi route sur le destinataire à l’intérieur de son propre pipeline, il n’y a donc rien à régénérer, rien à recharger et rien qui puisse se désynchroniser.
17.3. Comment le sous-système est agencé¶
Cinq étapes, deux bibliothèques et trois surfaces. Tout le reste de ce chapitre est un détail de l’un d’eux.
inbound mail
|
v
+------------------+ not a list +----------------------------+
| pepsi-stage-list | -------------> | the rest of your pipeline |
+------------------+ +----------------------------+
| | |
post | -owner | -bounces|
| -join | |
| etc. | |
v v v
+----------+ +---------+ +--------+
| ...-post | | command | | bounce |
+----------+ +---------+ +--------+
| | |
| one row \ | scores, disables,
| per member \ | warns, unsubscribes
v v v
+-------------+ +------------------------+
| ...-deliver | | replies, notices and |
+-------------+ | probes, injected at |
| | RESPONSE/NOTICE_STAGE |
v +------------------------+
pepsi-stage-dkim-sign -> relay -> the member
|
+--> the archive (pepsi-archive), and the digest accumulator
Les cinq étapes. pepsi-stage-list route ; c’est la seule qui s’exécute sur chaque message. pepsi-stage-list-post modère un message de liste et l’éclate en un enregistrement par membre. pepsi-stage-list-deliver fait de l’un de ces enregistrements la copie de ce membre. pepsi-stage-list-command répond à tout ce qu’une liste fait par courrier et qui n’est pas un message de liste. pepsi-stage-list-bounce consomme les échecs qui reviennent.
Les deux bibliothèques. pepsi-list détient le modèle de liste, la table des attributs, les décisions de modération, le constructeur de résumés et les importeurs – et c’est ce que la ligne de commande pepsi-list, l’API REST et la console du propriétaire appellent toutes, de sorte que les trois surfaces ne peuvent pas être en désaccord sur le sens d’un réglage. pepsi-archive détient les archives : stockage, constitution des fils, recherche, export, import et suppression, derrière la ligne de commande pepsi-archive.
Les trois surfaces, chacune sur un drapeau de listener propre, sont la raison pour laquelle un unique nom d’hôte n’est pas une unique frontière de confiance :
Surface |
Drapeau de listener |
À qui elle est destinée |
|---|---|---|
|
|
l”exploitant – |
|
|
des programmes – |
|
|
les propriétaires de listes, les modérateurs et les membres – |
17.3.1. Trois identités, et les mots pour les désigner¶
Le chapitre emploie ces trois mots exactement dans ces sens, et l’interface, les notifications et les pages de manuel aussi.
- Exploitant
Celui qui fait tourner l’installation Pepsi. Détient un
pepsi.admin_account, atteint/uiet/api/v1, éditepepsi.confet peut tout faire sur n’importe quelle liste. Il n’y a pas d’exploitant par liste.- Propriétaire de liste (et modérateur)
Celui qui administre une liste. Détient un compte
list_useret un enregistrementlist_memberavecrole = owneroumoderator– l’autorité est une interrogation de la liste des membres et non une permission accordée, ce qui est le modèle de Postorius et signifie qu’ajouter un propriétaire consiste à l’abonner. Un propriétaire change les réglages d’une liste ; un modérateur décide de ses messages retenus.- Membre
Un abonnement, non une personne : une adresse sur la liste des membres d’une liste. Quelqu’un ayant deux adresses sur une liste fait deux membres, avec deux modes de remise, deux scores de bounce et deux URI de désabonnement. Le mot abonné a le même sens dans la prose ; membre est ce que l’API, l’interface et ce manuel emploient dans les parties de référence.
Un propriétaire de liste n’est pas un exploitant Pepsi, et les deux systèmes de comptes ne se rencontrent jamais ; voir Two account systems ci-dessous, et Deux systèmes de comptes, et aucun n’accorde rien à l’autre pour les tables, les cookies et le nom d’hôte unique qui peut les confondre.
17.3.2. Où aller ensuite¶
Faire tourner une liste, ses réglages et ses résumés – le reste de ce chapitre.
Migrer depuis GNU Mailman 2.1 ou 3 – Installation, puis What a migration does not bring.
Piloter Pepsi avec les clients d’amont eux-mêmes – L’API REST de GNU Mailman 3.
Les archives, leur recherche et leur suppression – Archives.
Les surfaces de navigation – La console d’administration.
Les normes en jeu – Index des RFC, qui rassemble en un seul endroit les RFC 2369, 5064, 1153, 3464 et 8058.
17.4. Pour commencer¶
Enregistrer un domaine, créer une liste, lui donner un propriétaire :
# pepsi-list domain add lists.example.org --base-url https://lists.example.org
added list domain lists.example.org
# pepsi-list list create announce@lists.example.org --style announce-only
created announce@lists.example.org with style legacy-announce
# pepsi-list owner add announce@lists.example.org alice@example.org
alice@example.org is now an owner of announce@lists.example.org
# pepsi-list owner reset-password announce@lists.example.org alice@example.org
password for alice@example.org: xzfkh-9gehq-r7y57-6np8r
(printed rather than mailed: this path has to work when mail is broken)
# pepsi-list check
note: site: archive search: full text and trigram (substring, fuzzy)
1 finding, none fatal
Deux avertissements au sujet de cette transcription.
Le domaine doit aussi être un domaine pour lequel Pepsi accepte du courrier. pepsi-list domain add enregistre un domaine pour les listes ; [pepsi-ingress] ACCEPTED_DOMAINS décide ce que le serveur accepte au RCPT. Une liste dans un domaine qu’ingress n’accepte pas est refusée à la frontière SMTP, et rien dans les journaux du sous-système de listes ne la mentionne, parce que le message ne l’a jamais atteint.
``members add`` contourne la politique d’abonnement. C’est à cela qu’un outil en ligne de commande sert – migrer un effectif, corriger une erreur – et c’est aussi la seule chose de ce sous-système qui puisse transformer une liste de diffusion en canon à spam. Le flux de confirmation existe pour qu’une adresse prouve qu’elle veut être là ; les seuls chemins qui le sautent sont cette commande et un appel explicitement pre_verified + pre_confirmed émis par un client REST authentifié.
17.5. Styles¶
Un style est un ensemble nommé de valeurs d’attributs par défaut, appliqué à la création d’une liste. GET /3.0/lists/styles en rapporte trois, qui sont ceux d’amont, avec les noms, les descriptions et la valeur par défaut d’amont :
Nom |
Également accepté comme |
Ce qu’il est |
|---|---|---|
|
|
Liste de discussion ordinaire. Le style par défaut. |
|
|
Annonces seulement : les membres ne peuvent pas écrire. |
|
|
Liste de discussion à archives privées ; non annoncée, et les abonnements exigent à la fois une confirmation et un modérateur. |
Un style de plus est propre à Pepsi. Il est accepté par pepsi-list et par la console du propriétaire, et n’est pas listé par REST :
moderatedUne liste de discussion sur laquelle chaque message de membre est retenu pour un modérateur.
Un nom de style inconnu est une erreur. Le create_list d’amont n’applique silencieusement aucun style lorsqu’il ne reconnaît pas un nom, ce qui laisse une liste dont tous les attributs valent le défaut de colonne, sans que rien ne soit dit nulle part ; le script de provisionnement d’un site en migration peut échouer ainsi pendant des mois.
17.6. Réglages par liste¶
Une liste porte les 99 attributs que GNU Mailman 3.3.10 expose par REST. pepsi-list list show les affiche ; --explain ajoute une ligne de prose pour chacun :
$ pepsi-list list show announce@lists.example.org | head -6
accept_these_nonmembers
acceptable_aliases
admin_immed_notify yes
admin_notify_mchanges no
administrivia yes
advertised yes
Dix-sept d’entre eux sont en lecture seule, dont les huit adresses dérivées (posting_address, owner_address, bounces_address et les autres), calculées depuis l’identité de la liste et jamais stockées – une seconde copie de l’identité d’une liste est un second endroit où elle peut être fausse.
Six autres, les attributs de modèle *_uri, n’existent que dans la version 3.0 de l’API ; la version 3.1 les atteint par le gestionnaire de modèles. list show signale les deux catégories.
Avertissement
``unsubscription_policy`` ne gouverne pas le lien de désabonnement en un clic. Lorsque [pepsi-list] BASE_URL et UNSUBSCRIBE_SECRET sont tous deux définis, chaque message que Pepsi envoie à une liste porte un en-tête List-Unsubscribe-Post (RFC 8058), et le bouton « se désabonner » d’un fournisseur de boîtes appelle cette cible par un unique POST. Un jeton valide retire le membre immédiatement, quoi que dise cet attribut — y compris moderate et confirm.
C’est délibéré et ce n’est pas une lacune. La RFC 8058 n’autorise aucune interaction supplémentaire : un fournisseur qui reçoit une redirection, une page de confirmation ou un « votre demande attend une approbation » ne peut rien en faire, et beaucoup marqueront simplement le courrier comme spam. Un en-tête qui promet un clic et ne l’honore pas est pire que pas d’en-tête.
La politique gouverne toujours tout ce qu’une personne fait : l’adresse -leave, le formulaire de désabonnement sur la page de la liste et le DELETE REST. Si une liste doit vraiment modérer chaque départ, la réponse est de cesser d’émettre l’en-tête — laissez [pepsi-list] UNSUBSCRIBE_SECRET non défini et aucune forme https: n’est émise — et d’accepter que la liste paraisse moins bonne à tout fournisseur de boîtes qui vérifie.
17.6.1. Trois réglages dont on demande plus souvent des nouvelles que des quatre-vingt-seize autres¶
advertisedSi la liste paraît dans l’index public. Ce n’est pas un réglage de confidentialité : une liste non annoncée reste joignable à sa propre URL, accepte toujours des messages, et ses archives sont gouvernées par
archive_policyet non par ceci. C’est le sens d’amont et le changer serait une rupture de compatibilité. « Non annoncée » se lit comme « cachée » ; cela veut dire « pas au catalogue ».archive_policynever,privateoupublic.neverne stocke rien – les archives ne sont pas écrites, il n’y a donc rien à rendre public plus tard.privatestocke les messages et refuse les lecteurs anonymes : les URL d’archives répondent comme si la liste n’existait pas, car un « interdit » confirmerait qu’elle existe.publicest public pour l’internet, moteurs de recherche compris, et/robots.txtleur demande d’indexer les archives et de laisser le point de recherche tranquille.member_roster_visibilityQui peut voir qui est abonné :
public,membersoumoderators. La page de la liste n’affiche la liste des membres que pourpublic. C’est l’attribut auquel recourir quand quelqu’un dit « non annoncée » et veut dire « les abonnés ne doivent pas former un répertoire public de ceux qui correspondent avec nous ».
Les quatre-vingt-dix-neuf figurent sur onze écrans de la console du propriétaire, dans le regroupement de Postorius, et les écrans sont générés depuis la même déclaration qui pilote list show et l’API REST – une valeur que la console refuse est refusée par les deux autres, dans les mêmes termes. Deux systèmes de comptes, et aucun n’accorde rien à l’autre en fait le tour.
17.6.2. Les réglages que Pepsi a inventés¶
pepsi-list list set-ext gère un second ensemble, bien plus petit, de réglages par liste que Pepsi a ajoutés et que l’API REST ne montre jamais :
search_trigramoff,shortoufull– jusqu’où va l’index de recherche par sous-chaîne et approchée de cette liste. Borné par le plafondSEARCH_TRIGRAMdu serveur.archive_show_addressesMontrer aux lecteurs anonymes des archives publiques de cette liste les adresses e-mail complètes des auteurs. Désactivé par défaut.
archive_retention_daysSupprimer les messages archivés plus anciens que cela. Absent signifie le défaut du serveur.
Ils sont invisibles pour REST à dessein, et ce n’est pas un choix de style. Le PUT /3.0/lists/<id>/config d’amont, qui porte sur la ressource entière, exige que chaque attribut modifiable soit présent dans la requête. Un client bâti contre Mailman 3.3.10 ignore tout ce que Pepsi a ajouté : il omettrait les nôtres et serait rejeté – un seul attribut inventé casserait chacun de ces PUT depuis chaque client existant. Les réglages propres à Pepsi vivent donc entièrement hors de l’ensemble des attributs, joignables depuis la ligne de commande et la console du propriétaire, et depuis nul endroit qu’un client Mailman puisse voir.
17.7. Configuration¶
La configuration par liste réside dans la base. pepsi.conf ne contient que ce que l”exploitant possède :
[pepsi-list]
SITE_OWNER = postmaster@example.org
BASE_URL = https://lists.example.org
API_USER = restadmin
API_PASS = a long random string
SEARCH_TRIGRAM = short
ARCHIVE_PARTITIONS = 32
NOTICE_STAGE = dkim-sign
Voir pepsi.conf(5) pour l’ensemble complet. Trois de ces options méritent une note ici.
NOTICE_STAGE est l’endroit où les passes périodiques déposent leur courrier. La plupart des notifications sont envoyées par une étape, qui a son propre RESPONSE_STAGE ; les passes de rejet qui avertissent puis retirent sont exécutées par une minuterie, qui n’en a pas. Sans cette option, ces passes peuvent changer l’état d’un membre sans pouvoir le lui dire : pepsi-setup refuse donc une configuration qui traite les rejets sans elle.
ARCHIVE_PARTITIONS est fixé à l’installation. Les archives sont partitionnées par hachage sur la liste, et PostgreSQL ne sait pas repartitionner à chaud : changer le module implique une nouvelle table et une copie complète de chaque message archivé. pepsi-setup crée les partitions une fois et refuse ensuite de les changer en silence, et pepsi-list check signale une configuration qui contredit ce qui est sur le disque. Choisissez une fois. Trente-deux est confortablement au-delà du point où autre chose devient le goulot d’étranglement.
SEARCH_TRIGRAM est un plafond, non un défaut. Chaque liste choisit off, short ou full jusqu’à lui. Abaisser la valeur du serveur réduit donc l’index à la prochaine réindexation, au lieu de ne toucher que les listes créées ensuite.
17.8. La recherche de sous-chaîne est optionnelle¶
La recherche d’archives de Pepsi emploie deux mécanismes de PostgreSQL, et ils répondent à des questions différentes. La recherche plein texte – racinisation, classement, extraits – répond à « trouve-moi le fil sur les certificats ». La recherche par trigrammes, de l’extension pg_trgm, répond à ce que le plein texte fait mal : une sous-chaîne, une faute d’orthographe, un nom d’hôte, une clé de configuration, une ligne de trace d’exécution. Sur une liste technique, cela représente une grande part de ce que les gens cherchent réellement, et un dictionnaire de racinisation jette exactement cette matière.
pg_trgm est livré dans postgresql-contrib, que les images de conteneurs minimales omettent souvent. Un site sans elle s’installe quand même et fonctionne quand même ; il n’a simplement que la recherche plein texte. pepsi-list check indique dans quel mode le site se trouve :
$ pepsi-list check
warning: site: archive search: full text only -- pg_trgm is not installed,
so substring and fuzzy search are unavailable
install postgresql-contrib and re-run pepsi-setup; the archive then
needs `pepsi-archive reindex` to populate trgm_text
17.9. Deux systèmes de comptes¶
Les propriétaires de listes ne sont pas des exploitants Pepsi, et les deux identités ne se rencontrent jamais.
pepsi.admin_account et la console /ui appartiennent à l”exploitant du serveur, et le manuel dit de les lier à la boucle locale et de les atteindre par un tunnel SSH. Les propriétaires de listes ne peuvent évidemment pas travailler ainsi. La console du propriétaire réside donc sur le listener public et tire son autorité de la liste des membres – un enregistrement de list_member avec role = owner ou moderator –, ce qui est précisément le modèle de Postorius, où l’autorisation est une interrogation de la liste des membres et non une permission accordée.
Deux systèmes de comptes, à dessein, avec des tables distinctes, des cookies de session distincts et des empreintes de mots de passe distinctes, et aucun n’accorde rien à l’autre. Une session de membre ne peut jamais satisfaire un garde administratif, dans aucun des deux sens. Cela compte plus qu’il n’y paraît : les cookies sont liés à l’hôte et non au listener, un exploitant qui sert les deux surfaces depuis un même nom d’hôte ne s’appuie donc que sur les noms de cookies et les contrôles du garde.
Deux systèmes de comptes, et aucun n’accorde rien à l’autre met les deux côte à côte, nomme les tables et les cookies, et dit ce qui arrive si vous servez les deux depuis un même nom d’hôte. Un propriétaire qui cherche ce qu’il peut réellement faire voudra la description de la console dans ce même chapitre.
17.10. Traitement des rejets¶
Une liste de diffusion écrit à des adresses qui cessent de fonctionner, et il faut bien que quelqu’un le remarque. La réponse de Pepsi est celle de GNU Mailman 3, pas à pas, parce que chaque réglage y est visible par l’API REST et que la documentation d’un site doit continuer d’être vraie.
La forme générale : un échec de remise revient à l’adresse -bounces de la liste, il est attribué au membre qu’il concerne, le score de bounce de ce membre monte d’au plus un par jour civil, et lorsque le score atteint le seuil de la liste sa remise est désactivée. Être désactivé n’est pas être désabonné – un membre désactivé est averti quelques fois au cours des semaines suivantes, et seulement ensuite retiré.
17.10.1. L’attribution n’est pas de la devinette¶
Chaque copie de chaque message que Pepsi envoie porte un expéditeur d’enveloppe nommant le membre auquel elle est destinée : announce-bounces+alice=example.net@lists.example.org. Un rejet de cette copie dit donc de qui il s’agit sans que rien ait à lire le rejet lui-même. Mailman ne peut le faire que si un exploitant active VERP ; l’éclatement de Pepsi se fait toujours par destinataire, il n’est donc jamais désactivé. Le + est le [pepsi] RECIPIENT_DELIMITER du site — l’unique option avec laquelle l’éclatement écrit et selon laquelle le routeur découpe, de sorte que les deux ne peuvent pas diverger.
Cela compte pour une raison pratique. Les dix-sept détecteurs heuristiques de rejet d’amont – un normalisé (RFC 3464) et seize qui nomment un éditeur ou un site – existent parce que l’attribution par l’enveloppe n’était pas disponible. Pepsi porte les dix-sept (ce sont ceux de flufl.bounce, Apache-2.0, avec leurs propres jeux de test), mais ils ne lisent jamais qu’un rejet arrivé par un autre chemin. La fréquence de ce cas est comptée dans pepsi.event_log sous list.bounce.unrecognized, et ce décompte est la réponse honnête à « ce site a-t-il besoin de détecteurs supplémentaires ».
Un rejet que rien ne reconnaît atteint un humain, avec l’original joint tel quel, à moins que le forward_unrecognized_bounces_to de la liste ne dise discard. Ce transfert est délibéré : l’échantillon est le seul moyen pour que le détecteur suivant soit écrit.
17.10.2. Les neuf attributs¶
Attribut |
Ce qu’il décide |
|---|---|
|
Si cette liste comptabilise les rejets du tout. Désactivé, ils sont abandonnés sans être lus. |
|
Combien de jours comptabilisés désactivent un membre (5 par défaut). |
|
Combien de temps un score survit sans nouveau rejet (7 jours par défaut). Passé ce délai, le rejet suivant repart à 1. |
|
Combien d’avertissements un membre désactivé reçoit avant son retrait (3 par défaut). Zéro signifie retrait sans aucun avertissement. |
|
Le délai entre ces avertissements (7 jours par défaut). |
|
Informer les propriétaires de chaque incrémentation (désactivé par défaut – sur une grande liste, cela fait beaucoup de courrier). |
|
Informer les propriétaires quand un membre est désactivé (activé par défaut). |
|
Informer les propriétaires quand un membre est retiré (activé par défaut). |
|
|
17.10.3. Un exemple travaillé¶
Une liste avec les valeurs par défaut, et une adresse qui a cessé d’accepter du courrier :
Jour 1 |
un échec permanent arrive. Score 1. Personne n’est informé. |
Jour 1 |
quatre autres échecs le même jour. Toujours score 1 – au plus une incrémentation par jour civil. |
Jours 2 à 4 |
un échec chaque jour. Score 4. |
Jour 5 |
un de plus. Score 5 = le seuil : la remise est désactivée et les propriétaires sont informés, avec la notification d’état de remise déclenchante en pièce jointe. |
Jour 5 |
le membre reçoit un avertissement indiquant que son abonnement a été désactivé et pourquoi. Avertissements envoyés : 1. |
Jour 12 |
avertissement 2. |
Jour 19 |
avertissement 3. |
Jour 26 |
les avertissements sont épuisés et l’intervalle s’est encore écoulé : le membre est désabonné et les propriétaires sont informés. |
Une adresse qui meurt met donc environ quatre semaines à quitter la liste, et un mauvais après-midi chez un fournisseur coûte un point. Une tempête de rejets – mille échecs en une heure – coûte elle aussi exactement un point.
Tout ce qui suit « désactivé » est fait par pepsi-list tasks --once, qu’une minuterie exécute chaque jour. Si rien ne l’exécute, les membres sont désactivés puis jamais avertis et jamais retirés.
17.10.4. Sondes¶
[pepsi-list] BOUNCE_PROBES = yes change ce que fait le franchissement du seuil : au lieu de désactiver le membre, Pepsi lui envoie un message portant un jeton à usage unique dans son expéditeur d’enveloppe et remet son score à zéro. Si ce message est rejeté, le jeton le nomme exactement et il est désactivé aussitôt. S’il ne l’est pas, tout allait bien et rien ne se passe.
C’est désactivé par défaut, comme en amont. Le compromis : un message de plus vers une adresse probablement morte, contre le fait de ne pas désactiver quelqu’un dont le fournisseur a eu un mauvais après-midi.
17.10.5. Ce qu’une migration n’apporte pas¶
Un site importé depuis Mailman démarre chaque membre au score zéro. L’importeur d’amont ne lit pas non plus l’historique des rejets, cela concorde donc – mais cela signifie qu’une adresse morte depuis longtemps reçoit une tentative de remise supplémentaire après la bascule.
17.11. Limitations connues¶
Le sous-système couvre le modèle de données et l’outil en ligne de commande, le chemin d’envoi avec sa chaîne de modération et son éclatement par membre, l’interface de commandes par e-mail, le traitement des rejets, les archives et leur recherche (Archives), l’API REST de GNU Mailman 3 (L’API REST de GNU Mailman 3), l’interface web publique, les comptes de membres et la console du propriétaire (La console d’administration), les importeurs (Installation) et les deux formats de résumé.
Ce qu’il ne fait pas : /plugins est toujours vide et il n’y a pas d’interface de greffons, il n’y a pas de passerelle NNTP (gateway_to_news est réglable et journalisé comme l’opération vide qu’il est), l’étiquetage des fils et les catégories manquent aux archives, et un message retenu rejeté est abandonné sans l’avis de rejet qu’amont envoie. Chacun de ces points est répété là où un lecteur le rencontrerait.
17.12. Résumés¶
Les deux formats, le multipart/digest MIME et la forme simple de la RFC 1153, parce qu’un client peut relire digest_is_default et mime_is_default_digest et qu’un membre peut demander plaintext_digests – livrer un format et accepter l’attribut de l’autre serait exactement le genre de mensonge discret que le contrat de compatibilité existe pour empêcher.
17.12.1. Comment un résumé s’accumule et comment il est envoyé¶
L’accumulation fait partie de la remise d’un message : quand digests_enabled est actif, le chemin d’envoi ajoute le message à un enregistrement par liste, dans la même transaction que tout le reste de ce que fait le message. Amont ajoute à un fichier de boîte MMDF sous verrou ; un enregistrement est l’un des endroits où une base de données est simplement meilleure.
L’enregistrement porte les messages eux-mêmes et non des références vers des archives. Une liste peut parfaitement avoir digests_enabled avec archive_policy = never – pepsi-list check fait même remarquer que les résumés sont alors le seul témoignage de ce qui a été envoyé – si bien qu’un résumé bâti sur des références d’archives serait vide précisément pour les listes qui en ont le plus besoin. digest_size_threshold borne ce qui s’accumule.
L’envoi a deux déclencheurs, et amont n’a aucun exécutant périodique : son maybe_send_digest_now se déclenche de façon synchrone sur un message dès que le seuil de taille est franchi, et mailman digests --send est censé être mis dans le cron de l’exploitant. Pepsi conserve les deux moitiés et place la seconde là où elle appartient :
taille –
digest_size_threshold, en kilo-octets (l’unité d’amont, que le nom de colonne ne dit pas). Zéro signifie que la taille ne déclenche jamais d’envoi : une liste peut donc être uniquement périodique.périodique –
pepsi-list digest periodicdepuis une minuterie systemd, en respectantdigest_send_periodicpar liste. Le même agencement quepepsi-list tasks, et la raison pour laquelle aucun service de résumés de longue durée n’est écrit.
pepsi-list digest send force une livraison sans égard au seuil, et digest bump fait avancer le volume sans envoyer – les deux drapeaux d’amont.
17.12.2. Numéro de volume et de livraison¶
digest_volume_frequency (yearly, monthly, quarterly, weekly, daily) décide si la période a avancé depuis digest_last_sent_at :
une liste qui n’a jamais envoyé de résumé garde son volume et son numéro courants, de sorte que la première livraison d’une liste est la livraison 1 et non la 2 ;
si la période a avancé, le volume s’incrémente et le numéro repart à 1 ;
si elle n’a pas avancé, le numéro s’incrémente.
C’est la période qui est comparée et non le temps écoulé, et c’est ce qui rend la réponse identique le 1er d’un mois et le 31 : deux messages séparés d’un jour à cheval sur une fin de mois sont dans des mois différents, et deux messages séparés de trente jours à l’intérieur d’un même mois ne le sont pas.
17.12.3. À quoi ressemblent les deux formats¶
Le résumé MIME est un multipart/mixed de cinq parties dans cet ordre : l’en-tête de tête (portant l’objet de la livraison comme Content-Description, ce qui rend un résumé lisible dans un client qui énumère les parties), l’en-tête, la table des matières, un multipart/digest interne dont les enfants sont les messages d’origine en message/rfc822, et le pied de page. Les parties d’en-tête et de pied sont omises lorsque leur modèle est vide – ce qu’est list:member:digest:header, en amont comme ici.
Le résumé RFC 1153 est un unique corps text/plain plat, et chaque décompte qu’il contient est porteur, parce que les lecteurs découpent les résumés sur ces lignes depuis 1990 : soixante-dix tirets une fois après la table des matières, trente avant chaque message sauf le premier, le pied de page en faux message supplémentaire avec son propre Subject: Digest Footer plutôt qu’en appendice, et une formule de fin suivie d’une ligne d’astérisques de même longueur.
La RFC 1153 est du texte brut : une pièce jointe ne peut donc pas y survivre. Chaque partie non textuelle devient donc un substitut nommant ce qui a été retiré – son nom de fichier, son type de média et sa taille – car un résumé simple qui laisserait silencieusement tomber un tableur laisserait un lecteur croire qu’il a vu tout le message. Un multipart/alternative livre son texte brut et ne dit rien de son jumeau HTML, puisque rien n’a été retiré.
17.12.4. Qui reçoit quoi¶
Les membres en résumé dont la remise est activée se répartissent selon delivery_mode : plaintext_digests reçoivent la livraison RFC 1153, et mime_digests ainsi que ``summary_digests`` reçoivent tous deux celle en MIME. Amont n’a pas de format de synthèse distinct et traite les deux à l’identique ; en inventer un signifierait qu’un membre peut demander un format qu’aucun autre Mailman ne produit.
Chaque format est bâti une fois et éclaté par destinataire, aux mêmes conditions que toute autre remise – un résumé porte aussi un List-Unsubscribe.
17.13. Différences déclarées avec GNU Mailman 3¶
Rassemblées en un seul endroit, parce qu’un exploitant qui compare les deux systèmes en a besoin en un seul endroit et qu’une conversation d’assistance a besoin de quelque chose à montrer. Chacune est une décision avec une raison, non un accident.
Différence |
Pourquoi |
|---|---|
Désabonnement en un clic (RFC 8058) |
Nous émettons |
L’éclatement se fait toujours par destinataire |
|
Les adresses d’expéditeur archivées sont obscurcies |
Pour les visiteurs anonymes, par défaut, avec une surcharge par liste. Ce n’est pas un contrôle de sécurité : ce qui est empêché, c’est la collecte en masse qui fait d’archives publiques une source de spam. Un membre connecté voit l’adresse entière. |
Une suppression laisse une pierre tombale de 90 jours |
Afin qu’une remise répétée ou un import rejoué ne ressuscite pas un message supprimé à dessein. |
``max_days_to_hold`` est respecté |
Il est inerte en amont : un grep de tout l’arbre hors tests de Mailman 3 trouve la colonne, la valeur par défaut du style et le validateur REST, et aucune tâche qui le lise. Ici, |
Un ``style_name`` inconnu est une erreur |
Le |
Les URI de substitution de modèles sont récupérées sous contraintes |
Un propriétaire de liste — et non l’exploitant — peut en poser une : une URI |
``archive_rendering_mode = markdown`` est stocké et non rendu |
L’attribut existe parce que l’ensemble des attributs est le contrat ; les deux valeurs s’affichent en texte. Rendre du markdown fourni par un utilisateur dans notre propre origine est ce que la Content-Security-Policy des pages doit rendre impossible. |
Aucun JavaScript, nulle part |
Sur aucune des deux surfaces de navigation. Le prix en est les parties interactives de HyperKitty ; le bénéfice, une politique entièrement dépourvue de |
``X-Mailman-*`` est renommé ``X-Pepsi-List-*`` |
Avec une table de correspondance, parce que les règles procmail et Sieve sont le coût réel pour un utilisateur qui migre. |
Pas de passerelle NNTP, pas d’archiveurs enfichables, pas d’API de greffons |
Les six attributs NNTP restent dans l’ensemble des attributs et sont inertes, et |
Les mots de passe, les scores de bounce et les jetons en cours ne sont pas migrés |
L’importeur d’amont ne les apporte pas non plus. Voir Migrer depuis GNU Mailman. |