Discussion:
Serveur INN
(trop ancien pour répondre)
unknown
2013-03-25 00:38:21 UTC
Permalink
J'arrête pas d'essayer des combinaisons, tu arrives à obtenir un truc
qui marche sur ton serveur ?
La syntaxe que je t'ai donné dans mon premier message a fonctionné
24/24 pendant plus de cinq ans.
Voilà où j'en suis, j'ai dirigé directement la sortie vers un fichier php :

newsfeeds :

httpnntp!:fr.*:Tp,Wf:/usr/lib/news/bin/sm %s | php5 /news/gateway.php


gateway.php :

$content = "";

for($line = fgets(STDIN))
{
$content .= line;
}

Le problème c'est qu'il s'arrête au premier retour chariot du head de
l'article. Y a pas moyen de récupérer directement le STDIN? (la fonction
filesize ne semble pas fonctionner sur un stdin.


Sinon côté INN, il n'y aurait pas moyen de récupérer d'une façon simple
ces articles, par exemple avec chemin physique de l'article, avec la
commande sm ?
Bruno Ducrot
2013-03-25 22:09:58 UTC
Permalink
["Followup-To:" header set to fr.comp.lang.php.]
Post by unknown
Sinon côté INN, il n'y aurait pas moyen de récupérer d'une façon simple
ces articles, par exemple avec chemin physique de l'article, avec la
commande sm ?
Oui :

% grephistory '<514ed208$0$2118$***@news.free.fr>'
@050000000304000000000000001000000000@
% grephistory '<514ed208$0$2118$***@news.free.fr>' | sm -c
@050000000304000000000000001000000000@ method=tradspool class=0 ngnum=772 artnum=0 file=/usr/local/news/spool/articles/fr/comp/usenet/serveurs/16

Le fichier dans le spool sera donc :

/usr/local/news/spool/articles/fr/comp/usenet/serveurs/16

Bien entendu, celà ne marche qu'avec tradspool.

A plus,
--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
unknown
2013-03-26 20:19:42 UTC
Permalink
Post by Bruno Ducrot
["Followup-To:" header set to fr.comp.lang.php.]
Post by unknown
Sinon côté INN, il n'y aurait pas moyen de récupérer d'une façon simple
ces articles, par exemple avec chemin physique de l'article, avec la
commande sm ?
@050000000304000000000000001000000000@
@050000000304000000000000001000000000@ method=tradspool class=0 ngnum=772 artnum=0 file=/usr/local/news/spool/articles/fr/comp/usenet/serveurs/16
/usr/local/news/spool/articles/fr/comp/usenet/serveurs/16
Bien entendu, celà ne marche qu'avec tradspool.
A plus,
Et comment je récupère la liste des messageid ?

Bon J'ai quand même des difficultés à prendre en main INN, j'en ai
pourtant juste besoin pour rediriger le feed dans ma base de données, le
feed dans l'autre sens pour assurer la liaison HTTP-NNTP -> NNTP se fera
via un socket php. L'idéal aurait été d'écrire ce serveur en javascript
avec nodejs mais le problème c'est que le port 80 est réservé au serveur
web. Par contre pour ma passerelle j'ai juste besoin d'écouter pour
répondre aux CHECK et SENDIT. En gros, il me faut une demi passerelle,
je pourrais reprendre ce projet :
https://gist.github.com/mcroydon/807303
unknown
2013-03-26 21:59:55 UTC
Permalink
Post by unknown
Post by Bruno Ducrot
["Followup-To:" header set to fr.comp.lang.php.]
Post by unknown
Sinon côté INN, il n'y aurait pas moyen de récupérer d'une façon simple
ces articles, par exemple avec chemin physique de l'article, avec la
commande sm ?
@050000000304000000000000001000000000@
@050000000304000000000000001000000000@ method=tradspool class=0
ngnum=772 artnum=0
file=/usr/local/news/spool/articles/fr/comp/usenet/serveurs/16
/usr/local/news/spool/articles/fr/comp/usenet/serveurs/16
Bien entendu, celà ne marche qu'avec tradspool.
A plus,
Et comment je récupère la liste des messageid ?
Bon ça y est ça fonctionne.

J'ai quelques questions et je trouve pas mes réponses dans les RFC :

1) Lors de l'envoi de l'article par quoi le client remplace t-il la
séquence de fin d'article (en principe "." + "CRLF") si par hasard il
s'en trouve une dans le body ?

2) Je suis en train de parser des articles pour introduire les bons
headers dans ma base, je pensais que le retour de chariot devait être le
caractère de séparation des différents champs du header mais à ma grande
surprise je trouve plein d'articles avec des retours chariots dans le
header comme par exemple : news://<kit1cp$da7$***@dont-email.me>
Comment faire dans ce cas là?

3) Ce n'est pas une question mais une remarque. le format d'encodage des
articles est une usine à gaz, il n'est pas étonnant qu'il y ait tant de
problèmes. Pourquoi ne pas tout basculer en utf8 ?

4) Y a t-il d'autres caractères spéciaux qui vous viendraient à l'esprit ?

Voici ce que j'ai écrit en php pour récupérer les différents champs de
headers :

$pos = strpos($article, "\n\n");
$head = substr($article, 0, $pos);
$body = substr($article, $pos+1);

$lignes = explode("\n", $head);

foreach ($lignes as $ligne)
{
// $ligne
}

Que faut il faire alors ?
Olivier Miakinen
2013-03-26 23:25:52 UTC
Permalink
Post by unknown
1) Lors de l'envoi de l'article par quoi le client remplace t-il la
séquence de fin d'article (en principe "." + "CRLF") si par hasard il
s'en trouve une dans le body ?
Si je me rappelle bien, tout point de début de ligne est doublé.
Post by unknown
2) Je suis en train de parser des articles pour introduire les bons
headers dans ma base, je pensais que le retour de chariot devait être le
caractère de séparation des différents champs du header mais à ma grande
surprise je trouve plein d'articles avec des retours chariots dans le
Comment faire dans ce cas là?
Mot-clé : folding white space ou FWS dans les RFC.
Post by unknown
3) Ce n'est pas une question mais une remarque. le format d'encodage des
articles est une usine à gaz, il n'est pas étonnant qu'il y ait tant de
problèmes. Pourquoi ne pas tout basculer en utf8 ?
Puisque ce n'est pas une question, je ne donnerai pas de réponse.
Juste un indice : poids de l'historique, dates respectives de NNTP et
de UTF-8, tout ça.
Post by unknown
4) Y a t-il d'autres caractères spéciaux qui vous viendraient à l'esprit ?
« >From » en début de ligne, toujours si je me rappelle bien. À moins
que ce ne soit que pour le mail.
Post by unknown
Voici ce que j'ai écrit en php pour récupérer les différents champs de
$pos = strpos($article, "\n\n");
$head = substr($article, 0, $pos);
$body = substr($article, $pos+1);
Ce ne serait pas $pos+1 pour $head et $pos+2 pour $body ?
Post by unknown
$lignes = explode("\n", $head);
Ah, je retire ma remarque pour $head. Mais cf. le traitement des FWS.
Regarde aussi le RFC 2047 pour le QP ou Base64 dans les entêtes.
Post by unknown
foreach ($lignes as $ligne)
{
// $ligne
}
Que faut il faire alors ?
Commencer par regarder ce qui existe déjà ?

Tiens, ce n'est pas spécifique aux news, mais les formats sont très
proches alors peut-être y trouveras-tu ton bonheur :
http://pear.php.net/manual/fr/package.mail.php
unknown
2013-03-27 00:26:47 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
1) Lors de l'envoi de l'article par quoi le client remplace t-il la
séquence de fin d'article (en principe "." + "CRLF") si par hasard il
s'en trouve une dans le body ?
Si je me rappelle bien, tout point de début de ligne est doublé.
Post by unknown
2) Je suis en train de parser des articles pour introduire les bons
headers dans ma base, je pensais que le retour de chariot devait être le
caractère de séparation des différents champs du header mais à ma grande
surprise je trouve plein d'articles avec des retours chariots dans le
Merci pour toutes ces explications.

Je rencontre un autre problème toujours lié à l'encodage sans doute,
quand je fais
$body = json_encode($body);
toujours sur cet article <news:kit1cp$da7$***@dont-email.me> PHP me
retourne une valeur null.
À partir de la version 5.4 de PHP l'option JSON_UNESCAPED_UNICODE
(<http://www.php.net/manual/fr/json.constants.php>)
pourrait peut être régler mon problème mais je tourne sur la version
PHP Version 5.3.3-7+squeeze15.
Est ce que quelqu'un pourrait tester sur une version 5.4 si ça passe ?
Et sinon n'existerait il pas une autre librairie PHP pour encoder en json?
unknown
2013-03-27 17:26:35 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
Post by unknown
1) Lors de l'envoi de l'article par quoi le client remplace t-il la
séquence de fin d'article (en principe "." + "CRLF") si par hasard il
s'en trouve une dans le body ?
Si je me rappelle bien, tout point de début de ligne est doublé.
Post by unknown
2) Je suis en train de parser des articles pour introduire les bons
headers dans ma base, je pensais que le retour de chariot devait être le
caractère de séparation des différents champs du header mais à ma grande
surprise je trouve plein d'articles avec des retours chariots dans le
Merci pour toutes ces explications.
Je rencontre un autre problème toujours lié à l'encodage sans doute,
quand je fais
$body = json_encode($body);
retourne une valeur null.
Problème réglé, il fallait faire
$body = json_encode(utf8_encode($body));

Visiblement json_encode n'apprécie pas les accents encodés sur un octet
(code hexadécimal = E9) ce qui à mon sens est une faute, car cette
fonction devrait être capable d'encoder absolument n'importe quelle
combinaison de bits.
Olivier Miakinen
2013-03-27 23:35:03 UTC
Permalink
Post by unknown
Post by unknown
Je rencontre un autre problème toujours lié à l'encodage sans doute,
quand je fais
$body = json_encode($body);
retourne une valeur null.
Problème réglé, il fallait faire
$body = json_encode(utf8_encode($body));
Attention, danger !

La fonction utf8_encode() transforme de l'*ISO-8859-1* en UTF-8. Donc
si au départ tu as de l'ISO-8859-1 c'est parfait, mais si c'est autre
chose, en particulier si $body contient des valeurs d'octets comprises
entre 128 et 159 (80 et 9F hexa), le résultat n'est pas défini.

Ce cas peut se produire par exemple si $body est déjà en UTF-8 (le
code UTF-8 du caractère € est E2 82 AC, dont l'octet 82 n'est pas
dans ISO-8859-1).

Ça peut se produire aussi si $body est en CP1252 (le code CP1252 du
caractère € est 80, celui du caractère œ est 9C).

