Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Serveur INN

13 views
Skip to first unread message

Julien Arlandis

unread,
Mar 24, 2013, 8:38:21 PM3/24/13
to
Le 25/03/13 01:03, Stᅵphane Catteau a ᅵcrit :
> Julien Arlandis devait dire quelque chose comme ceci :
>
>> 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

unread,
Mar 25, 2013, 6:09:58 PM3/25/13
to
["Followup-To:" header set to fr.comp.lang.php.]
On 2013-03-25, Julien Arlandis wrote:
>
> 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$426a...@news.free.fr>'
@050000000304000000000000001000000000@
% grephistory '<514ed208$0$2118$426a...@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 ?

Julien Arlandis

unread,
Mar 26, 2013, 4:19:42 PM3/26/13
to
Le 25/03/13 23:09, Bruno Ducrot a ᅵcrit :
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

Julien Arlandis

unread,
Mar 26, 2013, 5:59:55 PM3/26/13
to
Le 26/03/13 21:19, Julien Arlandis a ᅵcrit :
> Le 25/03/13 23:09, Bruno Ducrot a ᅵcrit :
>> ["Followup-To:" header set to fr.comp.lang.php.]
>> On 2013-03-25, Julien Arlandis wrote:
>>>
>>> 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$426a...@news.free.fr>'
>> @050000000304000000000000001000000000@
>> % grephistory '<514ed208$0$2118$426a...@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,
>
> 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$1...@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

unread,
Mar 26, 2013, 7:25:52 PM3/26/13
to
Le 26/03/2013 22:59, Julien Arlandis a écrit :
>
> 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 ?

Si je me rappelle bien, tout point de début de ligne est doublé.

> 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$1...@dont-email.me>

La syntaxe pour citer un article par son MID est plutôt :
<news:kit1cp$da7$1...@dont-email.me>

> Comment faire dans ce cas là?

Mot-clé : folding white space ou FWS dans les RFC.

> 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.

> 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.

> 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);

Ce ne serait pas $pos+1 pour $head et $pos+2 pour $body ?

> $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.

> 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

Julien Arlandis

unread,
Mar 26, 2013, 8:26:47 PM3/26/13
to
Le 27/03/13 00:25, Olivier Miakinen a écrit :
> Le 26/03/2013 22:59, Julien Arlandis a écrit :
>>
>> 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 ?
>
> Si je me rappelle bien, tout point de début de ligne est doublé.
>
>> 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$1...@dont-email.me>
>
> La syntaxe pour citer un article par son MID est plutôt :
> <news:kit1cp$da7$1...@dont-email.me>


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$1...@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?




Julien Arlandis

unread,
Mar 27, 2013, 5:24:25 AM3/27/13
to
Le 27/03/13 00:25, Olivier Miakinen a écrit :
> Le 26/03/2013 22:59, Julien Arlandis a écrit :
>>
>> 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 ?
>
> 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 ?


> 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

Merci je vais regarder.

Message has been deleted

Julien Arlandis

unread,
Mar 27, 2013, 12:29:51 PM3/27/13
to
Le 27/03/13 17:17, Eric Demeester a écrit :
> dans (in) fr.comp.lang.php, Julien Arlandis <"julien.arlandis at
> laposte.net"> ecrivait (wrote) :
>
> Bonjour,
>
>> Le 27/03/13 00:25, Olivier Miakinen a écrit :
>>> 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 ?

Julien Arlandis

unread,
Mar 27, 2013, 1:26:35 PM3/27/13
to
Le 27/03/13 01:26, Julien Arlandis a écrit :
> Le 27/03/13 00:25, Olivier Miakinen a écrit :
>> Le 26/03/2013 22:59, Julien Arlandis a écrit :
>>>
>>> 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 ?
>>
>> Si je me rappelle bien, tout point de début de ligne est doublé.
>>
>>> 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$1...@dont-email.me>
>>
>> La syntaxe pour citer un article par son MID est plutôt :
>> <news:kit1cp$da7$1...@dont-email.me>
>
>
> 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$1...@dont-email.me> PHP me
> 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.


