Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

annonce du codage via POST multipart/from-data

15 réponses
Avatar
Paul Gaborit
Bonjour,

J'ai un problème de décodage des données soumises via des formulaires.

Plusieurs formulaires (sur des serveurs différents et utilisant des
codages différents) doivent soummettre de données à une même
application. Mon souci est de détecter dans cette application, le
codage des données soumises.

Pour l'illustrer, voici deux formulaires identiques sauf que l'un
soumet ses données codées en utf8 et l'autre en iso-8859-1 :

<form action="" method="post" enctype="multipart/form-data"
accept-charset="utf8">
<p>
Soummission en utf8&nbsp;:<br />
<textarea name="texte" rows="3" cols="50"></textarea>
<br />
<input type="submit" value="Envoyer" />
</p>
</form>

<form action="" method="post" enctype="multipart/form-data"
accept-charset="iso-8859-1">
<p>
Soummission en iso-8859-1&nbsp;:<br />
<textarea name="texte" rows="3" cols="50">Essai</textarea>
<br />
<input type="submit" value="Envoyer" />
</p>
</form>

Si je saisie le caractère "é" dans mon champ texte avec le premier
formulaire, voici un extrait de la requête HTTP qui est transmise (par
firefox) :

++++++++++++++++++++++++++++++++++++++++
Content-Length: 174
Content-Type: multipart/form-data; boundary=---------------------------74604530118940943891270616348
Keep-Alive: 300
Proxy-Connection: keep-alive

-----------------------------74604530118940943891270616348
Content-Disposition: form-data; name="texte"

é
-----------------------------74604530118940943891270616348--

++++++++++++++++++++++++++++++++++++++++

Si je saisie le même caractère "é" dans le champ texte mais cette fois
avec le second formulaire, voici un extrait de la requête HTTP qui est
transmise (par firefox) :

++++++++++++++++++++++++++++++++++++++++
Content-Length: 173
Content-Type: multipart/form-data; boundary=---------------------------12732967551707535069857896562
Keep-Alive: 300
Proxy-Connection: keep-alive

-----------------------------12732967551707535069857896562
Content-Disposition: form-data; name="texte"

é
-----------------------------12732967551707535069857896562--

++++++++++++++++++++++++++++++++++++++++