Et donc, plutôt que utf8_encode, il vaudrait mieux utiliser iconv
ou mb_convert_encoding (le dernier semblant plus fiable en matière
de gestion d'erreurs), en passant le charset déclaré dans les
entêtes MIME.

Mais le pire, c'est que certains nouvelleurs envoient du CP1252 tout
en annonçant de l'ISO-8859-1, donc tu ne peux même pas toujours te
fier aux entêtes MIME s'ils existent... Cela dit, je ne serais pas
opposé à ce que tu poubellises tout article dont les entêtes MIME
seraient absents(¹) ou incorrects, ça aiderait peut-être à ce que
les utilisateurs configurent correctement leur machin...

(¹) Sauf bien sûr si l'article est entièrement en US-ASCII, auquel
cas il est possible de ne faire aucune déclaration MIME.
Post by unknown
Visiblement json_encode n'apprécie pas les accents encodés sur un octet
(code hexadécimal = E9) ce qui à mon sens est une faute, car cette
fonction devrait être capable d'encoder absolument n'importe quelle
combinaison de bits.
Si je ne m'abuse, le J de JSON signifie JavaScript, et JavaScript
travaille exclusivement en UTF-8. Même si la page web est codée dans
un autre charset, elle est transcodée en UTF-8 avant d'être passée
à JavaScript. Enfin, il me semble.

Cordialement,
--
Olivier Miakinen
unknown
2013-03-28 00:01:17 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by unknown
Je rencontre un autre problème toujours lié à l'encodage sans doute,
quand je fais
$body = json_encode($body);
retourne une valeur null.
Problème réglé, il fallait faire
$body = json_encode(utf8_encode($body));
Attention, danger !
La fonction utf8_encode() transforme de l'*ISO-8859-1* en UTF-8. Donc
si au départ tu as de l'ISO-8859-1 c'est parfait, mais si c'est autre
chose, en particulier si $body contient des valeurs d'octets comprises
entre 128 et 159 (80 et 9F hexa), le résultat n'est pas défini.
Ce cas peut se produire par exemple si $body est déjà en UTF-8 (le
code UTF-8 du caractère € est E2 82 AC, dont l'octet 82 n'est pas
dans ISO-8859-1).
Ça peut se produire aussi si $body est en CP1252 (le code CP1252 du
caractère € est 80, celui du caractère œ est 9C).
Et donc, plutôt que utf8_encode, il vaudrait mieux utiliser iconv
ou mb_convert_encoding (le dernier semblant plus fiable en matière
de gestion d'erreurs), en passant le charset déclaré dans les
entêtes MIME.
Mais le pire, c'est que certains nouvelleurs envoient du CP1252 tout
en annonçant de l'ISO-8859-1, donc tu ne peux même pas toujours te
fier aux entêtes MIME s'ils existent... Cela dit, je ne serais pas
opposé à ce que tu poubellises tout article dont les entêtes MIME
seraient absents(¹) ou incorrects, ça aiderait peut-être à ce que
les utilisateurs configurent correctement leur machin...
(¹) Sauf bien sûr si l'article est entièrement en US-ASCII, auquel
cas il est possible de ne faire aucune déclaration MIME.
Post by unknown
Visiblement json_encode n'apprécie pas les accents encodés sur un octet
(code hexadécimal = E9) ce qui à mon sens est une faute, car cette
fonction devrait être capable d'encoder absolument n'importe quelle
combinaison de bits.
Si je ne m'abuse, le J de JSON signifie JavaScript, et JavaScript
travaille exclusivement en UTF-8. Même si la page web est codée dans
un autre charset, elle est transcodée en UTF-8 avant d'être passée
à JavaScript. Enfin, il me semble.
Cordialement,
Tu saurais me faire une synthèse, un tableau des différents cas de
figure à traiter? Est ce qu'il serait possible de corriger
automatiquement l'encodage de l'article en se basant sur un algorithme
statistique ?
unknown
2013-03-28 00:17:33 UTC
Permalink
Post by Olivier Miakinen
Et donc, plutôt que utf8_encode, il vaudrait mieux utiliser iconv
ou mb_convert_encoding (le dernier semblant plus fiable en matière
de gestion d'erreurs), en passant le charset déclaré dans les
entêtes MIME.
Mais le pire, c'est que certains nouvelleurs envoient du CP1252 tout
en annonçant de l'ISO-8859-1, donc tu ne peux même pas toujours te
fier aux entêtes MIME s'ils existent... Cela dit, je ne serais pas
opposé à ce que tu poubellises tout article dont les entêtes MIME
seraient absents(¹) ou incorrects, ça aiderait peut-être à ce que
les utilisateurs configurent correctement leur machin...
(¹) Sauf bien sûr si l'article est entièrement en US-ASCII, auquel
cas il est possible de ne faire aucune déclaration MIME.
L'idéal ce serait une fonction
encode2utf8($string, $charset)
et si possible une fonction
detectCharset($string) au cas où le charset est absent et/ou incorrect.

Si on peut écrire ceci :
encode2utf8($string, detectCharset($string))
on règle définitivement ce problème d'encodage qui pourrit usenet.
Olivier Miakinen
2013-03-28 00:25:42 UTC
Permalink
Post by unknown
L'idéal ce serait une fonction
encode2utf8($string, $charset)
et si possible une fonction
detectCharset($string) au cas où le charset est absent et/ou incorrect.
http://www.php.net/mbstring

Je vois :
-> mb_check_encoding
-> mb_convert_encoding
-> mb_detect_encoding

Et... oh ! Il y a même encore mieux :
-> mb_decode_mimeheader
http://www.php.net/manual/fr/function.mb-decode-mimeheader.php
... sauf que je n'ai pas encore vu comment spécifier l'encodage interne
(qui devrait être UTF-8), sinon dans le php.ini
unknown
2013-03-28 21:33:25 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
L'idéal ce serait une fonction
encode2utf8($string, $charset)
et si possible une fonction
detectCharset($string) au cas où le charset est absent et/ou incorrect.
http://www.php.net/mbstring
-> mb_check_encoding
-> mb_convert_encoding
-> mb_detect_encoding
-> mb_decode_mimeheader
http://www.php.net/manual/fr/function.mb-decode-mimeheader.php
... sauf que je n'ai pas encore vu comment spécifier l'encodage interne
(qui devrait être UTF-8), sinon dans le php.ini
Impeccable, j'ai vidé la table des articles, on va voir si le test est
concluant pour le champ subject. À ton avis je dois appliquer la méthode
mb_decode_mimeheader également sur from et organisation ?
Pour le body quelles sont els premières conclusions ?
Olivier Miakinen
2013-03-28 23:04:11 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
-> mb_decode_mimeheader
http://www.php.net/manual/fr/function.mb-decode-mimeheader.php
... sauf que je n'ai pas encore vu comment spécifier l'encodage interne
(qui devrait être UTF-8), sinon dans le php.ini
Impeccable, j'ai vidé la table des articles, on va voir si le test est
concluant pour le champ subject.
Ok.
Post by unknown
À ton avis je dois appliquer la méthode
mb_decode_mimeheader également sur from et organisation ?
Oui. Parmi les nouveaux champs définis dans le RFC 5536, il y a aussi
le champ Summary qui me semble un bon candidat -- mais je ne sais pas
si on en verra un jour.
Post by unknown
Pour le body quelles sont les premières conclusions ?
Je ne comprends pas la question. Cela dit, commence donc par lire
attentivement le RFC 5536, ça devrait répondre à bon nombre de tes
question.


Cordialement,
--
Olivier Miakinen
unknown
2013-03-28 23:18:07 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
-> mb_decode_mimeheader
http://www.php.net/manual/fr/function.mb-decode-mimeheader.php
... sauf que je n'ai pas encore vu comment spécifier l'encodage interne
(qui devrait être UTF-8), sinon dans le php.ini
Impeccable, j'ai vidé la table des articles, on va voir si le test est
concluant pour le champ subject.
Ok.
Post by unknown
À ton avis je dois appliquer la méthode
mb_decode_mimeheader également sur from et organisation ?
Oui. Parmi les nouveaux champs définis dans le RFC 5536, il y a aussi
le champ Summary qui me semble un bon candidat -- mais je ne sais pas
si on en verra un jour.
Post by unknown
Pour le body quelles sont les premières conclusions ?
Je ne comprends pas la question. Cela dit, commence donc par lire
attentivement le RFC 5536, ça devrait répondre à bon nombre de tes
question.
Le header c'est un problème réglé, maintenant il faut encoder le body en
UTF8 et pour ça j'ai juste besoin du charset c'est bien ça ?
Olivier Miakinen
2013-03-28 23:24:17 UTC
Permalink
Post by unknown
Le header c'est un problème réglé, maintenant il faut encoder le body en
UTF8 et pour ça j'ai juste besoin du charset c'est bien ça ?
Oui. Du charset dans le Content-Type et du Content-Transfer-Encoding.
Et si ces entêtes sont absents, comme le dit Stéphane tu peux vérifier
que c'est déjà de l'UTF-8 (ce qui inclut US-ASCII), et sinon poubelle
(sauf si tu es un mec sympa et que tu acceptes de tester d'autres
charsets avant de jeter le tout).
unknown
2013-03-28 23:26:56 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Le header c'est un problème réglé, maintenant il faut encoder le body en
UTF8 et pour ça j'ai juste besoin du charset c'est bien ça ?
Oui. Du charset dans le Content-Type et du Content-Transfer-Encoding.
Et si ces entêtes sont absents, comme le dit Stéphane tu peux vérifier
que c'est déjà de l'UTF-8 (ce qui inclut US-ASCII), et sinon poubelle
(sauf si tu es un mec sympa et que tu acceptes de tester d'autres
charsets avant de jeter le tout).
Quelle information m'apporte le Content-Transfer-Encoding ?
Et comment je teste les autres charsets ?
unknown
2013-03-28 23:39:13 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Le header c'est un problème réglé, maintenant il faut encoder le body en
UTF8 et pour ça j'ai juste besoin du charset c'est bien ça ?
Oui. Du charset dans le Content-Type et du Content-Transfer-Encoding.
Et si ces entêtes sont absents, comme le dit Stéphane tu peux vérifier
que c'est déjà de l'UTF-8 (ce qui inclut US-ASCII), et sinon poubelle
(sauf si tu es un mec sympa et que tu acceptes de tester d'autres
charsets avant de jeter le tout).
Prenons un exemple pratique :

<news:801f5ff9-a689-4cd9-8d61-***@x13g2000vby.googlegroups.com>

"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable


Pendant que la crise redouble, le Parlement perd son temps =E0 discuter
pendant des mois sur le mariage des p=E9d=E9s !"

Qu'est ce qu'on peut faire pour lui, pour la forme pas pour le fond ;-)
Sur mon thunderbird son message s'affiche correctement mais pas sur Nemo ...
unknown
2013-03-28 23:43:28 UTC
Permalink
Post by Eric Demeester
Post by Olivier Miakinen
Post by unknown
Le header c'est un problème réglé, maintenant il faut encoder le body en
UTF8 et pour ça j'ai juste besoin du charset c'est bien ça ?
Oui. Du charset dans le Content-Type et du Content-Transfer-Encoding.
Et si ces entêtes sont absents, comme le dit Stéphane tu peux vérifier
que c'est déjà de l'UTF-8 (ce qui inclut US-ASCII), et sinon poubelle
(sauf si tu es un mec sympa et que tu acceptes de tester d'autres
charsets avant de jeter le tout).
"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Pendant que la crise redouble, le Parlement perd son temps =E0 discuter
pendant des mois sur le mariage des p=E9d=E9s !"
Qu'est ce qu'on peut faire pour lui, pour la forme pas pour le fond ;-)
Sur mon thunderbird son message s'affiche correctement mais pas sur Nemo ...
Bien qu'ayant le même charset que moi, comment se fait il que les
accents du message
<news:801f5ff9-a689-4cd9-8d61-***@x13g2000vby.googlegroups.com>
n'apparaissent pas quand on fait un copier coller ?
Olivier Miakinen
2013-03-29 00:32:12 UTC
Permalink
Post by unknown
Post by Eric Demeester
"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Pendant que la crise redouble, le Parlement perd son temps =E0 discuter
pendant des mois sur le mariage des p=E9d=E9s !"
Qu'est ce qu'on peut faire pour lui, pour la forme pas pour le fond ;-)
Essaye ceci (j'ai changé la phrase) :

$charset = "ISO-8859-1";
$quotedp = "la fourmi passait son temps =E0 chanter tout l'=E9t=E9";
$isolatin1 = preg_replace_callback(
'/=([0-9a-f]{2})/i',
create_function('$m', 'return pack("H*", $m[1]);'),
$quotedp);
$body = mb_convert_encoding($isolatin1, 'UTF-8', $charset);

Note : tu peux sans doute remplacer pack("H*", $m[1]) par hex2bin($m[1])
Post by unknown
Bien qu'ayant le même charset que moi, comment se fait il que les
accents du message
n'apparaissent pas quand on fait un copier coller ?
Chez moi ça marche © et ça devrait fonctionner avec ton Thunderbird
comme avec mon SeaMonkey.
unknown
2013-03-29 08:32:19 UTC
Permalink
C'est quoi l'intérêt de faire du quote-printable avec un charset
iso-8859-1 ???
D'ailleurs c'est quoi l'intérêt du quoteprintable tout court ?
Dans le corps d'un article de news : aucun intérêt, NNTP étant robuste
aux caractères 8bits dès le début. C'était utile pour le courriel car
au départ le protocole n'était pas prévu pour transmettre autre chose
que de l'ASCII 7 bits, et il itait pluttt friquent de voir les
caracthres transformis comme ga, ` cause de la perte du huitihme bit.
;-)
Ok, donc pour résumer, je récupère :

String $charset
Bollean $QP (qui vaut true ou false selon que quote-printable est
déclaré ou non)


if ($QP == true)
{
$body = quoted_printable_encode ( $body )
}

if ($charset != 'UTF-8)
{
$body = mb_convert_encoding( $body, 'UTF-8', $charset )
}

Toi qui est calé en expressions régulières tu pourrais m'extraire le
charset du content-Type en tenant compte de toutes les différences de
déclaration, guillemets, pas guillemet, espace ou autres...

Et ces deux informations à me sont elles utiles?
format=flowed
Content-Transfer-Encoding: 8bit
unknown
2013-03-29 10:01:44 UTC
Permalink
Post by unknown
C'est quoi l'intérêt de faire du quote-printable avec un charset
iso-8859-1 ???
D'ailleurs c'est quoi l'intérêt du quoteprintable tout court ?
Dans le corps d'un article de news : aucun intérêt, NNTP étant robuste
aux caractères 8bits dès le début. C'était utile pour le courriel car
au départ le protocole n'était pas prévu pour transmettre autre chose
que de l'ASCII 7 bits, et il itait pluttt friquent de voir les
caracthres transformis comme ga, ` cause de la perte du huitihme bit.
;-)
String $charset
Bollean $QP (qui vaut true ou false selon que quote-printable est
déclaré ou non)
if ($QP == true)
{
$body = quoted_printable_encode ( $body )
}
if ($charset != 'UTF-8)
{
$body = mb_convert_encoding( $body, 'UTF-8', $charset )
}
Toi qui est calé en expressions régulières tu pourrais m'extraire le
charset du content-Type en tenant compte de toutes les différences de
déclaration, guillemets, pas guillemet, espace ou autres...
J'ai écrit ceci :
$value = preg_replace('#([^.;a-z0-9=-]+)#i', ' ', $value);
preg_match( "/charset=(.+);/", $value, $charset );
$charset = $charset[1];

mais j'ai des doutes sur le ";"...
Olivier Miakinen
2013-03-29 17:20:45 UTC
Permalink
Post by unknown
String $charset
Boolean $QP (qui vaut true ou false selon que quote-printable est
déclaré ou non)
Il faudrait traiter un peu plus que « QP / non QP ». Même si je
comprends bien que tu ne veuilles pas prendre en compte le type
"binary", ni les ietf-token ou x-token prévus dans le RFC 2045[1],
il faut au moins conserver "7bit", "8bit", "quoted-printable" et
"base64".
Post by unknown
if ($QP == true)
{
$body = quoted_printable_encode ( $body )
}
Tu voulais dire « decode » plutôt que « encode », non ?
Post by unknown
Toi qui est calé en expressions régulières tu pourrais m'extraire le
charset du content-Type en tenant compte de toutes les différences de
déclaration, guillemets, pas guillemet, espace ou autres...
Voyons voir...

<cit. RFC 2045[1]>
5.1. Syntax of the Content-Type Header Field

In the Augmented BNF notation of RFC 822, a Content-Type header field
value is defined as follows:

content := "Content-Type" ":" type "/" subtype
*(";" parameter)
; Matching of media type and subtype
; is ALWAYS case-insensitive.

[...]

parameter := attribute "=" value

attribute := token
; Matching of attributes
; is ALWAYS case-insensitive.

value := token / quoted-string

token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
or tspecials>

tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
</cit.>

<cit. RFC 5322[2]>
quoted-pair = ("\" (VCHAR / WSP)) / obs-qp

qtext = %d33 / ; Printable US-ASCII
%d35-91 / ; characters not including
%d93-126 / ; "\" or the quote character
obs-qtext

qcontent = qtext / quoted-pair

quoted-string = [CFWS]
DQUOTE *([FWS] qcontent) [FWS] DQUOTE
[CFWS]
</cit.>


Bon, dans un premier temps on va faire un peu plus simple...

Mais je dois quand même tenir compte du fait qu'il peut y avoir ou
non des guillemets, et des commentaires entres parenthèses. Je vais
y réfléchir.
Post by unknown
Et ces deux informations à me sont
;-)

Régionalisme, ou coquillle ?
Post by unknown
elles utiles?
format=flowed
Beurk, mais oui, le client étant un navigateur web, il serait bon
d'en tenir compte. Cela dit, ce n'est vraiment pas le plus urgent.
D'ailleurs il me semble l'avoir écrit dans un article précédent,
sauf que je n'arrive pas à retrouver lequel.
Post by unknown
Content-Transfer-Encoding: 8bit
Oui ! Celui-ci veut dire qu'il ne faut rien faire. ;-)
Cf. le RFC 2045[1].


[1] RFC 2045, MIME #1: Format of Internet Message Bodies
<http://tools.ietf.org/html/rfc2045>

[2] RFC 5322, Internet Message Format
<http://tools.ietf.org/html/rfc5322>
unknown
2013-03-30 13:48:15 UTC
Permalink
Bonjour,

Sur cette page j'ouvre un socket pour me connecter sur mon serveur INN
en localhost :
http://news.julien-arlandis.fr/test3.php

Le problème c'est que je ne parviens pas à envoyer l'article (code 439
au lieu de 239), MAIS quand je passe en telnet et que je fais un copier
coller de ce que j'ai dans la page (dans le code source) ça passe
parfaitement avec le code 239. Il doit y avoir une subtilité qui
m'échappe mais je ne vois pas laquelle...

Voici le contenu du script PHP :
<?php

$messageid=uniqid()."@news.julien-arlandis.fr";

$article=<<<EOF
Path: .POSTED!not-for-mail
from: julien
Subject: re test
References:
Newsgroups: fr.test
date: Sat, 30 Mar 13 11:33:14 +0100
userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8)
AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Message-ID: <{$messageid}>
organization: Nemo News
postingHost: 86.217.59.230
complaintsTo: ***@laposte.net
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
EOF;