Message has been deleted

Olivier Miakinen

unread,
Mar 27, 2013, 7:02:57 PM3/27/13
to
Le 27/03/2013 17:29, Julien Arlandis a écrit :
>>
>>>> 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.
>
> Bon alors du coup cet algo simple ne fonctionne plus :
>
> $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.

> 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)

Julien Arlandis

unread,
Mar 27, 2013, 7:10:05 PM3/27/13
to
Le 28/03/13 00:02, Olivier Miakinen a écrit :

>> 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)

Marche pas :

Warning: preg_split(): Compilation failed: nothing to repeat at offset 0

Olivier Miakinen

unread,
Mar 27, 2013, 7:35:03 PM3/27/13
to
Le 27/03/2013 18:26, Julien Arlandis a écrit :
>>
>> 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$1...@dont-email.me> PHP me
>> 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.

> 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

Olivier Miakinen

unread,
Mar 27, 2013, 7:37:53 PM3/27/13
to
Le 28/03/2013 00:10, Julien Arlandis a écrit :
>>
>> 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)
>
> Marche pas :
>
> 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);

Julien Arlandis

unread,
Mar 27, 2013, 7:50:56 PM3/27/13
to
Le 28/03/13 00:37, Olivier Miakinen a écrit :
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 ?

Julien Arlandis

unread,
Mar 27, 2013, 8:01:17 PM3/27/13
to
Le 28/03/13 00:35, Olivier Miakinen a écrit :
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 ?

Olivier Miakinen

unread,
Mar 27, 2013, 8:16:54 PM3/27/13
to
Le 28/03/2013 00:50, Julien Arlandis a écrit :
>
> Pour le Subject j'ai fait ceci :
>
> $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>

> $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.

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

Et là tu encodes en supposant un charset de départ ISO-8859-1.

> 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.

Julien Arlandis

unread,
Mar 27, 2013, 8:17:33 PM3/27/13
to
Le 28/03/13 00:35, Olivier Miakinen a écrit :


> 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

unread,
Mar 27, 2013, 8:25:42 PM3/27/13
to
Le 28/03/2013 01:17, Julien Arlandis a écrit :
>
> 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
Message has been deleted

Erwan David

unread,
Mar 28, 2013, 4:40:48 PM3/28/13
to
Eric Demeester <er...@grosnaze.org.invalid> �crivait�:

> 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.

Non, d'autres en-t�tes le peuvent :

From, pour la partie "Nom r�el" de l'adresse. (Par exemple un
From : �ric Demeester <er...@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.

>
> 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.

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�

Julien Arlandis

unread,
Mar 28, 2013, 5:26:39 PM3/28/13
to
Le 28/03/13 21:11, Eric Demeester a �crit :

> 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.

Julien Arlandis

unread,
Mar 28, 2013, 5:33:25 PM3/28/13
to
Le 28/03/13 01:25, Olivier Miakinen a �crit :
> Le 28/03/2013 01:17, Julien Arlandis a �crit :
>>
>> 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
>

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

unread,
Mar 28, 2013, 6:47:27 PM3/28/13
to
Le 28/03/2013 21:11, Eric Demeester a �crit :
>
> 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.
>
> 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)

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.

> 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.

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).

> 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: .

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].

> 4. Encodage des champs :
>
> 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.>

> 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.

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.

> Cela d�pend de ces lignes, par exemple, si on a :
> 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.

> 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.

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.

> Oui mais :
> - 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
> possible en envoyant un encodage propre, genre :
> 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

unread,
Mar 28, 2013, 6:50:02 PM3/28/13
to
Le 28/03/2013 23:47, j'�crivais :
>>
>> 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.

Olivier Miakinen