Les autres en-têtes des deux requêtes sont similaires. Firefox a bien
respecté le codage demandé (utf8 dans un cas et iso-8859-1 dans
l'autre) par chacun des deux formulaires.

Mais dans les requêtes rien n'indique le codage utilisé pour le
contenu du champ 'texte'. Donc, du côté du serveur qui ne peut pas
savoir quel formualire a été utilisé, on ne peut pas distinguer par
exemple l'envoi d'un "é" via le formulaire codé en utf8 de l'envoi de
"é" via le formulaire codé en iso-8859-1 !

De plus, MIME permet de spécifier le codage de chacun des différents
éléments d'un message multipart/form-data. Pourquoi Firefox ne
l'indique pas dans sa requête ?

Merci.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>

10 réponses

1 2
Avatar
Olivier Masson
Paul Gaborit a écrit :
Bonjour,

J'ai un problème de décodage des données soumises via des formulaires.

Plusieurs formulaires (sur des serveurs différents et utilisant des
codages différents) doivent soummettre de données à une même
application. Mon souci est de détecter dans cette application, le
codage des données soumises.



Tu as été voir du côté de mbstring (mb_http_input, mb_detect_encoding, etc.?
Mais lire http://docs.php.net/manual/fr/ref.mbstring.php, section
entrée/sortie HTTP.
Avatar
Paul Gaborit
À (at) Wed, 19 Dec 2007 13:54:56 +0100,
Olivier Masson écrivait (wrote):
Paul Gaborit a écrit :
Bonjour,

J'ai un problème de décodage des données soumises via des formulaires.

Plusieurs formulaires (sur des serveurs différents et utilisant des
codages différents) doivent soummettre de données à une même
application. Mon souci est de détecter dans cette application, le
codage des données soumises.



Tu as été voir du côté de mbstring (mb_http_input, mb_detect_encoding, etc.?
Mais lire http://docs.php.net/manual/fr/ref.mbstring.php, section
entrée/sortie HTTP.



Le problème est donc bien que l'information d'encodage de chacun des
champs soumis en multipart/form-data n'est pas transmise via la
requête POST (en tous cas depuis Firefox).

Vous me proposez donc de tenter un détection automatique ou une
conversion systématique. Que ce soit en PHP, en Perl, en Python... ce
genre de choses est malheureusement voué à l'échec.

Il est impossible de distinguer l'envoi de la valeur 'é' (codé en
UTF-8) de l'envoi de la valeur 'é' (codé en iso-8859-1). Leur
représentation binaire est strictement identique !

Cela m'étonne que personne n'ait jamais rencontré ce problème.


--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Avatar
Pierre Goiffon
Paul Gaborit wrote:
J'ai un problème de décodage des données soumises via des formulaires.

Plusieurs formulaires (sur des serveurs différents et utilisant des
codages différents) doivent soummettre de données à une même
application. Mon souci est de détecter dans cette application, le
codage des données soumises.

Pour l'illustrer, voici deux formulaires identiques sauf que l'un
soumet ses données codées en utf8 et l'autre en iso-8859-1 :

<form action="" method="post" enctype="multipart/form-data"
accept-charset="utf8">
<p>
Soummission en utf8&nbsp;:<br />
<textarea name="texte" rows="3" cols="50"></textarea>
<br />
<input type="submit" value="Envoyer" />
</p>
</form>

<form action="" method="post" enctype="multipart/form-data"
accept-charset="iso-8859-1">
<p>
Soummission en iso-8859-1&nbsp;:<br />
<textarea name="texte" rows="3" cols="50">Essai</textarea>
<br />
<input type="submit" value="Envoyer" />
</p>
</form>

Si je saisie le caractère "é" dans mon champ texte avec le premier
formulaire, voici un extrait de la requête HTTP qui est transmise (par
firefox) :

++++++++++++++++++++++++++++++++++++++++
Content-Length: 174
Content-Type: multipart/form-data; boundary=---------------------------74604530118940943891270616348
Keep-Alive: 300
Proxy-Connection: keep-alive

-----------------------------74604530118940943891270616348
Content-Disposition: form-data; name="texte"

é
-----------------------------74604530118940943891270616348--

++++++++++++++++++++++++++++++++++++++++

Si je saisie le même caractère "é" dans le champ texte mais cette fois
avec le second formulaire, voici un extrait de la requête HTTP qui est
transmise (par firefox) :

++++++++++++++++++++++++++++++++++++++++
Content-Length: 173
Content-Type: multipart/form-data; boundary=---------------------------12732967551707535069857896562
Keep-Alive: 300
Proxy-Connection: keep-alive

-----------------------------12732967551707535069857896562
Content-Disposition: form-data; name="texte"

é
-----------------------------12732967551707535069857896562--

++++++++++++++++++++++++++++++++++++++++

Les autres en-têtes des deux requêtes sont similaires. Firefox a bien
respecté le codage demandé (utf8 dans un cas et iso-8859-1 dans
l'autre) par chacun des deux formulaires.

Mais dans les requêtes rien n'indique le codage utilisé pour le
contenu du champ 'texte'. Donc, du côté du serveur qui ne peut pas
savoir quel formualire a été utilisé, on ne peut pas distinguer par
exemple l'envoi d'un "é" via le formulaire codé en utf8 de l'envoi de
"é" via le formulaire codé en iso-8859-1 !

De plus, MIME permet de spécifier le codage de chacun des différents
éléments d'un message multipart/form-data. Pourquoi Firefox ne
l'indique pas dans sa requête ?



Question intéressante... Je vous conseille très vivement d'aller la
poser sur par exemple comp.infosystems.www.authoring.html où plus
d'intervenants pourront vous répondre.

De mon côté je ne saurai que vous renvoyer vers la page de référence :
<http://web.archive.org/web/20060427015200/ppewww.ph.gla.ac.uk/~flavell/charset/form-i18n.html>
(un chapitre court et peu encourageant pour vous est consacré au
multipart/form-data)
Avatar
Paul Gaborit
À (at) Wed, 19 Dec 2007 16:54:32 +0100,
Pierre Goiffon écrivait (wrote):
Paul Gaborit wrote:


[...]

Mais dans les requêtes rien n'indique le codage utilisé pour le
contenu du champ 'texte'. Donc, du côté du serveur qui ne peut pas
savoir quel formualire a été utilisé, on ne peut pas distinguer par
exemple l'envoi d'un "é" via le formulaire codé en utf8 de l'envoi de
"é" via le formulaire codé en iso-8859-1 !

De plus, MIME permet de spécifier le codage de chacun des différents
éléments d'un message multipart/form-data. Pourquoi Firefox ne
l'indique pas dans sa requête ?



Question intéressante... Je vous conseille très vivement d'aller la
poser sur par exemple comp.infosystems.www.authoring.html où plus
d'intervenants pourront vous répondre.

De mon côté je ne saurai que vous renvoyer vers la page de référence :
<http://web.archive.org/web/20060427015200/ppewww.ph.gla.ac.uk/~flavell/charset/form-i18n.html>
(un chapitre court et peu encourageant pour vous est consacré au
multipart/form-data)



Je viens de lire cet page qui, même si elle date un peu, décrit
parfaitement ce que mes différentes expérimentations m'avaient fait
constater. Comme quoi les choses n'ont pas beaucoup évolué...

Je comprends parfaitement que, dans le cas du passage par GET (et donc
par un URL), on soit obligé de passer par de la détection automatique
comme fait Google (et encore...).

Mais ce qui m'étonne, c'est lorsqu'on passe par POST et
multipart/form-data... Tous les mécanismes (en particulier MIME et le
charset des Content-Type) existent pour pouvoir indiquer explicitement
le codage utilisé par la requête voire même un codage différent par
champ (ça marche d'ailleurs assez bien pour les fichiers). Mais ce
n'est tout simplement pas utilisé !

Juste pour voir, je vais tester le champ _charset_ mais je ne sais pas
combien de navigateurs respectent cela... ça ne me laisse donc pas
beaucoup d'espoir.

Par contre, la méthode avec champ caché de contrôle (je n'y avais pas
pensé) même si elle n'est pas complètement satisfaisante doit donner
de bons résultats (en tous cas fiables). Combinée avec de la
validation des caractères autorisés, on doit pouvoir faire quelque
chose d'à peu près efficace...

Merci pour le lien.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Avatar
Olivier Masson
Paul Gaborit a écrit :

Il est impossible de distinguer l'envoi de la valeur 'é' (codé en
UTF-8) de l'envoi de la valeur 'é' (codé en iso-8859-1). Leur
représentation binaire est strictement identique !




Certes. Si on raisonne strictement, c'est gênant. Mais quelle est la
probabilité de recevoir, dans un champ "lisible par un humain", la suite
é ? Et je pense que les algo de détection se base sur cette
constatation évidente (le a majuscule avec tréma ne doit pas déjà être
très courant, mais suivi d'un copyright...)
Avatar
Jibé
Bonjour,

pourquoi ne pas tester d'où provient la requête ?
Si le codage est lié à un serveur alors un test sur l'ip ou bien le
domaine devrait permettre de savoir en quel format sont codées les données.
Où je dis une bêtise ?...

JiBé
Paul Gaborit a écrit :
Bonjour,

J'ai un problème de décodage des données soumises via des formulaires.

Plusieurs formulaires (sur des serveurs différents et utilisant des
codages différents) doivent soummettre de données à une même
application. Mon souci est de détecter dans cette application, le
codage des données soumises.

Pour l'illustrer, voici deux formulaires identiques sauf que l'un
soumet ses données codées en utf8 et l'autre en iso-8859-1 :

<form action="" method="post" enctype="multipart/form-data"
accept-charset="utf8">
<p>
Soummission en utf8&nbsp;:<br />
<textarea name="texte" rows="3" cols="50"></textarea>
<br />
<input type="submit" value="Envoyer" />
</p>
</form>

<form action="" method="post" enctype="multipart/form-data"
accept-charset="iso-8859-1">
<p>
Soummission en iso-8859-1&nbsp;:<br />
<textarea name="texte" rows="3" cols="50">Essai</textarea>
<br />
<input type="submit" value="Envoyer" />
</p>
</form>

Si je saisie le caractère "é" dans mon champ texte avec le premier
formulaire, voici un extrait de la requête HTTP qui est transmise (par
firefox) :

++++++++++++++++++++++++++++++++++++++++
Content-Length: 174
Content-Type: multipart/form-data; boundary=---------------------------74604530118940943891270616348
Keep-Alive: 300
Proxy-Connection: keep-alive

-----------------------------74604530118940943891270616348
Content-Disposition: form-data; name="texte"

é
-----------------------------74604530118940943891270616348--

++++++++++++++++++++++++++++++++++++++++

Si je saisie le même caractère "é" dans le champ texte mais cette fois
avec le second formulaire, voici un extrait de la requête HTTP qui est
transmise (par firefox) :

++++++++++++++++++++++++++++++++++++++++
Content-Length: 173
Content-Type: multipart/form-data; boundary=---------------------------12732967551707535069857896562
Keep-Alive: 300
Proxy-Connection: keep-alive

-----------------------------12732967551707535069857896562
Content-Disposition: form-data; name="texte"

é
-----------------------------12732967551707535069857896562--

++++++++++++++++++++++++++++++++++++++++

Les autres en-têtes des deux requêtes sont similaires. Firefox a bien
respecté le codage demandé (utf8 dans un cas et iso-8859-1 dans
l'autre) par chacun des deux formulaires.

Mais dans les requêtes rien n'indique le codage utilisé pour le
contenu du champ 'texte'. Donc, du côté du serveur qui ne peut pas
savoir quel formualire a été utilisé, on ne peut pas distinguer par
exemple l'envoi d'un "é" via le formulaire codé en utf8 de l'envoi de
"é" via le formulaire codé en iso-8859-1 !

De plus, MIME permet de spécifier le codage de chacun des différents
éléments d'un message multipart/form-data. Pourquoi Firefox ne
l'indique pas dans sa requête ?

Merci.

Avatar
Paul Gaborit
À (at) Wed, 19 Dec 2007 21:22:29 +0100,
Olivier Masson écrivait (wrote):
Paul Gaborit a écrit :

Il est impossible de distinguer l'envoi de la valeur 'é' (codé en
UTF-8) de l'envoi de la valeur 'é' (codé en iso-8859-1). Leur
représentation binaire est strictement identique !




Certes. Si on raisonne strictement, c'est gênant. Mais quelle est la
probabilité de recevoir, dans un champ "lisible par un humain", la
suite é ? Et je pense que les algo de détection se base sur cette
constatation évidente (le a majuscule avec tréma ne doit pas déjà être
très courant, mais suivi d'un copyright...)



Mais ce n'est qu'un exemple parmi d'autre... Et que pensez des &#xxxx;
par lesquels firefox remplace les caractères exotiques lorsqu'on tente
de poster des caractères inexistants dans le charset retenuf sans même
encoder le '&' de la séquence "&#yyyy;" si elle apparaît normalement
ailleurs.

Et puis la détection par heuristique prend du temps alors qu'il aurait
été si simple de transmettre l'information...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Avatar
Paul Gaborit
À (at) Thu, 20 Dec 2007 09:18:00 +0100,
Jibé écrivait (wrote):
pourquoi ne pas tester d'où provient la requête ?



Elle provient d'un navigateur... ou d'un autre. Peut-être d'un
formulaire ou mais peut-être aussi de quelqu'un qui a écrit un
programme pour faire des requêtes automatiques ou encore...

Si le codage est lié à un serveur alors un test sur l'ip ou bien le
domaine devrait permettre de savoir en quel format sont codées les
données.
Où je dis une bêtise ?...



Je crois. Pour un serveur, a priori, les seuls éléments fiables sont
contenus dans la requête qu'il reçoit. Et encore faut-il les valider.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Avatar
Pierre Goiffon
Paul Gaborit wrote:
<http://web.archive.org/web/20060427015200/ppewww.ph.gla.ac.uk/~flavell/charset/form-i18n.html>
(un chapitre court et peu encourageant pour vous est consacré au
multipart/form-data)



Juste pour voir, je vais tester le champ _charset_ mais je ne sais pas
combien de navigateurs respectent cela... ça ne me laisse donc pas
beaucoup d'espoir.

Par contre, la méthode avec champ caché de contrôle (je n'y avais pas
pensé) même si elle n'est pas complètement satisfaisante doit donner
de bons résultats (en tous cas fiables). Combinée avec de la
validation des caractères autorisés, on doit pouvoir faire quelque
chose d'à peu près efficace...



Ou n'utiliser des form multipart/form-data que pour envoyer des fichiers ?
Avatar
Paul Gaborit
À (at) Thu, 20 Dec 2007 10:12:26 +0100,
Pierre Goiffon écrivait (wrote):
Ou n'utiliser des form multipart/form-data que pour envoyer des fichiers ?



En utilisant application/x-www-form-urlencoded ? C'est encore pire
puisqu'on ne peut utiliser que de l'ASCII !

Petit extrait des spécification HTML 4.01 :

The content type "application/x-www-form-urlencoded" is inefficient
for sending large quantities of binary data or text containing
non-ASCII characters. The content type "multipart/form-data" should
be used for submitting forms that contain files, non-ASCII data,
and binary data.

Donc, a priori, dès qu'on envoie autre chose que de l'ASCII, on
devrait utiliser multipart/form-data....


--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
1 2