$body="Re test passerelle";


$server = 'localhost';
$port = 119;
$fp = fsockopen($server, $port);

echo fgets($fp, 128);


$put = "TAKETHIS <{$messageid}>\n";
echo $put;
fputs($fp, $put, strlen($put));

$lignes = explode("\n",$article);
foreach($lignes as $put)
{
$put.="\n";
echo $put;
fputs($fp, $put, strlen($put));
}

$put = "\n".$body;
echo $put;
fputs($fp, $put, strlen($put));
$put = "\r\n.\r\n";
echo $put;
fputs($fp, $put, strlen($put));
echo fgets($fp, 128);

$put = "QUIT"."\r\n";
echo $put;
fputs($fp, $put);

fclose($fp);
?>
unknown
2013-03-30 13:52:56 UTC
Permalink
Post by Eric Demeester
Bonjour,
Sur cette page j'ouvre un socket pour me connecter sur mon serveur INN
http://news.julien-arlandis.fr/test3.php
Le problème c'est que je ne parviens pas à envoyer l'article (code 439
au lieu de 239), MAIS quand je passe en telnet et que je fais un copier
coller de ce que j'ai dans la page (dans le code source) ça passe
parfaitement avec le code 239. Il doit y avoir une subtilité qui
m'échappe mais je ne vois pas laquelle...
Problème réglé il fallait insérer un "\r\n" entre le head et le body, je
mettais un "\n\n" ...
Olivier Miakinen
2013-03-30 14:33:10 UTC
Permalink
Salut !

J'ai vu que tu as résolu ton problème. Mais je t'en signale d'autres,
réels ou potentiels.
Post by unknown
<?php
$article=<<<EOF
Path: .POSTED!not-for-mail
from: julien
Même si les lecteurs ne devraient pas tenir compte de la casse,
traditionnellement on écrit « From: » et pas « from: ». Il pourrait
y avoir des lecteurs mal foutus pour qui cela compte.
Post by unknown
Subject: re test
<http://tools.ietf.org/html/rfc5536>
o Every line of a header field body (including the first and any
that are subsequently folded) MUST contain at least one non-
whitespace character.

NOTE: This means that no header field body defined by or
referenced by this document can be empty.
</>

Cela veut dire d'une part que tu ne dois pas mettre un champ optionnel
tel que References si son contenu est vide, et d'autre part que tu ne
peux pas laisser un utilisateur mettre un Subject vide : comme ce champ
est obligatoire, au pire tu mets « (pas de sujet) » à la place.
Post by unknown
Newsgroups: fr.test
date: Sat, 30 Mar 13 11:33:14 +0100
userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8)
Attention, là ce n'est pas qu'une question de casse : il manque le
trait d'union pour que ce champ soit reconnu.
Post by unknown
AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Il manque l'espace de continuation après le saut de ligne. Et si tu
n'avais pas mis de saut de ligne, alors la ligne devait être un peu
longue : bien que ce ne soit pas une obligation tant que tu ne dépasses
pas 998, ce serait bien d'aller à la ligne avant 78 octets.
Post by unknown
Message-ID: <{$messageid}>
organization: Nemo News
postingHost: 86.217.59.230
Tu voulais dire « NNTP-Posting-Host: » ? Par ailleurs, si tu mets ce
champ, tu peux y mettre aussi « NNTP-Posting-Date ». Mais puisque tu
développes un nouveau logiciel, autant respecter le RFC 5536 et inclure
plutôt Injection-Date et Injection-Info.
Tu voulais dire « X-Complaints-To: » ? De toute manière c'est aussi
dans Injection-Info. Tu as lu le RFC 5536 ?
Post by unknown
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
EOF;
Je croyais avoir déjà trop insisté dans mon article en réponse à
celui d'Éric, mais visiblement il faut que je le répète encore.

NE PAS OUBLIER « MIME-Version: 1.0 » !

NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !

NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !


Cordialement,
--
Olivier Miakinen

P.-S. : il ne faut pas oublier l'entête « MIME-Version: 1.0 ».
Julien Arlandis
2013-03-30 14:45:25 UTC
Permalink
Post by Olivier Miakinen
Salut !
J'ai vu que tu as résolu ton problème. Mais je t'en signale d'autres,
réels ou potentiels.
Post by unknown
<?php
$article=<<<EOF
Path: .POSTED!not-for-mail
from: julien
Même si les lecteurs ne devraient pas tenir compte de la casse,
traditionnellement on écrit « From: » et pas « from: ». Il pourrait
y avoir des lecteurs mal foutus pour qui cela compte.
Oui
Post by Olivier Miakinen
<http://tools.ietf.org/html/rfc5536>
o Every line of a header field body (including the first and any
that are subsequently folded) MUST contain at least one non-
whitespace character.
NOTE: This means that no header field body defined by or
referenced by this document can be empty.
</>
Cela veut dire d'une part que tu ne dois pas mettre un champ optionnel
tel que References si son contenu est vide, et d'autre part que tu ne
peux pas laisser un utilisateur mettre un Subject vide : comme ce champ
est obligatoire, au pire tu mets « (pas de sujet) » à la place.
Post by unknown
Newsgroups: fr.test
date: Sat, 30 Mar 13 11:33:14 +0100
Peux tu me dire si la date est au bon format ? Notamment l'année, il
manque les 2 premiers chiffres.
Post by Olivier Miakinen
Post by unknown
userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8)
Attention, là ce n'est pas qu'une question de casse : il manque le
trait d'union pour que ce champ soit reconnu.
Oui, effectivement. Pour la compatibilité avec javascript je voulais
interdire le tiret dans une clé json pour qu'il n'y ait pas de confusion
avec le signe -.
Post by Olivier Miakinen
Post by unknown
AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Il manque l'espace de continuation après le saut de ligne. Et si tu
n'avais pas mis de saut de ligne, alors la ligne devait être un peu
longue : bien que ce ne soit pas une obligation tant que tu ne dépasses
pas 998, ce serait bien d'aller à la ligne avant 78 octets.
"espace + \r + \n" c'est bien ça ?
Post by Olivier Miakinen
Post by unknown
Message-ID: <{$messageid}>
Oui
Post by Olivier Miakinen
Post by unknown
organization: Nemo News
Oui
Post by Olivier Miakinen
Post by unknown
postingHost: 86.217.59.230
Tu voulais dire « NNTP-Posting-Host: » ? Par ailleurs, si tu mets ce
champ, tu peux y mettre aussi « NNTP-Posting-Date ». Mais puisque tu
développes un nouveau logiciel, autant respecter le RFC 5536 et inclure
plutôt Injection-Date et Injection-Info.
Ok
Post by Olivier Miakinen
Tu voulais dire « X-Complaints-To: » ? De toute manière c'est aussi
dans Injection-Info. Tu as lu le RFC 5536 ?
J'ai parcouru les RFC mais je préfère corriger les problèmes au fil de
l'eau comme on fait actuellement...
Post by Olivier Miakinen
Post by unknown
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
EOF;
Je croyais avoir déjà trop insisté dans mon article en réponse à
celui d'Éric, mais visiblement il faut que je le répète encore.
NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !
NE PAS OUBLIER « MIME-Version: 1.0 » !
Ok, je corrige tout ça.
unknown
2013-03-30 17:11:39 UTC
Permalink
Post by Olivier Miakinen
Même si les lecteurs ne devraient pas tenir compte de la casse,
traditionnellement on écrit « From: » et pas « from: ». Il pourrait
y avoir des lecteurs mal foutus pour qui cela compte.
J'ai corrigé pas mal de choses, sauf pour le retour chariot pour imposer
une limite de taille aux lignes du header. Sauf que je sais pas trop
comment le positionner, y aurait pas une méthode PHP qui gère ça pour
les mails ?

Ici, tu peux comparer les paquets json et NTTP des derniers articles
publiés :
http://news.julien-arlandis.fr/http-nntp/test.php


<?php

$headersJSONtoNNTP = array(
"Path" => "Path",
"MessageID" => "Message-ID",
"From" => "From",
"Subject" => "Subject",
"Newsgroups" => "Newsgroups",
"Date" => "Date",
"References" => "References",
"UserAgent" => "User-Agent",
"Organization" => "Organization",
"PostingHost" => "NNTP-Posting-Host",
"ComplaintsTo" => "X-Complaints-To",
"Body"=> false
);


foreach ($json as $cle=>$value)
{
if($cle === 'Path')
{
$article .= $headersJSONtoNNTP[$cle].": ".$value."\n";
}
elseif($cle === 'MessageID')
{
$article .= $headersJSONtoNNTP[$cle].": ".$value."\n";
}
elseif($cle === 'From')
{
$article .= $headersJSONtoNNTP[$cle].": ".$value."\n";
}
elseif($cle === 'Subject')
{
$article .= $headersJSONtoNNTP[$cle].":
".mb_encode_mimeheader($value)."\n";
}
elseif($cle === 'Newsgroups')
{
$article .= $headersJSONtoNNTP[$cle].": ".implode(",", $value)."\n";
}
elseif($cle === 'Date')
{
$article .= $headersJSONtoNNTP[$cle].": ".$value."\n";
}
elseif($cle === 'References')
{
if(!empty($value))
{
$article .= $headersJSONtoNNTP[$cle].": ".implode(" ", $value)."\n";
}
}
elseif($cle === 'UserAgent')
{
$article .= $headersJSONtoNNTP[$cle].": ".$value."\n";
}
elseif($cle === 'Organization')
{
$article .= $headersJSONtoNNTP[$cle].":
".mb_encode_mimeheader($value)."\n";
}
elseif($cle === 'PostingHost')
{
$article .= $headersJSONtoNNTP[$cle].": ".$value."\n";
}
elseif($cle === 'ComplaintsTo')
{
$article .= $headersJSONtoNNTP[$cle].": ".$value."\n";
}
elseif($cle === 'ExtendedHeaders')
{
foreach ($json->{$cle} as $cle=>$value)
{
$article .= $cle .": ".$value."\n";
}
}
else
{
if($headersJSONtoNNTP[$cle])
{
$article .= $cle .": ".$value."\n";
}
}
}

$article .= "MIME-Version: 1.0\n";
$article .= "Content-Type: text/plain; charset=UTF-8; format=flowed\n";
$article .= "Content-Transfer-Encoding: 8bit\n";
$article .= "\r\n";
$article .= str_replace("\r\n.\r\n", "\r\n..\r\n", $json->{'Body'});

?>
Eric Demeester
2013-03-30 17:32:01 UTC
Permalink
dans (in) fr.comp.lang.php, Julien Arlandis <"julien.arlandis at
laposte.net"> ecrivait (wrote) :

Bonjour,
Post by unknown
J'ai corrigé pas mal de choses, sauf pour le retour chariot pour imposer
une limite de taille aux lignes du header. Sauf que je sais pas trop
comment le positionner, y aurait pas une méthode PHP qui gère ça pour
les mails ?
Une piste : wordwrap :
http://www.manuelphp.com/php/function.wordwrap.php

Intéressant aussi pour forcer les retour-chariot dans la rédaction des
articles.

Contrairement à Olivier, je préconise plutôt 72 caractères, ça permet
l'indentation de plusieurs niveaux de citations, mais c'est limite
pinaillage :)
--
Eric
Eric Demeester
2013-03-30 17:36:21 UTC
Permalink
Post by Eric Demeester
http://www.manuelphp.com/php/function.wordwrap.php
Contrairement à Olivier, je préconise plutôt 72 caractères, ça permet
l'indentation de plusieurs niveaux de citations, mais c'est limite
pinaillage :)
Finalement, 75 caracy=tères, c'est bien :

« Par défaut, wordwrap va automatiquement insérer une nouvelle ligne en
utilisant \n tous les 75 caractères, si width ou break ne sont pas
fournis. »

Et hop, sauf cas particulier, un paramètre de moins à gérer.
--
Eric
unknown
2013-03-30 17:53:12 UTC
Permalink
Post by Eric Demeester
dans (in) fr.comp.lang.php, Julien Arlandis <"julien.arlandis at
Bonjour,
Post by unknown
J'ai corrigé pas mal de choses, sauf pour le retour chariot pour imposer
une limite de taille aux lignes du header. Sauf que je sais pas trop
comment le positionner, y aurait pas une méthode PHP qui gère ça pour
les mails ?
http://www.manuelphp.com/php/function.wordwrap.php
Intéressant aussi pour forcer les retour-chariot dans la rédaction des
articles.
Contrairement à Olivier, je préconise plutôt 72 caractères, ça permet
l'indentation de plusieurs niveaux de citations, mais c'est limite
pinaillage :)
Merci mais est ce qu'avec les histoires d'encodage dans les titres ça va
pas foutre le bordel ? Après l'encodage il n'y a plus d'espaces et avant
on ne sait pas où il faut tronquer...
Olivier Miakinen
2013-03-30 21:58:29 UTC
Permalink
Post by unknown
Post by Eric Demeester
http://www.manuelphp.com/php/function.wordwrap.php
Merci mais est ce qu'avec les histoires d'encodage dans les titres ça va
pas foutre le bordel ? Après l'encodage il n'y a plus d'espaces et avant
on ne sait pas où il faut tronquer...
Bah... les fonctions d'encodage d'entêtes MIME fournissent forcément
ça puisque les RFC demandent explicitement de ne pas dépasser 76
caractères.

Tiens, au hasard :

<http://php.net/manual/en/function.mb-encode-mimeheader.php>
linefeed

linefeed specifies the EOL (end-of-line) marker with which
mb_encode_mimeheader() performs line-folding (a » RFC term, the act of
breaking a line longer than a certain length into multiple lines. The
length is currently hard-coded to 74 characters). Falls back to "\r\n"
(CRLF) if not given.

indent