unread,
Mar 28, 2013, 7:04:11 PM3/28/13
to
Le 28/03/2013 22:33, Julien Arlandis a �crit :
>>
>> 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
>
> Impeccable, j'ai vid� la table des articles, on va voir si le test est
> concluant pour le champ subject.

Ok.

> � 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.

> 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

Julien Arlandis

unread,
Mar 28, 2013, 7:18:07 PM3/28/13
to
Le 29/03/13 00:04, Olivier Miakinen a �crit :
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

unread,
Mar 28, 2013, 7:24:17 PM3/28/13
to
Le 29/03/2013 00:18, Julien Arlandis a �crit :
>
> 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).

Julien Arlandis

unread,
Mar 28, 2013, 7:26:56 PM3/28/13
to
Le 29/03/13 00:24, Olivier Miakinen a �crit :
Quelle information m'apporte le Content-Transfer-Encoding ?
Et comment je teste les autres charsets ?

Julien Arlandis

unread,
Mar 28, 2013, 7:39:13 PM3/28/13
to
Le 29/03/13 00:24, Olivier Miakinen a �crit :
Prenons un exemple pratique :

<news:801f5ff9-a689-4cd9...@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 ...

Julien Arlandis

unread,
Mar 28, 2013, 7:43:28 PM3/28/13
to
Le 29/03/13 00:39, Julien Arlandis a �crit :
Bien qu'ayant le m�me charset que moi, comment se fait il que les
accents du message
<news:801f5ff9-a689-4cd9...@x13g2000vby.googlegroups.com>
n'apparaissent pas quand on fait un copier coller ?

Olivier Miakinen

unread,
Mar 28, 2013, 8:32:12 PM3/28/13
to
Le 29/03/2013 00:43, Julien Arlandis a �crit :
>>
>> Prenons un exemple pratique :
>>
>> <news:801f5ff9-a689-4cd9...@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 ;-)

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])

> Bien qu'ayant le m�me charset que moi, comment se fait il que les
> accents du message
> <news:801f5ff9-a689-4cd9...@x13g2000vby.googlegroups.com>
> n'apparaissent pas quand on fait un copier coller ?

Chez moi �a marche � et �a devrait fonctionner avec ton Thunderbird
comme avec mon SeaMonkey.

Julien Arlandis

unread,
Mar 29, 2013, 4:32:19 AM3/29/13
to
Le 29/03/13 02:17, Olivier Miakinen a �crit :
> Le 29/03/2013 01:48, Julien Arlandis a �crit :
>>
>> 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

Julien Arlandis

unread,
Mar 29, 2013, 6:01:44 AM3/29/13
to
Le 29/03/13 09:32, Julien Arlandis a �crit :
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

unread,
Mar 29, 2013, 1:20:45 PM3/29/13
to
Le 29/03/2013 09:32, Julien Arlandis a ᅵcrit :
>
> Ok, donc pour rᅵsumer, je rᅵcupᅵre :
>
> 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".

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

Tu voulais dire ᅵ decode ᅵ plutᅵt que ᅵ encode ᅵ, non ?

> 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.

> Et ces deux informations ᅵ me sont

;-)

Rᅵgionalisme, ou coquillle ?

> 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.

> 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>

Julien Arlandis

unread,
Mar 30, 2013, 9:48:15 AM3/30/13
to
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: julien....@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);
?>

Julien Arlandis

unread,
Mar 30, 2013, 9:52:56 AM3/30/13
to
Le 30/03/13 14:48, Julien Arlandis a ᅵcrit :
> 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...

Problᅵme rᅵglᅵ il fallait insᅵrer un "\r\n" entre le head et le body, je
mettais un "\n\n" ...

Olivier Miakinen

unread,
Mar 30, 2013, 10:33:10 AM3/30/13
to
Salut !

J'ai vu que tu as r�solu ton probl�me. Mais je t'en signale d'autres,
r�els ou potentiels.