Indentation of the first line (number of characters in the header
before str).
</>
unknown
2013-03-30 23:19:36 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by Eric Demeester
http://www.manuelphp.com/php/function.wordwrap.php
Merci mais est ce qu'avec les histoires d'encodage dans les titres ça va
pas foutre le bordel ? Après l'encodage il n'y a plus d'espaces et avant
on ne sait pas où il faut tronquer...
Bah... les fonctions d'encodage d'entêtes MIME fournissent forcément
ça puisque les RFC demandent explicitement de ne pas dépasser 76
caractères.
<http://php.net/manual/en/function.mb-encode-mimeheader.php>
linefeed
Pour spécifier le linefeed je suis obligé de spécifier le charset
(argument placé juste avant dans la fonction), et c'est mal fichu le php
car si la valeur par défaut convient je ne sais pas quoi spécifier si je
dois fixer quelque chose... Donc je mets quoi?
Post by Olivier Miakinen
linefeed specifies the EOL (end-of-line) marker with which
mb_encode_mimeheader() performs line-folding (a » RFC term, the act of
breaking a line longer than a certain length into multiple lines. The
length is currently hard-coded to 74 characters). Falls back to "\r\n"
(CRLF) if not given.
indent
Indentation of the first line (number of characters in the header
before str).
</>
Olivier Miakinen
2013-03-31 08:46:41 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
<http://php.net/manual/en/function.mb-encode-mimeheader.php>
linefeed
Pour spécifier le linefeed je suis obligé de spécifier le charset
(argument placé juste avant dans la fonction), et c'est mal fichu le php
car si la valeur par défaut convient je ne sais pas quoi spécifier si je
dois fixer quelque chose... Donc je mets quoi?
Je ne comprends pas de quoi tu parles. Quelle valeur par défaut ?

Le charset à utiliser pour l'encodage, c'est toi qui le spécifies.
Sur usenet-fr, tu peux tester dans l'ordre ISO-8859-15, puis ISO-8859-1
(ou l'inverse), et enfin UTF-8 si le reste échoue. Ou bien tu peux
décider de te limiter à UTF-8.
Post by unknown
Post by Olivier Miakinen
linefeed specifies the EOL (end-of-line) marker with which
[etc.]
Inutile de citer ce à quoi tu ne réponds pas, hein ! ;-)
Julien Arlandis
2013-03-31 10:31:49 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
<http://php.net/manual/en/function.mb-encode-mimeheader.php>
linefeed
Pour spécifier le linefeed je suis obligé de spécifier le charset
(argument placé juste avant dans la fonction), et c'est mal fichu le php
car si la valeur par défaut convient je ne sais pas quoi spécifier si je
dois fixer quelque chose... Donc je mets quoi?
Je ne comprends pas de quoi tu parles. Quelle valeur par défaut ?
Le charset à utiliser pour l'encodage, c'est toi qui le spécifies.
Sur usenet-fr, tu peux tester dans l'ordre ISO-8859-15, puis ISO-8859-1
(ou l'inverse), et enfin UTF-8 si le reste échoue. Ou bien tu peux
décider de te limiter à UTF-8.
Pour l'instant je faisais un
"Subject: ".mb_encode_mimeheader($value)."\r\n";


Si j'écris
"Subject: ".mb_encode_mimeheader($value, "UTF-8", " \n")."\r\n";

c'est bon ?
Julien Arlandis
2013-03-31 10:38:50 UTC
Permalink
Post by Julien Arlandis
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
<http://php.net/manual/en/function.mb-encode-mimeheader.php>
linefeed
Pour spécifier le linefeed je suis obligé de spécifier le charset
(argument placé juste avant dans la fonction), et c'est mal fichu le php
car si la valeur par défaut convient je ne sais pas quoi spécifier si je
dois fixer quelque chose... Donc je mets quoi?
Je ne comprends pas de quoi tu parles. Quelle valeur par défaut ?
Le charset à utiliser pour l'encodage, c'est toi qui le spécifies.
Sur usenet-fr, tu peux tester dans l'ordre ISO-8859-15, puis ISO-8859-1
(ou l'inverse), et enfin UTF-8 si le reste échoue. Ou bien tu peux
décider de te limiter à UTF-8.
Pour l'instant je faisais un
"Subject: ".mb_encode_mimeheader($value)."\r\n";
Si j'écris
"Subject: ".mb_encode_mimeheader($value, "UTF-8", " \n")."\r\n";
c'est bon ?
Apparemment non :

Subject: ééé marche pas
renvoi ceci
Subject: =?UTF-8?B?w4PCqcODwqnDg8KpIG1hcmNoZSBwYXM=?=
et qui affiche
ééé marche pas

Bon là c'est de la base 64, faudrait peut être spécifier du QP ?
Olivier Miakinen
2013-03-31 13:04:10 UTC
Permalink
Post by Julien Arlandis
Post by Julien Arlandis
Si j'écris
"Subject: ".mb_encode_mimeheader($value, "UTF-8", " \n")."\r\n";
c'est bon ?
D'après la doc, ça devrait l'être si ton texte d'origine ($value)
contient de l'UTF-8 normal, et pas doublement encodé.
Post by Julien Arlandis
Subject: ééé marche pas
renvoi ceci
Subject: =?UTF-8?B?w4PCqcODwqnDg8KpIG1hcmNoZSBwYXM=?=
et qui affiche
ééé marche pas
Tu es sûr de $value ? Quelles sont les valeurs des quatre premiers
octets de cette chaîne ? Et sa longueur... 17 ou 23 ?
Post by Julien Arlandis
Bon là c'est de la base 64, faudrait peut être spécifier du QP ?
Tu y verrais plus clair, mais s'il n'y a pas de bug dans la fonction ça
ne devrait rien changer.
unknown
2013-03-31 13:10:36 UTC
Permalink
Post by Olivier Miakinen
Post by Julien Arlandis
Post by Julien Arlandis
Si j'écris
"Subject: ".mb_encode_mimeheader($value, "UTF-8", " \n")."\r\n";
c'est bon ?
D'après la doc, ça devrait l'être si ton texte d'origine ($value)
contient de l'UTF-8 normal, et pas doublement encodé.
C'est la valeur stockée dans l'objet json...
Post by Olivier Miakinen
Tu es sûr de $value ? Quelles sont les valeurs des quatre premiers
octets de cette chaîne ? Et sa longueur... 17 ou 23 ?
Post by Julien Arlandis
Bon là c'est de la base 64, faudrait peut être spécifier du QP ?
Tu y verrais plus clair, mais s'il n'y a pas de bug dans la fonction ça
ne devrait rien changer.
Regarde cet article posté avec Nemo :

<news:***@news.julien-arlandis.fr>

J'ai utilisé mb_encode_mimeheader($value, "UTF-8", "Q", " \n")
Olivier Miakinen
2013-03-31 20:06:12 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
Post by Julien Arlandis
Si j'écris
"Subject: ".mb_encode_mimeheader($value, "UTF-8", " \n")."\r\n";
c'est bon ?
D'après la doc, ça devrait l'être si ton texte d'origine ($value)
contient de l'UTF-8 normal, et pas doublement encodé.
C'est la valeur stockée dans l'objet json...
La variable PHP « $value », c'est un objet json ?
Post by unknown
Post by Olivier Miakinen
Tu es sûr de $value ? Quelles sont les valeurs des quatre premiers
octets de cette chaîne ? Et sa longueur... 17 ou 23 ?
Comme je ne sais pas comment tu passes de l'objet json à la variable
$value, le bug pourrait être aussi bien dans cette partie-là que dans
la fonction mb_encode_mimeheader. C'était pour localiser le problème
que je te demandais le contenu de la variable si possible, ou au moins
sa longueur (en donnant le résultat exact correspondant).
Post by unknown
J'ai utilisé mb_encode_mimeheader($value, "UTF-8", "Q", " \n")
Oui, j'ai bien vu le résultat. Mais j'aurais voulu connaître la
source donnant ce résultat.

En clair, donner à la fois les deux résultats suivants ;
bin2hex($value)
et
mb_encode_mimeheader($value, "UTF-8", "Q", " \n")

Si je n'ai plus la flemme je remettrai un environnement PHP sur ma
machine pour pouvoir le faire moi-même, mais pour le moment tout
ce que je t'indique n'est basé que sur mes souvenirs ou sur la doc.
unknown
2013-03-31 20:55:12 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
Post by Julien Arlandis
Si j'écris
"Subject: ".mb_encode_mimeheader($value, "UTF-8", " \n")."\r\n";
c'est bon ?
D'après la doc, ça devrait l'être si ton texte d'origine ($value)
contient de l'UTF-8 normal, et pas doublement encodé.
C'est la valeur stockée dans l'objet json...
La variable PHP « $value », c'est un objet json ?
Non c'est uns String, que je récupère dans une boucle en faisant un
foreach ($json as $cle=>$value)
où $json est mon article.
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
Tu es sûr de $value ? Quelles sont les valeurs des quatre premiers
octets de cette chaîne ? Et sa longueur... 17 ou 23 ?
Comme je ne sais pas comment tu passes de l'objet json à la variable
$value, le bug pourrait être aussi bien dans cette partie-là que dans
la fonction mb_encode_mimeheader. C'était pour localiser le problème
que je te demandais le contenu de la variable si possible, ou au moins
sa longueur (en donnant le résultat exact correspondant).
Post by unknown
J'ai utilisé mb_encode_mimeheader($value, "UTF-8", "Q", " \n")
Oui, j'ai bien vu le résultat. Mais j'aurais voulu connaître la
source donnant ce résultat.
En clair, donner à la fois les deux résultats suivants ;
bin2hex($value)
c3a9c3a9c3a9
Post by Olivier Miakinen
et
mb_encode_mimeheader($value, "UTF-8", "Q", " \n")
=?UTF-8?Q?=C3=83=C2=A9=C3=83=C2=A9=C3=83=C2=A9?=

Chaine encodée : ééé
Olivier Miakinen
2013-03-31 21:09:26 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
En clair, donner à la fois les deux résultats suivants ;
bin2hex($value)
c3a9c3a9c3a9
Post by Olivier Miakinen
et
mb_encode_mimeheader($value, "UTF-8", "Q", " \n")
=?UTF-8?Q?=C3=83=C2=A9=C3=83=C2=A9=C3=83=C2=A9?=
Merci. Cela confirme que c'est la fonction mb_encode_mimeheader qui est
en cause : elle encode bien en UTF-8 mais suppose que la chaîne d'entrée
est en ISO-8859-1.

Peut-être faut-il préciser l'inverse avec mb_internal_encoding.

1) Que répond « echo mb_internal_encoding(); » ?
2) Est-ce que ça marche mieux après « mb_internal_encoding("UTF-8"); » ?
Julien Arlandis
2013-03-31 22:01:36 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
En clair, donner à la fois les deux résultats suivants ;
bin2hex($value)
c3a9c3a9c3a9
Post by Olivier Miakinen
et
mb_encode_mimeheader($value, "UTF-8", "Q", " \n")
=?UTF-8?Q?=C3=83=C2=A9=C3=83=C2=A9=C3=83=C2=A9?=
Merci. Cela confirme que c'est la fonction mb_encode_mimeheader qui est
en cause : elle encode bien en UTF-8 mais suppose que la chaîne d'entrée
est en ISO-8859-1.
Peut-être faut-il préciser l'inverse avec mb_internal_encoding.
1) Que répond « echo mb_internal_encoding(); » ?
ISO-8859
Post by Olivier Miakinen
2) Est-ce que ça marche mieux après « mb_internal_encoding("UTF-8"); » ?
mb_encode_mimeheader($value, mb_internal_encoding(), "Q", " \n")

ça a marché :
Subject: =?ISO-8859-1?Q?=C3=A9=C3=A9=C3=A9?=

Merci, je crois que le problème d'encodage est réglé pour la conversion
HTTP <-> HTTP-NNTP
unknown
2013-03-31 13:39:34 UTC
Permalink
Je voudrais supprimer les caractères "<" et ">" autour du Message-ID là
c'est facile je fais :

elseif($champ === "message-id")
{
$value = trim($value);
$article->{'MessageID'} = substr($value, 1, strlen($value)-2);
}

Pour les References c'est un peu plus compliqué, non seulement je dois
virer les < > et je dois stocker les MessageID dans un tableau.

Pour l'instant, j'ai provisoirement écrit ceci :

$value = trim($value);
$refs = explode(" ", $value);
foreach($refs as $ref)
{
$ref = substr($value, 1, strlen($ref)-2);
}

$article->{'References'} = $refs;

Si t'as une meilleure solution je prends.
Olivier Miakinen
2013-03-31 20:10:41 UTC
Permalink
Post by unknown
Je voudrais supprimer les caractères "<" et ">" autour du Message-ID
[...]
Pour les References c'est un peu plus compliqué, non seulement je dois
virer les < > et je dois stocker les MessageID dans un tableau.
$value = trim($value);
$refs = explode(" ", $value);
foreach($refs as $ref)
{
$ref = substr($value, 1, strlen($ref)-2);
}
$article->{'References'} = $refs;
Si t'as une meilleure solution je prends.
Si tu n'as pas à vérifier que la syntaxe est respectée, pourquoi ne pas
faire un preg_split avec "/[<>, \t]+/" comme pattern, et avec le flag
PREG_SPLIT_NO_EMPTY ?
Olivier Miakinen
2013-03-30 21:53:38 UTC
Permalink
Post by Eric Demeester
Post by unknown
J'ai corrigé pas mal de choses, sauf pour le retour chariot pour imposer
une limite de taille aux lignes du header. Sauf que je sais pas trop
comment le positionner, y aurait pas une méthode PHP qui gère ça pour
les mails ?
http://www.manuelphp.com/php/function.wordwrap.php
Oui, mais il faudra faire autrement dans le cas d'un encodage RFC2047.
Post by Eric Demeester
Intéressant aussi pour forcer les retour-chariot dans la rédaction des
articles.
Oui aussi, à faire lors de la phase de rédaction et pas au moment de
l'envoi, afin que l'auteur d'un article sache exactement où ça coupe
et qu'il puisse éventuellement corriger (sauf si format flowed, car là
l'utilisateur s'en remet entièrement au logiciel).
Post by Eric Demeester
Contrairement à Olivier, je préconise plutôt 72 caractères, ça permet
l'indentation de plusieurs niveaux de citations, mais c'est limite
pinaillage :)
Je parlais des entêtes, lesquels n'ont aucune raison d'être cités !
Olivier Miakinen
2013-03-30 15:48:31 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Toi qui est calé en expressions régulières tu pourrais m'extraire le
charset du content-Type en tenant compte de toutes les différences de
déclaration, guillemets, pas guillemet, espace ou autres...
Voyons voir...
<cit. RFC 2045[1]>
5.1. Syntax of the Content-Type Header Field
[...]
value := token / quoted-string
token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
or tspecials>
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
</cit.>
Voici la liste des charsets enregistrés auprès de l'IANA :
http://www.iana.org/assignments/character-sets/character-sets.xml

À la date du 23 janvier 2013, les seuls caractères utilisés sont :
- les lettres majuscules et minuscules A-Z et a-z ;
- les chiffres 0-9 ;
- les six caractères « - », « _ », « : », « . », « ( » et « ) ».

Il y a malheureusement trois caractères qui font partie de tspecials,
ce qui empêcherait de traiter de la même manière les charsets avec
et sans guillemets. Seulement :
- deux d'entre eux sont les parenthèses qu'on ne trouve que dans le
seul charset "NF_Z_62-010_(1973)" ;
- l'autre est le deux points, qui précède aussi une date ;
et dans tous les cas il existe un alias sans parenthèses ni deux-points.

On va donc dire que les seuls caractères à considérer sont les suivants
[A-Za-z0-9\-_.]
et je ne prends pas en compte la syntaxe quoted-pair.

Par ailleurs, je fais l'hypothèse qu'on ne peut pas avoir de commentaire
juste avant le « charset », ni avant ou après le signe « = ». Mais en
revanche je traite le cas où l'on peut avoir du « folding white space ».

Bon, ça devrait donner un truc comme ça, à essayer :

$token = "[A-Za-z0-9\\-_.]+";
$optFWS = "(?:[ \t]\n?)*";
$pattern = "charset{$optFWS}={$optFWS}(\"?)({$token})\\1";
$regexp = "/;{$optFWS}{$pattern}{$optFWS}(?:[(;]|$)/";
if (preg_match($regexp, $contenttype, $matches)) {
$charset = $matches[2];
}

Cordialement,
--
Olivier Miakinen
unknown
2013-04-01 00:11:41 UTC
Permalink
Post by Olivier Miakinen
Post by Olivier Miakinen
Post by unknown
Toi qui est calé en expressions régulières tu pourrais m'extraire le
charset du content-Type en tenant compte de toutes les différences de
déclaration, guillemets, pas guillemet, espace ou autres...
Voyons voir...
<cit. RFC 2045[1]>
5.1. Syntax of the Content-Type Header Field
[...]
value := token / quoted-string
token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
or tspecials>
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
</cit.>
http://www.iana.org/assignments/character-sets/character-sets.xml
- les lettres majuscules et minuscules A-Z et a-z ;
- les chiffres 0-9 ;
- les six caractères « - », « _ », « : », « . », « ( » et « ) ».
Il y a malheureusement trois caractères qui font partie de tspecials,
ce qui empêcherait de traiter de la même manière les charsets avec
- deux d'entre eux sont les parenthèses qu'on ne trouve que dans le
seul charset "NF_Z_62-010_(1973)" ;
- l'autre est le deux points, qui précède aussi une date ;
et dans tous les cas il existe un alias sans parenthèses ni deux-points.
On va donc dire que les seuls caractères à considérer sont les suivants
[A-Za-z0-9\-_.]
et je ne prends pas en compte la syntaxe quoted-pair.
Par ailleurs, je fais l'hypothèse qu'on ne peut pas avoir de commentaire
juste avant le « charset », ni avant ou après le signe « = ». Mais en
revanche je traite le cas où l'on peut avoir du « folding white space ».
$token = "[A-Za-z0-9\\-_.]+";
$optFWS = "(?:[ \t]\n?)*";
$pattern = "charset{$optFWS}={$optFWS}(\"?)({$token})\\1";
$regexp = "/;{$optFWS}{$pattern}{$optFWS}(?:[(;]|$)/";
if (preg_match($regexp, $contenttype, $matches)) {
$charset = $matches[2];
}
Cordialement,
Ça ne marche pas, chaine vide. Et je suis de nouveau embêté je ne
parviens pas à récupérer le charset dans tous les cas... Sans n'avoir
rien modifié ça ne marche plus...
Olivier Miakinen
2013-04-01 08:00:44 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
$token = "[A-Za-z0-9\\-_.]+";
$optFWS = "(?:[ \t]\n?)*";
$pattern = "charset{$optFWS}={$optFWS}(\"?)({$token})\\1";
$regexp = "/;{$optFWS}{$pattern}{$optFWS}(?:[(;]|$)/";
if (preg_match($regexp, $contenttype, $matches)) {
$charset = $matches[2];
}
Ça ne marche pas, chaine vide.
Avec quelle chaîne de départ ?

Autre chose. J'ai vu dans tes exemples que parfois tu écris \n et
parfois \r\n. Pour bien faire, il faudrait que tu ne manipules que
des \n, et que ce soit seulement à la lecture ou à l'envoi vers le
réseau qu'ils soient transformés (respectivement) depuis ou vers
\r\n.
unknown
2013-04-01 08:18:35 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
$token = "[A-Za-z0-9\\-_.]+";
$optFWS = "(?:[ \t]\n?)*";
$pattern = "charset{$optFWS}={$optFWS}(\"?)({$token})\\1";
$regexp = "/;{$optFWS}{$pattern}{$optFWS}(?:[(;]|$)/";
if (preg_match($regexp, $contenttype, $matches)) {
$charset = $matches[2];
}
Ça ne marche pas, chaine vide.
Avec quelle chaîne de départ ?
Autre chose. J'ai vu dans tes exemples que parfois tu écris \n et
parfois \r\n. Pour bien faire, il faudrait que tu ne manipules que
des \n, et que ce soit seulement à la lecture ou à l'envoi vers le
réseau qu'ils soient transformés (respectivement) depuis ou vers
\r\n.
Ben c'est ce que je fais...

La chaine qui marche pas :
Content-Type: text/plain; charset=UTF-8; format=flowed

Il reste deux problèmes : le charset à bien récupérer et les "_" dans
certains titres.
Eric Demeester
2013-04-01 10:16:39 UTC
Permalink
Julien Arlandis (Mon, 01 Apr 2013 10:18:35 +0200 - fr.comp.lang.php) :

Salut,
Post by unknown
Content-Type: text/plain; charset=UTF-8; format=flowed
Il reste deux problèmes : le charset à bien récupérer et les "_" dans
certains titres.
Et un troisième (qui n'en pas réellement un, je te le concède) :

Pourquoi t'obstiner à utiliser « format=flowed », facultatitif, qui
casse les pieds à certains logiciels de lecture, et est de plus inutile
puisque grace à wordwrap, tu passes de toute façon à la ligne à 75
caractères ?
--
Eric
Julien Arlandis
2013-04-01 17:27:21 UTC
Permalink
Post by yamo'
Salut,
Post by unknown
Content-Type: text/plain; charset=UTF-8; format=flowed
Il reste deux problèmes : le charset à bien récupérer et les "_" dans
certains titres.
Pourquoi t'obstiner à utiliser « format=flowed », facultatitif, qui
casse les pieds à certains logiciels de lecture, et est de plus inutile
puisque grace à wordwrap, tu passes de toute façon à la ligne à 75
caractères ?
Oui, à vrai dire je ne sais pas ce que signifie cette option, je la met
car j'ai bêtement recopié les headers par défaut de mon thunderbird,
mais si tu me dis que c'est mal je la retire sur le champ, je suis
conciliant moi ... :-)
Olivier Miakinen
2013-04-01 18:30:16 UTC
Permalink
Post by Julien Arlandis
Post by unknown
format=flowed
Oui, à vrai dire je ne sais pas ce que signifie cette option, je la met
car j'ai bêtement recopié les headers par défaut de mon thunderbird,
mais si tu me dis que c'est mal je la retire sur le champ, je suis
conciliant moi ... :-)
Tant que tu ne sais pas ce que c'est, retire-là. Tu pourras l'ajouter
plus tard, sur option de l'utilisateur.
unknown
2013-04-01 18:33:24 UTC
Permalink
Post by Olivier Miakinen
Post by Julien Arlandis
Post by unknown
format=flowed
Oui, à vrai dire je ne sais pas ce que signifie cette option, je la met
car j'ai bêtement recopié les headers par défaut de mon thunderbird,
mais si tu me dis que c'est mal je la retire sur le champ, je suis
conciliant moi ... :-)
Tant que tu ne sais pas ce que c'est, retire-là. Tu pourras l'ajouter
plus tard, sur option de l'utilisateur.
Faut dire aussi que je ne suis pas en train de coder un client NNTP mais
un nouveau protocole qui se veut compatible avec NNTP, les ajustements
et les réglages se feront assez facilement par la suite, pour l'instant
je suis plus dans la réalisation d'une preuve de concept, mais quoi
qu'il arrive le résultat final sera je l'espère irréprochable.
Eric Demeester
2013-04-02 14:22:22 UTC
Permalink
Julien Arlandis (Mon, 01 Apr 2013 19:27:21 +0200 - fr.comp.lang.php) :

Bonjour Julien,
Post by Julien Arlandis
Oui, à vrai dire je ne sais pas ce que signifie cette option,
« format=flowed » permet d'une part à l'auteur d'écrire au kilomètre
sans se préoccuper des passages à la ligne (mais puisque wordwrap()
passe derrière -- voire pendant -- la rédaction dans ton cas, on s'en
moque) ; d'autre part au logiciel lecteur de reformater le texte à la
volée si on modifie le taille de la zone d'écran assignée à l'affichage
du message.

Mon logiciel est organisé de telle façon qu'il offre, par effet de bord,
une large taille à la zone consacrée à l'affichage du message, avec pour
conséquence, si l'article que je lis n'a pas été « wordwrappé » avant
envoi, de devoir lire des lignes kilométriques, ce qui est
particulièrement désagréable.

Si tu ne visualises pas trop ce que je veux dire, je peux te faire des
copies d'écran.

Mais comme conseillé par Olivier, plutôt que d'approfondir ce point
secondaire, juste vire l'option pour le moment, et concentre-toi sur les
vraies difficultés, car elles ne manquent pas, et ça ne va faire que
croître et embellir au fur et à mesur de l'avancement de ton projet :)

Comme d'hab', bétises possibles, corrections et compléments bienvenus.
--
Eric
Julien Arlandis
2013-04-02 17:09:07 UTC
Permalink
Post by Eric Demeester
Bonjour Julien,
Post by Julien Arlandis
Oui, à vrai dire je ne sais pas ce que signifie cette option,
« format=flowed » permet d'une part à l'auteur d'écrire au kilomètre
sans se préoccuper des passages à la ligne (mais puisque wordwrap()
passe derrière -- voire pendant -- la rédaction dans ton cas, on s'en
moque) ; d'autre part au logiciel lecteur de reformater le texte à la
volée si on modifie le taille de la zone d'écran assignée à l'affichage
du message.
Mon logiciel est organisé de telle façon qu'il offre, par effet de bord,
une large taille à la zone consacrée à l'affichage du message, avec pour
conséquence, si l'article que je lis n'a pas été « wordwrappé » avant
envoi, de devoir lire des lignes kilométriques, ce qui est
particulièrement désagréable.
Si tu ne visualises pas trop ce que je veux dire, je peux te faire des
copies d'écran.
Je vois très bien. Actuellement c'est le serveur qui fait le wordwrap je
suppose que c'est le travail exclusif du client?
Concernant les citations, je vois sur thunderbird que le premier > placé
manuellement en début de chaque ligne est précédé par un espace de façon
à le différencier de la citation. Y a t-il d'autres solutions pour les
citations, c'est quoi la règle?
Post by Eric Demeester
Mais comme conseillé par Olivier, plutôt que d'approfondir ce point
secondaire, juste vire l'option pour le moment, et concentre-toi sur les
vraies difficultés, car elles ne manquent pas, et ça ne va faire que
croître et embellir au fur et à mesur de l'avancement de ton projet :)
Comme d'hab', bétises possibles, corrections et compléments bienvenus.
Olivier Miakinen
2013-04-02 20:30:03 UTC
Permalink
[...] Actuellement c'est le serveur qui fait le wordwrap je
suppose que c'est le travail exclusif du client?
Exclusif, oui.

Il me semble que, sauf exception rarissime, un serveur ne doit rien
enlever ni modifier, il ne peut que rajouter des entêtes.

Mais comme dit Éric (je cite) : bétises possibles, corrections et
compléments bienvenus.
Concernant les citations, je vois sur thunderbird que le premier > placé
manuellement en début de chaque ligne est précédé par un espace de façon
à le différencier de la citation.
Seulement en format flowed, ce qui est d'ailleurs l'un des bugs de ce
format censé être compatible avec le format non flowed.


Comme visiblement ça te gêne pour connaître le format normal, voici
comment configurer ton Thunderbird pour virer ce format, aussi bien
en lecture qu'en écriture.

1) Tu lances l'éditeur de configuration comme indiqué ici :
https://support.mozillamessaging.com/fr/kb/editeur-de-configuration

2) Tu mets « flowed » comme filtre pour sélectionner les lignes
appropriées.

3) Tu double-cliques sur les valeurs pour obtenir :
mailnews.display.disable_format_flowed_support true
mailnews.send_plaintext_flowed false

C'est tout, il n'est même pas nécessaire de relancer Thunderbird.
Y a t-il d'autres solutions pour les
citations, c'est quoi la règle?
Certains mettent d'autres caractères que « > », parfois pour contourner
un bug de logiciels de lecture à haute voix pour aveugles. D'autres
ajoutent devant le « > » les initiales de la personne à qui ils
répondent. Mais le plus standard, c'est ce que fait par exemple
citation de premier niveau
citation de deuxième niveau
citation de troisième niveau
Attention à ne pas reproduire le bug d'Outlook Express consistant à
refaire un « wordwrap » sur les citations, ce qui a pour effet
d'alterner des lignes longues et des lignes courtes.
--
Olivier Miakinen
unknown
2013-04-02 20:35:36 UTC
Permalink
Post by Olivier Miakinen
[...] Actuellement c'est le serveur qui fait le wordwrap je
suppose que c'est le travail exclusif du client?
Exclusif, oui.
Il me semble que, sauf exception rarissime, un serveur ne doit rien
enlever ni modifier, il ne peut que rajouter des entêtes.
J'ai choppé cette fonction ici :
http://stackoverflow.com/questions/8423994/jquery-equivalent-of-phps-wordwrap

Pas encore testée, mais ton avis est le bienvenu.

function wordwrap( str, width, brk, cut ) {
brk = brk || '\n';
width = width || 75;
cut = cut || false;

if (!str) { return str; }

var regex = '.{1,' +width+ '}(\\s|$)' + (cut ? '|.{' +width+
'}|.+$' : '|\\S+?(\\s|$)');

return str.match( RegExp(regex, 'g') ).join( brk );
}
Post by Olivier Miakinen
mailnews.display.disable_format_flowed_support true
mailnews.send_plaintext_flowed false
C'est tout, il n'est même pas nécessaire de relancer Thunderbird.
Merci je teste.
Post by Olivier Miakinen
Y a t-il d'autres solutions pour les
citations, c'est quoi la règle?
Certains mettent d'autres caractères que « > », parfois pour contourner
un bug de logiciels de lecture à haute voix pour aveugles. D'autres
ajoutent devant le « > » les initiales de la personne à qui ils
répondent. Mais le plus standard, c'est ce que fait par exemple
citation de premier niveau
citation de deuxième niveau
citation de troisième niveau
Attention à ne pas reproduire le bug d'Outlook Express consistant à
refaire un « wordwrap » sur les citations, ce qui a pour effet
d'alterner des lignes longues et des lignes courtes.
Vu que le wordwrap est fait à la fin comment ne pas le faire sur les
citations ?
Eric Demeester
2013-04-02 20:37:06 UTC
Permalink
Post by Julien Arlandis
Je vois très bien. Actuellement c'est le serveur qui fait le wordwrap je
suppose que c'est le travail exclusif du client?
Puisque le serveur fait le wordwrap avant envoi, le client n'a rien à
faire. C'est si le serveur ne fait pas le wordwrap et que
« format=flowed » est renseigné que le risque existe sur le logiciel
client d'avoir un texte difficile à lire à cause des lignes trop
longues.