Le 30/03/2013 14:48, Julien Arlandis a �crit :
>
> Voici le contenu du script PHP :
> <?php
>
> $messageid=uniqid()."@news.julien-arlandis.fr";
>
> $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.

> Subject: re test
> References:

<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.

> Newsgroups: fr.test
> date: Sat, 30 Mar 13 11:33:14 +0100

Date:

> 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.

User-Agent:

> 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.

> Message-ID: <{$messageid}>
> organization: Nemo News

Organization:

> 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.

> complaintsTo: julien....@laposte.net

Tu voulais dire � X-Complaints-To: � ? De toute mani�re c'est aussi
dans Injection-Info. Tu as lu le RFC 5536 ?

> 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

unread,
Mar 30, 2013, 10:45:25 AM3/30/13
to
Le 30/03/13 15:33, Olivier Miakinen a �crit :
> Salut !
>
> J'ai vu que tu as r�solu ton probl�me. Mais je t'en signale d'autres,
> r�els ou potentiels.
>
> Le 30/03/2013 14:48, Julien Arlandis a �crit :
>>
>> Voici le contenu du script PHP :
>> <?php
>>
>> $messageid=uniqid()."@news.julien-arlandis.fr";
>>
>> $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


> <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.
>
>> Newsgroups: fr.test
>> date: Sat, 30 Mar 13 11:33:14 +0100
>
> Date:

Peux tu me dire si la date est au bon format ? Notamment l'ann�e, il
manque les 2 premiers chiffres.


>> 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.
> User-Agent:

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 -.

>> 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 ?

>> Message-ID: <{$messageid}>

Oui

>> organization: Nemo News
>
> Organization:

Oui

>> 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

>> complaintsTo: julien....@laposte.net
>
> 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...

>> 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.

Olivier Miakinen

unread,
Mar 30, 2013, 11:48:31 AM3/30/13
to
Le 29/03/2013 18:20, j'�crivais :
>
>> 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>
>
> 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

Julien Arlandis

unread,
Mar 30, 2013, 1:11:39 PM3/30/13
to
Le 30/03/13 15:33, Olivier Miakinen a �crit :

> 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'});

?>
Message has been deleted
Message has been deleted

Julien Arlandis

unread,
Mar 30, 2013, 1:53:12 PM3/30/13
to
Le 30/03/13 18:32, Eric Demeester a �crit :
> dans (in) fr.comp.lang.php, Julien Arlandis <"julien.arlandis at
> laposte.net"> ecrivait (wrote) :
>
> Bonjour,
>
>> 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 :)
>

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

unread,
Mar 30, 2013, 5:53:38 PM3/30/13
to
Le 30/03/2013 18:32, Eric Demeester r�pondait � Julien Arlandis :
>
>> 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 ?
>
Oui, mais il faudra faire autrement dans le cas d'un encodage RFC2047.

> 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).

> 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

unread,
Mar 30, 2013, 5:58:29 PM3/30/13
to
Le 30/03/2013 18:53, Julien Arlandis a �crit :
>>
>> Une piste : wordwrap :
>> 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).
</>

Julien Arlandis

unread,
Mar 30, 2013, 7:19:36 PM3/30/13
to
Le 30/03/13 22:58, Olivier Miakinen a �crit :
> Le 30/03/2013 18:53, Julien Arlandis a �crit :
>>>
>>> Une piste : wordwrap :
>>> 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

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?

Olivier Miakinen

unread,
Mar 31, 2013, 4:46:41 AM3/31/13
to
Le 31/03/2013 00:19, Julien Arlandis a �crit :
>>
>> <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.

>> linefeed specifies the EOL (end-of-line) marker with which
>> [etc.]

Inutile de citer ce � quoi tu ne r�ponds pas, hein ! ;-)

Julien Arlandis