D'où la suggestion réitérée, puisque ton serveur fait bien son travail
de formatage des messages avant envoi, de supprimer ce « format=flowed »
superflu de tes en-têtes.
Post by Julien Arlandis
Concernant les citations, je vois sur thunderbird que le premier > placé
manuellement en début de chaque ligne est précédé par un espace de façon
à le différencier de la citation. Y a t-il d'autres solutions pour les
citations, c'est quoi la règle?
La règle, appliquée d'ailleurs par mon logiciel comme tu peux le
constater en lisant cet article, est la suivante :

Toute citation de la prose du contributeur auquel on répond doit être
précédée du signe « > », sans espace avant. S'il y a des discussions
imbriquées avec plusieurs niveaux de citations, on ajoute aussi le
« > », pour pouvoir comprendre qui a répondu à qui.

Euh, je ne sais pas si je suis très clair...

Tiens, je reprends un article où tu répondais à Olivier, ça donnait :

-------------------------------------------------------------------------
Post by Julien Arlandis
Post by Julien Arlandis
Post by unknown
format=flowed
Oui, à vrai dire je ne sais pas ce que signifie cette option, je la met
car j'ai bêtement recopié les headers par défaut de mon thunderbird,
mais si tu me dis que c'est mal je la retire sur le champ, je suis
conciliant moi ... :-)
Tant que tu ne sais pas ce que c'est, retire-là. Tu pourras l'ajouter
plus tard, sur option de l'utilisateur.
Faut dire aussi que je ne suis pas en train de coder un client NNTP mais
un nouveau protocole qui se veut compatible avec NNTP, les ajustements
et les réglages se feront assez facilement par la suite, pour l'instant
je suis plus dans la réalisation d'une preuve de concept, mais quoi
qu'il arrive le résultat final sera je l'espère irréprochable.
-------------------------------------------------------------------------

Tu vois clairement le niveau d'imbrication des questions-réponses en
fonction du nombre de « > » sur la gauche.

Il manque quand même au début un
Post by Julien Arlandis
Post by Julien Arlandis
Tartempion écrivait,
avant la ligne suivante, pour qu'on comprenne qui s'exprimait dans la
Post by Julien Arlandis
Post by Julien Arlandis
Post by unknown
format=flowed
de niveau 3.

Je ne sais toujours pas si je suis très clair, et ça commence à être pas
mal HS par rpport au PHP, mais comme tu développes en PHP, je laisse
quand même la discussion se poursuivre ici.
--
Eric
Stéphane Catteau
2013-04-01 10:18:41 UTC
Permalink
Post by Olivier Miakinen
$token = "[A-Za-z0-9\\-_.]+";
^^^^

De "\" à "_" au lieu du "\", "-" et "_" désiré.
--
17/06/1969 - 18/01/2011

Repose en paix mon amour :'(
Olivier Miakinen
2013-04-01 18:28:56 UTC
Permalink
Post by Stéphane Catteau
Post by Olivier Miakinen
$token = "[A-Za-z0-9\\-_.]+";
^^^^
De "\" à "_" au lieu du "\", "-" et "_" désiré.
Non, parce que le \\ est interprété par la syntaxe de chaînes de
caractères PHP, et il devient donc un simple \. Il est exact que
j'aurais pu écrire un seul \ car \- n'a pas de signification
spéciale, et que dans ce cas c'est équivalent à \\-, mais c'est
moins clair : dans certains langages, "\-" est équivalent à "-"
plutôt qu'à "\\-".

Pour faire de "\" à "_" il faut écrire "[\\\\-_]"
Stéphane Catteau
2013-04-02 19:18:28 UTC
Permalink
Post by Olivier Miakinen
Post by Stéphane Catteau
Post by Olivier Miakinen
$token = "[A-Za-z0-9\\-_.]+";
^^^^
De "\" à "_" au lieu du "\", "-" et "_" désiré.
Non, parce que le \\ est interprété par la syntaxe de chaînes de
caractères PHP, et il devient donc un simple \.
D'où l'utilité de mettre les chaînes comme ça entre simples quotes.
Autrement tu finis par y perdre ton latin.
--
17/06/1969 - 18/01/2011

Repose en paix mon amour :'(
Olivier Miakinen
2013-04-02 21:38:51 UTC
Permalink
Post by Stéphane Catteau
Post by Olivier Miakinen
Post by Stéphane Catteau
Post by Olivier Miakinen
$token = "[A-Za-z0-9\\-_.]+";
^^^^
De "\" à "_" au lieu du "\", "-" et "_" désiré.
Non, parce que le \\ est interprété par la syntaxe de chaînes de
caractères PHP, et il devient donc un simple \.
D'où l'utilité de mettre les chaînes comme ça entre simples quotes.
Autrement tu finis par y perdre ton latin.
Mais je perds la possibilité d'inclure des variables, et justement je
m'en étais servi pour simplifier la compréhension de la regexp. Et
d'ailleurs ça ne suffit pas forcément : pour écrire deux \ de suite,
il faut les quadrupler aussi bien entre guillemets simples qu'entre
guillemets doubles.

D'un autre côté, comme je le disais je pouvais très bien écrire \-
entre guillemets doubles, de la même manière que j'ai écrit \1 un
peu plus loin.

Olivier Miakinen
2013-04-01 18:16:20 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
$token = "[A-Za-z0-9\\-_.]+";
$optFWS = "(?:[ \t]\n?)*";
$pattern = "charset{$optFWS}={$optFWS}(\"?)({$token})\\1";
$regexp = "/;{$optFWS}{$pattern}{$optFWS}(?:[(;]|$)/";
if (preg_match($regexp, $contenttype, $matches)) {
$charset = $matches[2];
}
Ça ne marche pas, chaine vide.
Avec quelle chaîne de départ ?
Autre chose. J'ai vu dans tes exemples que parfois tu écris \n et
parfois \r\n. Pour bien faire, il faudrait que tu ne manipules que
des \n, et que ce soit seulement à la lecture ou à l'envoi vers le
réseau qu'ils soient transformés (respectivement) depuis ou vers
\r\n.
Ben c'est ce que je fais...
Content-Type: text/plain; charset=UTF-8; format=flowed
Je viens d'essayer ici :
http://www.thatsquality.com/apps/regex

pattern :
/;(?:[ \t]\n?)*charset(?:[ \t]\n?)*=(?:[
\t]\n?)*("?)([A-Za-z0-9\-_.]+)\1(?:[ \t]\n?)*(?:[(;]|$)/

search text :
Content-Type: text/plain; charset=UTF-8; format=flowed

Results :
$matches[0] = ; charset=UTF-8;
$matches[1] =
$matches[2] = UTF-8

$matches = array();
$pattern = '/;(?:[ \t]\n?)*charset(?:[ \t]\n?)*=(?:[
\t]\n?)*("?)([A-Za-z0-9\-_.]+)\1(?:[ \t]\n?)*(?:[(;]|$)/';
$text = 'Content-Type: text/plain; charset=UTF-8; format=flowed
';
preg_match($pattern, $text, $matches);


Note que c'est un peu différent que dans un vrai programme, car les \t
et \n sont mis en deux caractères, comme si j'avais écrit \\t et \\n
dans $optFWS.
Post by unknown
Il reste deux problèmes : le charset à bien récupérer et les "_" dans
certains titres.
Dans du QP ? cela doit devenir des espaces à la lecture.
Julien Arlandis
2013-04-01 18:26:23 UTC
Permalink
Post by Olivier Miakinen
$matches[0] = ; charset=UTF-8;
$matches[1] =
$matches[2] = UTF-8
$matches = array();
$pattern = '/;(?:[ \t]\n?)*charset(?:[ \t]\n?)*=(?:[
\t]\n?)*("?)([A-Za-z0-9\-_.]+)\1(?:[ \t]\n?)*(?:[(;]|$)/';
$text = 'Content-Type: text/plain; charset=UTF-8; format=flowed
';
preg_match($pattern, $text, $matches);
C'est ton dernier mot ?
Olivier Miakinen
2013-04-01 18:33:15 UTC
Permalink
Post by Julien Arlandis
Post by Olivier Miakinen
$matches[0] = ; charset=UTF-8;
$matches[1] =
$matches[2] = UTF-8
$matches = array();
$pattern = '/;(?:[ \t]\n?)*charset(?:[ \t]\n?)*=(?:[
\t]\n?)*("?)([A-Za-z0-9\-_.]+)\1(?:[ \t]\n?)*(?:[(;]|$)/';
$text = 'Content-Type: text/plain; charset=UTF-8; format=flowed
';
preg_match($pattern, $text, $matches);
C'est ton dernier mot ?
Il faudra que je monte vraiment mon serveur PHP, ou que j'essaye sur mon
site (en friche depuis des années). En attendant, viens donc afficher
ici le contenu du $regexp, pour voir si c'est différent du $pattern
ci-dessus.
unknown
2013-04-01 18:36:27 UTC
Permalink
Post by Olivier Miakinen
Post by Julien Arlandis
Post by Olivier Miakinen
$matches[0] = ; charset=UTF-8;
$matches[1] =
$matches[2] = UTF-8
$matches = array();
$pattern = '/;(?:[ \t]\n?)*charset(?:[ \t]\n?)*=(?:[
\t]\n?)*("?)([A-Za-z0-9\-_.]+)\1(?:[ \t]\n?)*(?:[(;]|$)/';
$text = 'Content-Type: text/plain; charset=UTF-8; format=flowed
';
preg_match($pattern, $text, $matches);
C'est ton dernier mot ?
Il faudra que je monte vraiment mon serveur PHP, ou que j'essaye sur mon
site (en friche depuis des années). En attendant, viens donc afficher
ici le contenu du $regexp, pour voir si c'est différent du $pattern
ci-dessus.
Si t'es sur un linux, rien ne t'empêche d'installer php5 en mode
console, ça te prendra à peine le temps de lire mon message avec aptitude.
Olivier Miakinen
2013-04-01 19:48:33 UTC
Permalink
Post by unknown
Si t'es sur un linux, rien ne t'empêche d'installer php5 en mode
console, ça te prendra à peine le temps de lire mon message avec aptitude.
Excellente idée, je viens de le faire, et j'ai testé mon programme.
Chez moi ça marche. ©

$ cat arlandis.php
<?php

$token = "[A-Za-z0-9\\-_.]+";
$optFWS = "(?:[ \t]\n?)*";
$pattern = "charset{$optFWS}={$optFWS}(\"?)({$token})\\1";
$regexp = "/;{$optFWS}{$pattern}{$optFWS}(?:[(;]|$)/";
$contenttype = "Content-Type: text/plain; charset=UTF-8; format=flowed";
if (preg_match($regexp, $contenttype, $matches)) {
$charset = $matches[2];
}
echo "pattern : $pattern\n";
echo "contenttype : $contenttype\n";
echo "charset : $charset\n";

?>
$ php arlandis.php
pattern : charset(?:[ ]
?)*=(?:[ ]
?)*("?)([A-Za-z0-9\-_.]+)\1
contenttype : Content-Type: text/plain; charset=UTF-8; format=flowed
charset : UTF-8
$
Julien Arlandis
2013-04-01 20:09:58 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Si t'es sur un linux, rien ne t'empêche d'installer php5 en mode
console, ça te prendra à peine le temps de lire mon message avec aptitude.
Excellente idée, je viens de le faire, et j'ai testé mon programme.
Chez moi ça marche. ©
Merci, j'ai rajouté ton bout de code dans le projet.
Olivier Miakinen
2013-04-01 22:47:19 UTC
Permalink
Post by Julien Arlandis
Merci, j'ai rajouté ton bout de code dans le projet.
Note que j'ai oublié de rajouter le flag /i pour le cas où quelqu'un
écrirait CHARSET ou ChArSeT au lieu de charset.
unknown
2013-04-01 18:38:43 UTC
Permalink
Post by Olivier Miakinen
Post by Julien Arlandis
Post by Olivier Miakinen
$matches[0] = ; charset=UTF-8;
$matches[1] =
$matches[2] = UTF-8
$matches = array();
$pattern = '/;(?:[ \t]\n?)*charset(?:[ \t]\n?)*=(?:[
\t]\n?)*("?)([A-Za-z0-9\-_.]+)\1(?:[ \t]\n?)*(?:[(;]|$)/';
$text = 'Content-Type: text/plain; charset=UTF-8; format=flowed
';
preg_match($pattern, $text, $matches);
C'est ton dernier mot ?
Il faudra que je monte vraiment mon serveur PHP, ou que j'essaye sur mon
site (en friche depuis des années). En attendant, viens donc afficher
ici le contenu du $regexp, pour voir si c'est différent du $pattern
ci-dessus.
Pour l'instant ça a l'air de marcher avec ce nouveau pattern. Maintenant
le dernier soucis c'est :
$article->{'Subject'} = utf8_encode(mb_decode_mimeheader($subject));
qui affiche certaines fois des "_" à la place des espaces.
Si je faisais un explode($subject, " ") et un
utf8_encode(mb_decode_mimeheader()) sur chacune des valeurs du tableau ?
Olivier Miakinen
2013-04-01 19:38:50 UTC
Permalink
Post by unknown
Pour l'instant ça a l'air de marcher avec ce nouveau pattern. Maintenant
$article->{'Subject'} = utf8_encode(mb_decode_mimeheader($subject));
^^^^^^^^^^^
Après avoir fait mb_internal_encoding('UTF-8'), ça te donne toujours un
résultat en ISO-8859-1 ???
Post by unknown
qui affiche certaines fois des "_" à la place des espaces.
Si je faisais un explode($subject, " ") et un
utf8_encode(mb_decode_mimeheader()) sur chacune des valeurs du tableau ?
Tu as raison, d'après la doc cette fonction serait à appeler sur un seul
« encoded-word ». Mais il faudra faire gaffe aux espaces à jeter et à
ceux à conserver. Comme je sais que tu ne liras pas le RFC 2047, je vais
tâcher de le faire.
unknown
2013-04-01 20:19:34 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Pour l'instant ça a l'air de marcher avec ce nouveau pattern. Maintenant
$article->{'Subject'} = utf8_encode(mb_decode_mimeheader($subject));
^^^^^^^^^^^
Après avoir fait mb_internal_encoding('UTF-8'), ça te donne toujours un
résultat en ISO-8859-1 ???
Si je fais directement
mb_internal_encoding('UTF-8');
$article->{'Subject'} = mb_decode_mimeheader($subject);

Le résultat est le même, j'ai toujours des "_" à la place des espaces.
Post by Olivier Miakinen
Post by unknown
qui affiche certaines fois des "_" à la place des espaces.
Si je faisais un explode($subject, " ") et un
utf8_encode(mb_decode_mimeheader()) sur chacune des valeurs du tableau ?
Tu as raison, d'après la doc cette fonction serait à appeler sur un seul
« encoded-word ». Mais il faudra faire gaffe aux espaces à jeter et à
ceux à conserver. Comme je sais que tu ne liras pas le RFC 2047, je vais
tâcher de le faire.
Je vais bien devoir les lire à un moment si je veux rédiger la mienne
;-) bon cela dit je ne sais pas trop comment m'y prendre...
Merci de ton aide précieuse dans tous les cas.
Olivier Miakinen
2013-04-01 22:53:43 UTC
Permalink
Post by unknown
Si je fais directement
mb_internal_encoding('UTF-8');
$article->{'Subject'} = mb_decode_mimeheader($subject);
Le résultat est le même, j'ai toujours des "_" à la place des espaces.
Tu as raison, la fonction est foireuse, je vais la réécrire. En
attendant, voici déjà une fonction que tu peux appeler sur un
entête complet (y compris éventuellement des FWS) et qui traite
encoded_word par encoded-word, il faudra juste remplacer ensuite
mb_decode_mimeheader par la fonction corrigée.

----------------------------------------------------------------------
function rfc2047_decode($header_value)
{
$words = preg_split('/[ \t\n]/', $header_value,
NULL, PREG_SPLIT_NO_EMPTY);
$was_ew = FALSE; /* TRUE après un encoded_word */
$result = ""; /* résultat du décodage */

foreach ($words as $word) {
$is_ew = FALSE;
if (strlen($word) <= 75) {
/* RFC 2047 : an encoded-word can't exceed 75 characters */
$dec_word = mb_decode_mimeheader($word);
if ($dec_word != $word) $is_ew = TRUE;
}
if ($was_ew && $is_ew) {
/* entre deux encoded-words on n'insère pas d'espace */
} else if ($result != '') {
/* on n'est pas en début de ligne : ajoute une espace */
$result .= ' ';
}
$result .= ($is_ew ? $dec_word : $word);
$was_ew = $is_ew;
}
return $result;
}
----------------------------------------------------------------------

Je l'ai testée :
----------------------------------------------------------------------
function test($header_value)
{
echo "<<< \n";
echo $header_value . "\n";
echo rfc2047_decode($header_value) . "\n";
echo ">>> \n";
}

mb_internal_encoding('UTF-8');
test('From: =?US-ASCII?Q?Keith_Moore?= <***@cs.utk.edu>');
test('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <***@dkuug.dk>');
test('CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <***@vm1.ulg.ac.be>');
test('Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?='
. "\n " . '=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=');
----------------------------------------------------------------------

Résultat :
----------------------------------------------------------------------
<<<
From: =?US-ASCII?Q?Keith_Moore?= <***@cs.utk.edu>
From: Keith_Moore <***@cs.utk.edu>
<<<
To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <***@dkuug.dk>
To: Keld_Jørn_Simonsen <***@dkuug.dk>
<<<
CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <***@vm1.ulg.ac.be>
CC: André Pirard <***@vm1.ulg.ac.be>
<<<
Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=
Subject: If you can read this you understand the example.
----------------------------------------------------------------------
Olivier Miakinen
2013-04-01 23:03:45 UTC
Permalink
Post by Olivier Miakinen
Tu as raison, la fonction est foireuse, je vais la réécrire. En
attendant, voici déjà une fonction que tu peux appeler sur un
entête complet (y compris éventuellement des FWS) et qui traite
encoded_word par encoded-word, il faudra juste remplacer ensuite
mb_decode_mimeheader par la fonction corrigée.
----------------------------------------------------------------------
function rfc2047_decode($header_value)
[...]
Bon, je me suis emmerdé pour rien, alors qu'il existe une fonction
iconv_mime_decode qui fait parfaitement le boulot !

----------------------------------------------------------------------
function test($header_value)
{
echo "<<< \n";
echo $header_value . "\n";
echo rfc2047_decode($header_value) . "\n";
echo iconv_mime_decode($header_value, 2, 'UTF-8') . "\n";
echo ">>> \n";
}

mb_internal_encoding('UTF-8');
test('From: =?US-ASCII?Q?Keith_Moore?= <***@cs.utk.edu>');
test('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <***@dkuug.dk>');
test('CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <***@vm1.ulg.ac.be>');
test('CC: =?UTF-8?Q?Andr=E9?= Pirard <***@vm1.ulg.ac.be>');
test('Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?='
. "\n " . '=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=');
----------------------------------------------------------------------

Résultat (note le test d'erreur la 4e fois) :
----------------------------------------------------------------------
<<<
From: =?US-ASCII?Q?Keith_Moore?= <***@cs.utk.edu>
From: Keith_Moore <***@cs.utk.edu>
From: Keith Moore <***@cs.utk.edu>
<<<
To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <***@dkuug.dk>
To: Keld_Jørn_Simonsen <***@dkuug.dk>
To: Keld Jørn Simonsen <***@dkuug.dk>
<<<
CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <***@vm1.ulg.ac.be>
CC: André Pirard <***@vm1.ulg.ac.be>
CC: André Pirard <***@vm1.ulg.ac.be>
<<<
CC: =?UTF-8?Q?Andr=E9?= Pirard <***@vm1.ulg.ac.be>
CC: Andr Pirard <***@vm1.ulg.ac.be>
CC: =?UTF-8?Q?Andr=E9?= Pirard <***@vm1.ulg.ac.be>
<<<
Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=
Subject: If you can read this you understand the example.
Subject: If you can read this you understand the example.
----------------------------------------------------------------------
unknown
2013-04-01 23:07:12 UTC
Permalink
Post by Olivier Miakinen
Post by Olivier Miakinen
Tu as raison, la fonction est foireuse, je vais la réécrire. En
attendant, voici déjà une fonction que tu peux appeler sur un
entête complet (y compris éventuellement des FWS) et qui traite
encoded_word par encoded-word, il faudra juste remplacer ensuite
mb_decode_mimeheader par la fonction corrigée.
----------------------------------------------------------------------
function rfc2047_decode($header_value)
[...]
Bon, je me suis emmerdé pour rien, alors qu'il existe une fonction
iconv_mime_decode qui fait parfaitement le boulot !
Et ce test ci alors ?
Olivier Miakinen
2013-04-01 23:16:35 UTC
Permalink
Post by unknown
Et ce test ci alors ?
J'avais écrit « note le test d'erreur la 4e fois »...

Si tu regardes attentivement, tu verras que le charset est UTF-8 alors
que le é est codé incorrectement =E9 qui est de l'ISO-8859-1 !

La version avec iconv_mime_decode, qui reconnaît que la chaîne est
incorrecte et ne tente pas de la décoder, est meilleure que celle
avec mb_decode_mimeheader qui perd le « =E9 ».
Eric Demeester
2013-04-02 14:26:45 UTC
Permalink
Post by Olivier Miakinen
Si tu regardes attentivement, tu verras que le charset est UTF-8 alors
que le é est codé incorrectement =E9 qui est de l'ISO-8859-1 !
=E9 étant l'encodage de « é » en QP, pour préciser.
--
Eric
Olivier Miakinen
2013-04-01 19:31:16 UTC
Permalink
Post by Julien Arlandis
Post by Olivier Miakinen
$pattern = '/;(?:[ \t]\n?)*charset(?:[ \t]\n?)*=(?:[
\t]\n?)*("?)([A-Za-z0-9\-_.]+)\1(?:[ \t]\n?)*(?:[(;]|$)/';
C'est ton dernier mot ?
Ça devrait être la même chose que ce que j'avais déjà écrit.
yamo'
2013-03-27 22:37:07 UTC
Permalink
Salut,
Post by unknown
À partir de la version 5.4 de PHP l'option JSON_UNESCAPED_UNICODE
(<http://www.php.net/manual/fr/json.constants.php>)
pourrait peut être régler mon problème mais je tourne sur la version
PHP Version 5.3.3-7+squeeze15.
Est ce que quelqu'un pourrait tester sur une version 5.4 si ça passe ?
Tu peux installer php 5.4 en ne passant pas par les dépôts officiels :

<http://memo-linux.com/installer-php-5-4-sur-debian-squeeze/>

J'ai déjà utilisé ce dépôt pour installer un serveur mysql 5.5.
--
Stéphane <http://pasdenom.info/fortune/?>
BOFH excuse #134:

because of network lag due to too many people playing deathmatch
unknown
2013-03-27 09:24:25 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
1) Lors de l'envoi de l'article par quoi le client remplace t-il la
séquence de fin d'article (en principe "." + "CRLF") si par hasard il
s'en trouve une dans le body ?
Si je me rappelle bien, tout point de début de ligne est doublé.
C'est vraiment pas propre et c'est pareil pour SMTP j'imagine ?
Post by Olivier Miakinen
Commencer par regarder ce qui existe déjà ?
Tiens, ce n'est pas spécifique aux news, mais les formats sont très
http://pear.php.net/manual/fr/package.mail.php
Merci je vais regarder.
Eric Demeester
2013-03-27 16:17:40 UTC
Permalink
dans (in) fr.comp.lang.php, Julien Arlandis <"julien.arlandis at
laposte.net"> ecrivait (wrote) :

Bonjour,
Post by unknown
Post by Olivier Miakinen
Si je me rappelle bien, tout point de début de ligne est doublé.
C'est vraiment pas propre et c'est pareil pour SMTP j'imagine ?
C'est pareil pour SMTP, oui, de même que la ligne blanche obligatoire
séparant les champs d'en-tête du corps du message.

Propre, je ne me prononcerai pas, mais c'est la pratique. Je me demande
d'ailleurs si elle n'est pas définie dans une RFC.
--
Eric
unknown
2013-03-27 16:29:51 UTC
Permalink
Post by Eric Demeester
dans (in) fr.comp.lang.php, Julien Arlandis <"julien.arlandis at
Bonjour,
Post by unknown
Post by Olivier Miakinen
Si je me rappelle bien, tout point de début de ligne est doublé.
C'est vraiment pas propre et c'est pareil pour SMTP j'imagine ?
C'est pareil pour SMTP, oui, de même que la ligne blanche obligatoire
séparant les champs d'en-tête du corps du message.
Propre, je ne me prononcerai pas, mais c'est la pratique. Je me demande
d'ailleurs si elle n'est pas définie dans une RFC.
Bon alors du coup cet algo simple ne fonctionne plus :

$headers = explode("\n", $head);

foreach ($headers as $ligne)
{
// $ligne
}

Comment faire un explode() en ne considérant que les retours chariots
non précédés d'un espace ?
Olivier Miakinen
2013-03-27 23:02:57 UTC
Permalink
Post by unknown
Post by Eric Demeester
Post by Olivier Miakinen
Si je me rappelle bien, tout point de début de ligne est doublé.
[...]
Propre, je ne me prononcerai pas, mais c'est la pratique. Je me demande
d'ailleurs si elle n'est pas définie dans une RFC.
$headers = explode("\n", $head);
foreach ($headers as $ligne)
{
// $ligne
}
J'ai l'impression que tu te mélanges un peu les pinceaux, là. Les
entêtes ne commencent jamais par un « . », donc tu n'as pas à t'en
soucier ailleurs que dans le body, celui que tu as confirmé stocker
comme une chaîne unique.
Post by unknown
Comment faire un explode() en ne considérant que les retours chariots
non précédés d'un espace ?
Là encore, les retours chariots *précédés* d'une espace, c'est dans le
body que ça peut avoir une signification particulière (format flowed).

Je vais supposer que tu voulais parler des FWS, c'est-à-dire des cas
où tu as un CRLF *suivi* d'une espace ou d'une tabulation. Et je te
propose :
$headers = preg_split("\n(?![ \t])", $head);
(à tester)
unknown
2013-03-27 23:10:05 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Comment faire un explode() en ne considérant que les retours chariots
non précédés d'un espace ?
Là encore, les retours chariots *précédés* d'une espace, c'est dans le
body que ça peut avoir une signification particulière (format flowed).
Je vais supposer que tu voulais parler des FWS, c'est-à-dire des cas
où tu as un CRLF *suivi* d'une espace ou d'une tabulation. Et je te
$headers = preg_split("\n(?![ \t])", $head);
(à tester)
Marche pas :

Warning: preg_split(): Compilation failed: nothing to repeat at offset 0
Olivier Miakinen
2013-03-27 23:37:53 UTC
Permalink
Post by unknown
Post by Olivier Miakinen
Je vais supposer que tu voulais parler des FWS, c'est-à-dire des cas
où tu as un CRLF *suivi* d'une espace ou d'une tabulation. Et je te
$headers = preg_split("\n(?![ \t])", $head);
(à tester)
Warning: preg_split(): Compilation failed: nothing to repeat at offset 0
J'ai bêtement oublié les délimiteurs de regexp au début et à la fin.

$headers = preg_split("/\n(?![ \t])/", $head);
unknown
2013-03-27 23:50:56 UTC
Permalink
Post by Olivier Miakinen
Post by unknown
Post by Olivier Miakinen
Je vais supposer que tu voulais parler des FWS, c'est-à-dire des cas
où tu as un CRLF *suivi* d'une espace ou d'une tabulation. Et je te
$headers = preg_split("\n(?![ \t])", $head);
(à tester)
Warning: preg_split(): Compilation failed: nothing to repeat at offset 0
J'ai bêtement oublié les délimiteurs de regexp au début et à la fin.
$headers = preg_split("/\n(?![ \t])/", $head);
Merci ça marche bien.

Pour le Subject j'ai fait ceci :

$elements = imap_mime_header_decode($value);
$sujet = "";

for ($i=0; $i < count($elements); $i++)
{
$sujet .= $elements[$i]->{'text'};
}

$article->{'subject'} = utf8_encode($sujet);

Est ce que tu vois une erreur ?
Olivier Miakinen
2013-03-28 00:16:54 UTC
Permalink
Post by unknown
$elements = imap_mime_header_decode($value);
Je ne connaissais pas cette fonction, je suis allé voir la doc :
<http://php.net/manual/fr/function.imap-mime-header-decode.php>
Post by unknown
$sujet = "";
for ($i=0; $i < count($elements); $i++)
{
$sujet .= $elements[$i]->{'text'};
}
Attention, là tu mélanges des bouts de texte qui sont potentiellement
dans des charsets différents.
Post by unknown
$article->{'subject'} = utf8_encode($sujet);
Et là tu encodes en supposant un charset de départ ISO-8859-1.
Post by unknown
Est ce que tu vois une erreur ?
Oui. À priori je verrais plutôt un truc comme ça (non testé) :

for ($i=0; $i < count($elements); $i++)
{
$text = $elements[$i]->{'text'};
$charset = $elements[$i]->{'charset'};
if ($charset == 'default') {
$sujet .= $text;
} else {
$sujet .= mb_convert_encoding($text, 'UTF-8', $charset);
}
}


Ou, en plus compact :

for ($i=0; $i < count($elements); $i++)
{
if ($elements[$i]->{'charset'} == 'default') {
$sujet .= $elements[$i]->{'text'};
} else {
$sujet .= mb_convert_encoding($elements[$i]->{'text'},
'UTF-8', $elements[$i]->{'charset'});
}
}


Outre de possibles coquilles (de même que j'avais oublié les // dans mon
bout de code précédent), les points à vérifier sont :
1) gérer les erreurs, par exemple un charset inconnu ou un texte
incorrect dans ce charset ;
2) vérifier le traitement des espaces entre un élément encodé et un
élément non encodé (charset 'default').