unread,
Mar 31, 2013, 6:31:49 AM3/31/13
to
Le 31/03/13 10:46, Olivier Miakinen a �crit :
> Le 31/03/2013 00:19, Julien Arlandis a �crit :
>>>
>>> <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

unread,
Mar 31, 2013, 6:38:50 AM3/31/13
to
Le 31/03/13 12:31, Julien Arlandis a �crit :
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

unread,
Mar 31, 2013, 9:04:10 AM3/31/13
to
Le 31/03/2013 12:38, Julien Arlandis a �crit :
>>
>> 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�.

> Apparemment non :
>
> 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 ?

> 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.

Julien Arlandis

unread,
Mar 31, 2013, 9:10:36 AM3/31/13
to
Le 31/03/13 15:04, Olivier Miakinen a �crit :
> Le 31/03/2013 12:38, Julien Arlandis a �crit :
>>>
>>> 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...

> Tu es s�r de $value ? Quelles sont les valeurs des quatre premiers
> octets de cette cha�ne ? Et sa longueur... 17 ou 23 ?
>
>> 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:515830...@news.julien-arlandis.fr>

J'ai utilis� mb_encode_mimeheader($value, "UTF-8", "Q", " \n")

Julien Arlandis

unread,
Mar 31, 2013, 9:39:34 AM3/31/13
to
Le 31/03/13 15:04, Olivier Miakinen a �crit :
> Le 31/03/2013 12:38, Julien Arlandis a �crit :

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

unread,
Mar 31, 2013, 4:06:12 PM3/31/13
to
Le 31/03/2013 15:10, Julien Arlandis a écrit :
>>>>
>>>> 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 ?

>> 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).

> Regarde cet article posté avec Nemo :
>
> <news:515830...@news.julien-arlandis.fr>
>
> 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.

Olivier Miakinen

unread,
Mar 31, 2013, 4:10:41 PM3/31/13
to
Le 31/03/2013 15:39, Julien Arlandis a écrit :
>
> 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.
>
> 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.

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 ?

Julien Arlandis

unread,
Mar 31, 2013, 4:55:12 PM3/31/13
to
Le 31/03/13 22:06, Olivier Miakinen a écrit :
> Le 31/03/2013 15:10, Julien Arlandis a écrit :
>>>>>
>>>>> 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.

>>> 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).



>> Regarde cet article posté avec Nemo :
>>
>> <news:515830...@news.julien-arlandis.fr>
>>
>> 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


> 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

unread,
Mar 31, 2013, 5:09:26 PM3/31/13
to
Le 31/03/2013 22:55, Julien Arlandis a �crit :
>>
>> En clair, donner � la fois les deux r�sultats suivants ;
>> bin2hex($value)
>
> c3a9c3a9c3a9
>
>
>> 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

unread,
Mar 31, 2013, 6:01:36 PM3/31/13
to
Le 31/03/13 23:09, Olivier Miakinen a écrit :
> Le 31/03/2013 22:55, Julien Arlandis a écrit :
>>>
>>> En clair, donner à la fois les deux résultats suivants ;
>>> bin2hex($value)
>>
>> c3a9c3a9c3a9
>>
>>
>>> 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

> 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

Julien Arlandis

unread,
Mar 31, 2013, 8:11:41 PM3/31/13
to
Le 30/03/13 16:48, Olivier Miakinen a écrit :
> Le 29/03/2013 18:20, j'écrivais :
>>
>>> 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>
>>
>> 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,
>
Ç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

unread,
Apr 1, 2013, 4:00:44 AM4/1/13
to
Le 01/04/2013 02:11, Julien Arlandis a écrit :
>>
>> 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];
>> }
>>
> Ç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.

Julien Arlandis

unread,
Apr 1, 2013, 4:18:35 AM4/1/13
to
Le 01/04/13 10:00, Olivier Miakinen a écrit :
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.
Message has been deleted

Stéphane Catteau