Si je trouve le temps, je te ferai des chaînes de test. Mais pas
maintenant, je devrais être au lit depuis longtemps.
Eric Demeester
2013-03-28 20:11:08 UTC
Permalink
dans (in) fr.comp.lang.php, Julien Arlandis <"julien.arlandis at
laposte.net"> ecrivait (wrote) :

Bonjour,
Post by unknown
$elements = imap_mime_header_decode($value);
$sujet = "";
En complément des réponses d'Olivier, il y a un certain nombre
d'éléments indispensables à comprendre concernant les en-têtes, qu'il
s'agisse de messages Usenet ou de courriels, éléments qu'on retrouve
dans les RFC.

Je vais peut-être enfoncer des portes ouvertes, mais tant qu'à faire,
autant essayer d'expliquer au mieux.

1. En-têtes obligatoires :

Elles sont indispensables à l'identification et à la propagation.
Je ne vais pas détailler, mais en gros :
Path: ,Date: ,From: ,MIME-Version: ,Newsgroups: ,Subject: ,
Content-Type: ,Content-Transfer-Encoding: ,etc., en font partie.
(note l'espace obligatoire après le « : », valable aussi pour les
en-têtes facultatives)

2. En-têtes facultatives :

Bien que non définies dans les RFC, elles donnent un certain nombre
d'indications supplémentaires, à titre d'information pour les lecteurs
ou les robots, et sont préfixées par X :
X-No-Archive: , X-Face: , X-Trace: , X-Complaints-To: , etc.

3. Ordre des champs :

Alors c'est très simple, il n'y en a pas. Généralement, le Path: vient
en premier, mais après, on ne sait pas. Tout ce que demande la RFC,
c'est que l'ensemble des champs indispensables soient présents, ce qui a
une importance particulière pour le champ Subject: .

4. Encodage des champs :

C'est systématiquement de l'ASCII 7 bits, sauf, parfois, pour le
Subject: .

5. Le cas du champ Subject :

C'est le seul champ d'en-tête dans lequel on peut trouver des caractères
non ASCII 7bits (caractères accentués par exemple). Lors du transport,
ils peuvent soit être encodés (en QP par exemple), soit pas.

Cela dépend de ces lignes, par exemple, si on a :
Content-Type: text/plain; charset=ISO-8859-15;
Content-Transfer-Encoding: 8bit

Il y a des chances que le Subject « ça va pas la tête ? » circule tel
quel.

Mais si on a des choses horribles genre :
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On risque de se trouver avec un Subject: encodé en QP.

Oui mais :
- d'une part, le Content-Type: et le Content-Transfer-Encoding: sont
sensés s'appliquer à l'encodage du CORPS du message, pas au
Subject : ;
- d'autre part, on ne peut pas être certain que le Subject: soit défini
APRÈS le Content-Type: et le Content-Transfer-Encoding: .

Corollaire : il faut laisser le champ Subject: tranquille, sans chercher
à l'encoder ou le décoder, juste se contenter de vérifier que ta
fonction PHP ne le transformera pas en gloubiboulga.

C'est le lociciel client qui se chargera le cas échéant de le décoder si
nécessaire (cas d'un encodage en QP par exemple). Sur ce point, tu me
répondras que le logiciel client, c'est l'interface de ton navigateur,
et tu n'auras pas tort.

Mais ce qui est valable en réception l'est aussi en envoi. Si ta
passerelle doit injecter des articles sur le réseau NNTP, elle doit
impérativement respecter les conventions de transport et d'encodage, si
possible en envoyant un encodage propre, genre :
Content-Type: text/plain; charset=ISO-8859-15;
Content-Transfer-Encoding: 8bit

et en le respectant dans le corps du message, sans quoi tes articles
risquent de s'avérer illisibles avec mon logiciel, par exemple.

Tout ceci est incomplet, mais c'est juste pour pointer la complexité de
ce à quoi tu t'attaques, et l'absolue nécessité d'avoir une parfaite
compréhension de tous ces points si tu veux éviter d'aller dans le mur.

J'ai d'ailleurs probablement raconté des bétises ou commis des
inexactitudes, corrections et compléments bienvenus de la part de ceux
qui savent mieux que moi.
--
Eric
Erwan David
2013-03-28 20:40:48 UTC
Permalink
Post by Eric Demeester
C'est le seul champ d'en-tête dans lequel on peut trouver des caractères
non ASCII 7bits (caractères accentués par exemple). Lors du transport,
ils peuvent soit être encodés (en QP par exemple), soit pas.
Non, d'autres en-têtes le peuvent :

From, pour la partie "Nom réel" de l'adresse. (Par exemple un
From : Éric Demeester <***@grosnaze.org.invalid>
est tout à fait possible.

Et le mot Éric devra être encodé.

ainsi que tous ceux qui portent un texte destiné aux humains, comme Organization.
Post by Eric Demeester
Content-Type: text/plain; charset=ISO-8859-15;
Content-Transfer-Encoding: 8bit
Il y a des chances que le Subject « ça va pas la tête ? » circule tel
quel.
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On risque de se trouver avec un Subject: encodé en QP.
Non, les encodages des en-têtes sont totalement indépendants des
encodages du corps (ceux qui sont définis par Content-Type et
Content-Transfert-Encoding).

Il faut regarder la RFC2047 (et il y a déjà des bibliothèques
d'encodage/décodage des en-têtes selon cette RFC).
--
Les simplifications c'est trop compliqué
unknown
2013-03-28 21:26:39 UTC
Permalink
Post by Eric Demeester
Tout ceci est incomplet, mais c'est juste pour pointer la complexité de
ce à quoi tu t'attaques, et l'absolue nécessité d'avoir une parfaite
compréhension de tous ces points si tu veux éviter d'aller dans le mur.
J'ai d'ailleurs probablement raconté des bétises ou commis des
inexactitudes, corrections et compléments bienvenus de la part de ceux
qui savent mieux que moi.
Tout le problème c'est de réussir à encoder toutes les chaines de
caractère en UTF8 lors de la transition de l'article de NNTP vers
HTTP-NNTP, le passage HTTP-NNTP vers NNTP lui ne devrait pas poser de
difficultés.
Olivier Miakinen
2013-03-28 22:47:27 UTC
Permalink
En complément des réponses d'Olivier, [...]
... et je vais compléter de nouveau ta réponse, parfois en contradiction
avec ce que tu écris (et avec ce qu'écrit Erwan juste après).
Je vais peut-être enfoncer des portes ouvertes, mais tant qu'à faire,
autant essayer d'expliquer au mieux.
Elles sont indispensables à l'identification et à la propagation.
Path: ,Date: ,From: ,MIME-Version: ,Newsgroups: ,Subject: ,
Content-Type: ,Content-Transfer-Encoding: ,etc., en font partie.
(note l'espace obligatoire après le « : », valable aussi pour les
en-têtes facultatives)
Je précise que MIME-Version, Content-Type et Content-Transfer-Encoding
sont une triade inséparable. Si le corps de l'article est tout entier
du texte brut en US-ASCII 7 bits, alors on peut les omettre tous les
trois. Sinon, tous les trois sont obligatoires.

Je me souviens par exemple d'un article qui avait un Content-Type et
un Content-Transfer-Encoding tout à fait corrects, ce qui satisfaisait
pleinement mon SeaMonkey. Mais quelqu'un était venu demander sur fu8
pourquoi ça ne fonctionnait pas dans son nouvelleur exotique, et on
a trouvé que c'était parce qu'il manquait MIME-Version.

Note : une seule version est définie pour ce champ, à savoir 1.0.
Bien que non définies dans les RFC, elles donnent un certain nombre
d'indications supplémentaires, à titre d'information pour les lecteurs
X-No-Archive: , X-Face: , X-Trace: , X-Complaints-To: , etc.
Certains entêtes ont été définis depuis, par exemple Archive (censé
remplacer X-No-Archive), Injection-Date et Injection-Info (pour faire
en gros la même chose que X-Trace), etc.

Tout ceci est défini dans le RFC 5536 [1], qu'on attendait depuis des
années (novembre 2009, soit vingt-deux ans après le RFC 1036 daté de
décembre 1987).
Alors c'est très simple, il n'y en a pas. Généralement, le Path: vient
en premier, mais après, on ne sait pas. Tout ce que demande la RFC,
c'est que l'ensemble des champs indispensables soient présents, ce qui a
une importance particulière pour le champ Subject: .
Il est aussi demandé pour la plupart des entêtes qu'ils ne soient pas
présents plus d'une fois. Cf. RFC 5536 [1].
C'est systématiquement de l'ASCII 7 bits, sauf, parfois, pour le
Subject: .
Formellement, c'est systématiquement de l'ASCII 7 bits, sans exception.
Pour y mettre des caractères non ASCII, c'est possible, mais en les
encodant selon le RFC 2047 [2].

Le flou qui règne à ce propos vient du fait que le RFC 2047 a été rédigé
en 1996 comme un complément du RFC 822 (ancètre du RFC 5322 [3]) qui ne
concerne que le mail, et qu'il a fallu attendre encore treize ans avant
que le RFC 5536 ne confirme que oui, bien sûr, cela s'appliquait aussi
aux news.

Du coup, sur usenet-fr où le besoin de caractères accentués était criant
dans les champs From et Subject, et où ISO-8859-1 était le seul standard
en dehors de US-ASCII (je parle de bien avant UTF-8), il a été dit que
la seule façon correcte de faire était de mettre de l'ISO-8859-1 non
déclaré et non codé dans les champs d'entête.

Quoi qu'il en soit, le RFC 5322 ne laisse plus aucun doute aujourd'hui :

<cit.>
o The character set for header fields is US-ASCII. Where the use of
non-ASCII characters is required, they MUST be encoded using the
MIME mechanisms defined in [RFC2047] and [RFC2231].
</cit.>
C'est le seul champ d'en-tête dans lequel on peut trouver des caractères
non ASCII 7bits (caractères accentués par exemple). Lors du transport,
ils peuvent soit être encodés (en QP par exemple), soit pas.
Donc non. D'une part on peut les trouver dans d'autres champs comme
le champ From par exemple (tu pourrais t'appeler Éric et non pas Eric)
mais surtout ils *doivent* (MUST) être encodés.
Content-Type: text/plain; charset=ISO-8859-15;
Content-Transfer-Encoding: 8bit
Rappel : si ces deux lignes sont présentes, alors il faut forcément la
troisième aussi.

Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
Mime-Version: 1.0
Il y a des chances que le Subject « ça va pas la tête ? » circule tel
quel.
Cela arrive encore, mais c'est une erreur.
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On risque de se trouver avec un Subject: encodé en QP.
Note aussi que l'on peut très bien trouver un body en QP et des entêtes
en Base64, ou l'inverse, et en fait n'importe quelle combinaison. Il
est même possible d'avoir dans un même champ d'entête une partie en
UTF-8/Base64 et une autre en ISO-8859-1/QP (par exemple).

Au passage, j'en profite pour rappeler (ou apprendre) à Julien qu'il
convient d'éviter le quoted-printable pour le body, contrairement à ce
que fait Google groupes.
- d'une part, le Content-Type: et le Content-Transfer-Encoding: sont
censés s'appliquer à l'encodage du CORPS du message, pas au
Subject : ;
- d'autre part, on ne peut pas être certain que le Subject: soit défini
APRÈS le Content-Type: et le Content-Transfer-Encoding: .
Tout à fait exact. D'autant plus que, comme tu le rappelais, les entêtes
peuvent être dans n'importe quel ordre sans que cela ne change leur
signification. Et les entêtes MIME que sont MIME-Version, Content-Type
et Content-Transfer-Encoding ne portent que sur l'encodage du body, pas
sur les autres entêtes.
Corollaire : il faut laisser le champ Subject: tranquille, sans chercher
à l'encoder ou le décoder, juste se contenter de vérifier que ta
fonction PHP ne le transformera pas en gloubiboulga.
Pas d'accord. En lecture il faut le décoder s'il est encodé en MIME, et
en écriture il faut l'encoder s'il contient autre chose que de l'ASCII.
C'est le lociciel client qui se chargera le cas échéant de le décoder si
nécessaire (cas d'un encodage en QP par exemple). Sur ce point, tu me
répondras que le logiciel client, c'est l'interface de ton navigateur,
et tu n'auras pas tort.
Ah, tu ne parlais pas du logiciel client. Oui, du coup je suis d'accord
avec ton paragraphe précédent : il faut laisser tranquilles tous les
entêtes que l'on n'a pas besoin d'interpréter.
Mais ce qui est valable en réception l'est aussi en envoi. Si ta
passerelle doit injecter des articles sur le réseau NNTP, elle doit
impérativement respecter les conventions de transport et d'encodage, si
Content-Type: text/plain; charset=ISO-8859-15;
Content-Transfer-Encoding: 8bit
sans oublier MIME-Version: 1.0 (comment ? je l'ai déjà dit ?)
et en le respectant dans le corps du message, sans quoi tes articles
risquent de s'avérer illisibles avec mon logiciel, par exemple.
Oui.
Tout ceci est incomplet, mais c'est juste pour pointer la complexité de
ce à quoi tu t'attaques, et l'absolue nécessité d'avoir une parfaite
compréhension de tous ces points si tu veux éviter d'aller dans le mur.
J'ai d'ailleurs probablement raconté des bétises ou commis des
inexactitudes, corrections et compléments bienvenus de la part de ceux
qui savent mieux que moi.
Je ne m'en suis pas privé. ;-)

Cordialement,
--
Olivier Miakinen

[1] RFC 5536, Netnews Article Format
<http://tools.ietf.org/html/rfc5536>

[2] RFC 2047, MIME #3 : Message Header Extensions for Non-ASCII Text
<http://tools.ietf.org/html/rfc2047>

[3] RFC 5322, Internet Message Format
<http://tools.ietf.org/html/rfc5322>
Olivier Miakinen
2013-03-28 22:50:02 UTC
Permalink
Post by Olivier Miakinen
En complément des réponses d'Olivier, [...]
... et je vais compléter de nouveau ta réponse, parfois en contradiction
avec ce que tu écris (et avec ce qu'écrit Erwan juste après).
Oups ! Il faut lire « conformément à ce qu'écrit Erwan ».

Toutes mes confuses.
Loading...