unread,
Apr 1, 2013, 6:18:41 AM4/1/13
to
Julien Arlandis n'ᅵtait pas loin de dire :

>>>> $token = "[A-Za-z0-9\\-_.]+";
^^^^

De "\" ᅵ "_" au lieu du "\", "-" et "_" dᅵsirᅵ.


--
17/06/1969 - 18/01/2011

Repose en paix mon amour :'(


Julien Arlandis

unread,
Apr 1, 2013, 1:27:21 PM4/1/13
to
Le 01/04/13 12:16, Eric Demeester a écrit :
> Julien Arlandis (Mon, 01 Apr 2013 10:18:35 +0200 - fr.comp.lang.php) :
>
> Salut,
>
>> 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.
>
> 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 ?

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

unread,
Apr 1, 2013, 2:16:20 PM4/1/13
to
Le 01/04/2013 10:18, Julien Arlandis a écrit :
>>>>
>>>> $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

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.

> 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

unread,
Apr 1, 2013, 2:26:23 PM4/1/13
to
Le 01/04/13 20:16, Olivier Miakinen a écrit :

> 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);

C'est ton dernier mot ?

Olivier Miakinen

unread,
Apr 1, 2013, 2:28:56 PM4/1/13
to
Le 01/04/2013 12:18, Stéphane Catteau a écrit :
> Julien Arlandis n'était pas loin de dire :
>
>>>>> $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 "[\\\\-_]"

Olivier Miakinen

unread,
Apr 1, 2013, 2:30:16 PM4/1/13
to
Le 01/04/2013 19:27, Julien Arlandis a �crit :
>>
>> 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.

Olivier Miakinen

unread,
Apr 1, 2013, 2:33:15 PM4/1/13
to
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.

Julien Arlandis

unread,
Apr 1, 2013, 2:33:24 PM4/1/13
to
Le 01/04/13 20:30, Olivier Miakinen a écrit :
> Le 01/04/2013 19:27, Julien Arlandis a écrit :
>>>
>>> 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.

Julien Arlandis

unread,
Apr 1, 2013, 2:36:27 PM4/1/13
to
Le 01/04/13 20:33, Olivier Miakinen a écrit :
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.

Julien Arlandis

unread,
Apr 1, 2013, 2:38:43 PM4/1/13
to
Le 01/04/13 20:33, Olivier Miakinen a écrit :
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

unread,
Apr 1, 2013, 3:31:16 PM4/1/13
to
Le 01/04/2013 20:26, Julien Arlandis a écrit :
>>
>> $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.

Olivier Miakinen

unread,
Apr 1, 2013, 3:38:50 PM4/1/13
to
Le 01/04/2013 20:38, Julien Arlandis a écrit :
>
> 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));
^^^^^^^^^^^
Après avoir fait mb_internal_encoding('UTF-8'), ça te donne toujours un
résultat en ISO-8859-1 ???

> 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.

Olivier Miakinen

unread,
Apr 1, 2013, 3:48:33 PM4/1/13
to
Le 01/04/2013 20:36, Julien Arlandis a écrit :
>
> 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

unread,
Apr 1, 2013, 4:09:58 PM4/1/13
to
Le 01/04/13 21:48, Olivier Miakinen a écrit :
> Le 01/04/2013 20:36, Julien Arlandis a écrit :
>>
>> 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.

Julien Arlandis

unread,
Apr 1, 2013, 4:19:34 PM4/1/13
to
Le 01/04/13 21:38, Olivier Miakinen a écrit :
> Le 01/04/2013 20:38, Julien Arlandis a écrit :
>>
>> 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));
> ^^^^^^^^^^^
> 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.

>> 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

unread,
Apr 1, 2013, 6:47:19 PM4/1/13
to
Le 01/04/2013 22:09, Julien Arlandis a écrit :
>
> 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.

Olivier Miakinen

unread,
Apr 1, 2013, 6:53:43 PM4/1/13
to
Le 01/04/2013 22:19, Julien Arlandis a écrit :
>
> 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?= <mo...@cs.utk.edu>');
test('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <ke...@dkuug.dk>');
test('CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIR...@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?= <mo...@cs.utk.edu>
From: Keith_Moore <mo...@cs.utk.edu>
>>>
<<<
To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <ke...@dkuug.dk>
To: Keld_Jørn_Simonsen <ke...@dkuug.dk>
>>>
<<<
CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>
CC: André Pirard <PIR...@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

unread,
Apr 1, 2013, 7:03:45 PM4/1/13
to
Le 02/04/2013 00:53, j'écrivais :
>
> 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?= <mo...@cs.utk.edu>');
test('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <ke...@dkuug.dk>');
test('CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>');
test('CC: =?UTF-8?Q?Andr=E9?= Pirard <PIR...@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?= <mo...@cs.utk.edu>
From: Keith_Moore <mo...@cs.utk.edu>
From: Keith Moore <mo...@cs.utk.edu>
>>>
<<<
To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <ke...@dkuug.dk>
To: Keld_Jørn_Simonsen <ke...@dkuug.dk>
To: Keld Jørn Simonsen <ke...@dkuug.dk>
>>>
<<<
CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>
CC: André Pirard <PIR...@vm1.ulg.ac.be>
CC: André Pirard <PIR...@vm1.ulg.ac.be>
>>>
<<<
CC: =?UTF-8?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>
CC: Andr Pirard <PIR...@vm1.ulg.ac.be>
CC: =?UTF-8?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>

Julien Arlandis

unread,
Apr 1, 2013, 7:07:12 PM4/1/13
to
Le 02/04/13 01:03, Olivier Miakinen a écrit :
> Le 02/04/2013 00:53, j'écrivais :
>>
>> 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 !
>

> CC: =?UTF-8?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>
> CC: Andr Pirard <PIR...@vm1.ulg.ac.be>
> CC: =?UTF-8?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>

Et ce test ci alors ?

Olivier Miakinen

unread,
Apr 1, 2013, 7:16:35 PM4/1/13
to
Le 02/04/2013 01:07, Julien Arlandis a écrit :
>
>> CC: =?UTF-8?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>
>> CC: Andr Pirard <PIR...@vm1.ulg.ac.be>
>> CC: =?UTF-8?Q?Andr=E9?= Pirard <PIR...@vm1.ulg.ac.be>
>
> 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 ».

Message has been deleted
Message has been deleted

Julien Arlandis

unread,
Apr 2, 2013, 1:09:07 PM4/2/13
to
Le 02/04/13 16:22, Eric Demeester a écrit :
> Julien Arlandis (Mon, 01 Apr 2013 19:27:21 +0200 - fr.comp.lang.php) :
>
> Bonjour Julien,
>
>> 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?

> 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.
>

Stéphane Catteau

unread,
Apr 2, 2013, 3:18:28 PM4/2/13
to
Olivier Miakinen n'était pas loin de dire :

>>>>>> $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.

Olivier Miakinen

unread,
Apr 2, 2013, 4:30:03 PM4/2/13
to
Le 02/04/2013 19:09, Julien Arlandis a écrit :
>
> [...] 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
Thunderbird en format non flowed :

> 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

Julien Arlandis

unread,
Apr 2, 2013, 4:35:36 PM4/2/13
to
Le 02/04/13 22:30, Olivier Miakinen a écrit :
> Le 02/04/2013 19:09, Julien Arlandis a écrit :
>>
>> [...] 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 );
}



> 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.


Merci je teste.

>> 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
> Thunderbird en format non flowed :
>
>> 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 ?

Message has been deleted

Olivier Miakinen

unread,
Apr 2, 2013, 5:38:51 PM4/2/13
to
Le 02/04/2013 21:18, Stéphane Catteau a écrit :
>
>>>>>>> $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.

0 new messages