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

[Apache] mauvais charset

20 views
Skip to first unread message

Vincent Lefevre

unread,
Sep 7, 2002, 5:48:48 AM9/7/02
to
Certaines des pages web servies par Apache ont un encodage (charset)
en utf-8, indiqué par les lignes

<?xml version="1.0" encoding="utf-8"?>

et

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

Mais Apache signale que le document est en iso-8859-1 (sans pour autant
transcoder le document). Comment faire pour changer cela et obtenir
d'Apache qu'il signale le bon charset?

--
Vincent Lefèvre <vin...@vinc17.org> - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Patrick

unread,
Sep 9, 2002, 4:19:27 AM9/9/02
to
> transcoder le document). Comment faire pour changer cela et obtenir
> d'Apache qu'il signale le bon charset?

Cf http://httpd.apache.org/docs/mod/core.html#adddefaultcharset
et éventuellement
http://httpd.apache.org/docs/mod/mod_mime.html#addcharset

Patrick.

Vincent Lefevre

unread,
Sep 9, 2002, 6:34:23 AM9/9/02
to
Dans l'article <pan.2002.09.09.10...@gandi.net>,
Patrick <patric...@gandi.net> écrit:

> Cf http://httpd.apache.org/docs/mod/core.html#adddefaultcharset

Le charset par défaut est bon, c'est bien ISO-8859-1. Mais là, je veux
de l'UTF-8.

> et éventuellement
> http://httpd.apache.org/docs/mod/mod_mime.html#addcharset

C'est basé sur l'extension, donc cela ne convient pas (d'autant plus
que ce sont des fichiers récupérés sur le web, donc je n'ai pas le
choix de l'extension).

Il faudrait qu'Apache regarde le contenu du fichier (la première ligne
suffit, puisque ce sont des fichiers XHTML) ou alors qu'il puisse prendre
en compte un préfixe pour le nom du fichier (mais c'est moins bien, car
pas automatique).

Patrick

unread,
Sep 9, 2002, 8:05:14 AM9/9/02
to
> Il faudrait qu'Apache regarde le contenu du fichier (la première ligne
> suffit, puisque ce sont des fichiers XHTML) ou alors qu'il puisse

modperl

Patrick.

Vincent Lefevre

unread,
Sep 9, 2002, 8:27:02 AM9/9/02
to
Dans l'article <pan.2002.09.09.14...@gandi.net>,
Patrick <patric...@gandi.net> écrit:

>> Il faudrait qu'Apache regarde le contenu du fichier (la première ligne
>> suffit, puisque ce sont des fichiers XHTML) ou alors qu'il puisse

> modperl

Je n'ai jamais utilisé ces choses-là. URL?

Patrick

unread,
Sep 9, 2002, 9:05:55 AM9/9/02
to
>>> Il faudrait qu'Apache regarde le contenu du fichier (la première ligne
>>> suffit, puisque ce sont des fichiers XHTML) ou alors qu'il puisse
>
>> modperl
>
> Je n'ai jamais utilisé ces choses-là. URL?

En gros, dans votre cas, ca vous permettrait de construire un module
Apache, appelé en tant que Handler, mais écrit en Perl (ce qui est bien
plus simple que se taper du C)

Cf http://perl.Apache.org/ pour les détails.

Bref, un truc comme ca devrait fonctionner (à tester, c'est l'idée)

Dans Apache:
LoadModule perl_module /usr/lib/apache/1.3/mod_perl.so

<Location />
PerlSetEnv PERL5LIB /some/where
PerlTypeHandler ReadCharset
<Location>

Et dans un fichier ReadCharset.pm (dans le chemin /some/where)

use strict;
use Apache::Constants qw(:common);

sub handler
{
my $r=shift;
my $file=$r->filename();
open(F,"< ${file}") || return DECLINED;
my $first=<F>; ## on espère que c'est bien dans la 1ère ligne !
close(F) || return DECLINED;

my (undef,$enc)=($first=~m/(encoding|charset)="?(\S+)"/);
return DECLINED unless $enc;
$r->content_type("application/xml; charset=${enc}");
return OK
}
1;

Il faudra aussi probablement:
AddDefaultCharset off

Sinon (peut-être plus simple que modperl) vous pouvez aussi utiliser mod_headers
(http://httpd.apache.org/docs/mod/mod_headers.html) pour ajouter le bon
en-tête de vous-même.
Eventuellement couplé à mod_cern_meta
(http://httpd.apache.org/docs/mod/mod_cern_meta.html)

Patrick.

Vincent Lefevre

unread,
Sep 9, 2002, 12:20:53 PM9/9/02
to
Dans l'article <pan.2002.09.09.15....@gandi.net>,
Patrick <patric...@gandi.net> écrit:

> Sinon (peut-être plus simple que modperl) vous pouvez aussi utiliser mod_headers
> (http://httpd.apache.org/docs/mod/mod_headers.html) pour ajouter le bon
> en-tête de vous-même.
> Eventuellement couplé à mod_cern_meta
> (http://httpd.apache.org/docs/mod/mod_cern_meta.html)

Mais tout ça ne semble pas automatique. La meilleure solution semble
être mod_perl, même si c'est un peu lourd. Bizarre qu'Apache n'ait
pas cette fonctionnalité en standard.

Maxim Zakharov

unread,
Sep 9, 2002, 5:31:22 PM9/9/02
to
Vincent Lefevre wrote:

>> et éventuellement
>> http://httpd.apache.org/docs/mod/mod_mime.html#addcharset
>
> C'est basé sur l'extension, donc cela ne convient pas (d'autant plus
> que ce sont des fichiers récupérés sur le web, donc je n'ai pas le
> choix de l'extension).

Est-ce il y a posibilite placer tout fichiers avec meme charset dans les
repertoires divers et donner AddDefaultCharset pour chaque repertoire ?

>
> Il faudrait qu'Apache regarde le contenu du fichier (la première ligne
> suffit, puisque ce sont des fichiers XHTML) ou alors qu'il puisse prendre
> en compte un préfixe pour le nom du fichier (mais c'est moins bien, car
> pas automatique).

regarde le mod_mime_magic


--
Maxim Zakharov http://www.maxime.net.ru/
Sochi, Russia http://sochi.org.ru/

Vincent Lefevre

unread,
Sep 9, 2002, 6:15:15 PM9/9/02
to
Dans l'article <pan.2002.09.09.15....@gandi.net>,
Patrick <patric...@gandi.net> écrit:

> Dans Apache:
> LoadModule perl_module /usr/lib/apache/1.3/mod_perl.so

OK, après installation, le module est bien chargé:

[Tue Sep 10 00:01:46 2002] [notice] Apache/1.3.26 (Unix) Debian GNU/Linux mod_perl/1.26 configured -- resuming normal operations

> <Location />
> PerlSetEnv PERL5LIB /some/where

J'utilise /usr/local/lib/site_perl qui est dans le @INC, donc pas besoin
d'une telle ligne. J'y ai mis un script ReadEncoding.pm contenant une
routine handler:

use strict;
use Apache::Constants qw(:common);

sub handler
{
...
}

1;

> PerlTypeHandler ReadCharset

PerlTypeHandler ReadEncoding

dans mon cas.

> <Location>

</Location>

je suppose.

Mais ça ne fonctionne pas: j'obtiens l'erreur suivante:

[Tue Sep 10 00:01:51 2002] [error] Undefined subroutine &ReadEncoding::handler called.

J'ai essayé d'ajouter une ligne

SetHandler perl-script

avant la ligne PerlTypeHandler, mais ça ne change rien.

Que faire?

Vincent Lefevre

unread,
Sep 9, 2002, 6:27:37 PM9/9/02
to
Dans l'article <4413904.J...@sochi.com>,
Maxim Zakharov <max...@sochi.net.ru> écrit:

> Est-ce il y a posibilite placer tout fichiers avec meme charset dans les
> repertoires divers et donner AddDefaultCharset pour chaque repertoire ?

Ce n'est pas pratique: à chaque fois que j'installerai de nouveaux
fichiers/répertoires (dans un endroit dépendant du contenu du document,
pas de la manière dont il est encodé), il faudra que je modifie la
configuration d'Apache. Pas terrible!

>> Il faudrait qu'Apache regarde le contenu du fichier (la première ligne
>> suffit, puisque ce sont des fichiers XHTML) ou alors qu'il puisse prendre
>> en compte un préfixe pour le nom du fichier (mais c'est moins bien, car
>> pas automatique).

> regarde le mod_mime_magic

Ça ne donne apparemment pas l'encodage.

Vincent Lefevre

unread,
Sep 9, 2002, 6:40:21 PM9/9/02
to
Dans l'article <20020909220423$6f...@vinc17.org>,
Vincent Lefevre <vincen...@vinc17.org> écrit:

> Mais ça ne fonctionne pas: j'obtiens l'erreur suivante:

> [Tue Sep 10 00:01:51 2002] [error] Undefined subroutine &ReadEncoding::handler called.

Bon, après une recherche sur Google Groups, j'ai finalement trouvé
qu'il fallait une ligne

package ReadEncoding;

au début du script.

Je n'ai plus d'erreur, mais le charset n'est pas modifié.

Vincent Lefevre

unread,
Sep 9, 2002, 6:47:32 PM9/9/02
to
Dans l'article <20020909223554$31...@vinc17.org>,
Vincent Lefevre <vincen...@vinc17.org> écrit:

> Bon, après une recherche sur Google Groups, j'ai finalement trouvé


> qu'il fallait une ligne

> package ReadEncoding;

> au début du script.

> Je n'ai plus d'erreur, mais le charset n'est pas modifié.

Autre problème: sur certaines pages (e.g. http://localhost/~lefevre/),
je me prends un 404 Not Found. Si je commente le

<Location />
PerlTypeHandler ReadEncoding
</Location>

le problème des 404 Not Found disparaît.

Patrick

unread,
Sep 10, 2002, 6:16:04 AM9/10/02
to
>> Bon, après une recherche sur Google Groups, j'ai finalement trouvé
>> qu'il fallait une ligne
>
>> package ReadEncoding;
>
>> au début du script.

Oui, pardon, oubli de ma part.



>> Je n'ai plus d'erreur, mais le charset n'est pas modifié.

On a quoi exactement au niveau en-tête HTTP ?
AddDefaultCharset est bien à none ?

Je viens de tester, exactement avec le code que je vous ai donné, et cela
marche bien chez moi.

> Autre problème: sur certaines pages (e.g. http://localhost/~lefevre/),
> je me prends un 404 Not Found. Si je commente le
>
> <Location />
> PerlTypeHandler ReadEncoding
> </Location>

Si possible, restreindre le champ pour que le PerlTypeHandler ne
s'applique vraiment que là où nécessaire.

> le problème des 404 Not Found disparaît.

Il manque probablement des tests.
Il faut vérifier que $file existe bien et correspond bien à un fichier.

Après le my $file
un truc du style
return DECLINED unless -f $file;

D'autre part, juste après my $r=shift :
return DECLINED unless $r->is_main();

Patrick.

Vincent Lefevre

unread,
Sep 10, 2002, 7:46:13 AM9/10/02
to
Dans l'article <pan.2002.09.10.12....@gandi.net>,
Patrick <patric...@gandi.net> écrit:

> On a quoi exactement au niveau en-tête HTTP ?
> AddDefaultCharset est bien à none ?

Il était à on. Mais il faut un charset par défaut à iso-8859-1.
J'ai vu quelque part dans la doc qu'il vaut mieux utiliser
PerlFixupHandler que PerlTypeHandler à cause de ces problèmes.

Mais est-ce que le script resterait le même à part ça?

>> Autre problème: sur certaines pages (e.g. http://localhost/~lefevre/),
>> je me prends un 404 Not Found. Si je commente le
>>
>> <Location />
>> PerlTypeHandler ReadEncoding
>> </Location>

> Si possible, restreindre le champ pour que le PerlTypeHandler ne
> s'applique vraiment que là où nécessaire.

Il vaut mieux qu'il s'applique partout.

>> le problème des 404 Not Found disparaît.

> Il manque probablement des tests.
> Il faut vérifier que $file existe bien et correspond bien à un fichier.

> Après le my $file
> un truc du style
> return DECLINED unless -f $file;

Que veut dire le DECLINED? Et le OK?

> D'autre part, juste après my $r=shift :
> return DECLINED unless $r->is_main();

Qu'est-ce que cela signifie en pratique?

D'autre part, après une recherche sur is_main (sur perl.apache.org),
j'ai obtenu

http://perl.apache.org/docs/2.0/user/compat/compat.html#C__r_E_gt_is_main_

qui indique:

$r->is_main is not part of the mod_perl 2.0 API. Use !$r->main instead.

Je suppose qu'il vaut mieux alors

return DECLINED if $r->main();

Patrick

unread,
Sep 10, 2002, 10:20:53 AM9/10/02
to
>> On a quoi exactement au niveau en-tête HTTP ? AddDefaultCharset est
>> bien à none ?
>
> Il était à on. Mais il faut un charset par défaut à iso-8859-1. J'ai vu
> quelque part dans la doc qu'il vaut mieux utiliser PerlFixupHandler que
> PerlTypeHandler à cause de ces problèmes.
>
> Mais est-ce que le script resterait le même à part ça?

Oui, ca ne change rien.

>> Après le my $file
>> un truc du style
>> return DECLINED unless -f $file;
>
> Que veut dire le DECLINED? Et le OK?

DECLINED = le code dit à Apache: finalement je veux pas gérer ce cas,
donc ca ``retombe'' dans le code standard Apache qui gère normalement ce
cas

OK = j'ai fait le boulot, Apache n'a plus rien à faire (pour cette phase)



>> D'autre part, juste après my $r=shift : return DECLINED unless
>> $r->is_main();
>
> Qu'est-ce que cela signifie en pratique?

Quand on interroge un répertoire, Apache fait des ``sous''-requêtes en
interne. La première est la main, et pas les autres.
Le comportement n'est pas tout à fait le même dans les deux cas, d'où
nécessité de discriminer.

> $r->is_main is not part of the mod_perl 2.0 API. Use !$r->main
> instead.
>
> Je suppose qu'il vaut mieux alors
>
> return DECLINED if $r->main();

Il manque le ! devant $r->main()
sinon mettre un unless au lieu du if.
(on ne process que si on est dans le main)

Perso, en Apache 1.3 ca fonctionne bien (le code donné précédemment).

Patrick.

Vincent Lefevre

unread,
Sep 10, 2002, 11:37:31 AM9/10/02
to
Dans l'article <pan.2002.09.10.16....@gandi.net>,
Patrick <patric...@gandi.net> écrit:

> DECLINED = le code dit à Apache: finalement je veux pas gérer ce cas,
> donc ca ``retombe'' dans le code standard Apache qui gère normalement ce
> cas

> OK = j'ai fait le boulot, Apache n'a plus rien à faire (pour cette phase)

Bon, dans ce cas, il me semble que le AddDefaultCharset ne devrait
rien changer si on retourne OK (ce qui est le cas de ma routine).

Et puis si on fixe le charset à UTF-8, le AddDefaultCharset ne
devrait de toute façon pas s'appliquer, puisqu'il ne concerne
que les cas où le charset n'a pas été explicitement fixé.

Y a-t-il quelque chose que j'ai manqué?

>>> D'autre part, juste après my $r=shift : return DECLINED unless
>>> $r->is_main();
>>
>> Qu'est-ce que cela signifie en pratique?

> Quand on interroge un répertoire, Apache fait des ``sous''-requêtes en
> interne. La première est la main, et pas les autres.
> Le comportement n'est pas tout à fait le même dans les deux cas, d'où
> nécessité de discriminer.

OK, donc on décline pour les requêtes internes.

>> $r->is_main is not part of the mod_perl 2.0 API. Use !$r->main
>> instead.
>>
>> Je suppose qu'il vaut mieux alors
>>
>> return DECLINED if $r->main();

> Il manque le ! devant $r->main()
> sinon mettre un unless au lieu du if.

Pas d'accord. Cf le code ci-dessus:

return DECLINED unless $r->is_main();

C'est équivalent à

return DECLINED unless !$r->main();

d'après la doc, et donc à

return DECLINED if $r->main();

à moins que la doc soit incorrecte...

Patrick

unread,
Sep 10, 2002, 12:47:40 PM9/10/02
to
> Bon, dans ce cas, il me semble que le AddDefaultCharset ne devrait rien
> changer si on retourne OK (ce qui est le cas de ma routine).
>
> Et puis si on fixe le charset à UTF-8, le AddDefaultCharset ne devrait
> de toute façon pas s'appliquer, puisqu'il ne concerne que les cas où le
> charset n'a pas été explicitement fixé.
>
> Y a-t-il quelque chose que j'ai manqué?

Je suis d'accord avec vous, sur la théorie. Je ne sais si en pratique
c'est tout à fait équivalent.



>>>> D'autre part, juste après my $r=shift : return DECLINED unless
>>>> $r->is_main();
>>>
>>> Qu'est-ce que cela signifie en pratique?
>

> OK, donc on décline pour les requêtes internes.

Oui.

> Pas d'accord. Cf le code ci-dessus:

[..]


> à moins que la doc soit incorrecte...

Je sais pas, ca me parait bizarre (vu le nom), mais j'ai pas encore
touché à mod_perl sous Apache 2 (qui n'est pas finalisé), donc je prends
un joker. Quoiqu'il en soit, vous avez tout compris dans la phrase
précédente (on décline pour les requêtes internes), donc suffit de
prendre ca comme ligne de conduite ;-)

En espérant que vous allez toucher au but maintenant.

Patrick.

Vincent Lefevre

unread,
Sep 10, 2002, 3:16:41 PM9/10/02
to
Dans l'article <pan.2002.09.10.18....@gandi.net>,
Patrick <patric...@gandi.net> écrit:

> Je sais pas, ca me parait bizarre (vu le nom), mais j'ai pas encore
> touché à mod_perl sous Apache 2 (qui n'est pas finalisé), donc je prends
> un joker. Quoiqu'il en soit, vous avez tout compris dans la phrase
> précédente (on décline pour les requêtes internes), donc suffit de
> prendre ca comme ligne de conduite ;-)

Dans les deux cas, il y a un problème:

_ Avec "return DECLINED if $r->main();" après le "my $r = shift;",
j'obtiens une erreur 404 Not Found pour <http://localhost/~lefevre/>.

_ Avec "return DECLINED unless $r->main();" sur la même URL, j'obtiens
l'index du répertoire, comme s'il n'y avait pas de fichier index.html.

En revanche, si j'écris "return DECLINED;" avant le "my $r = shift;",
tout se passe bien!!!

J'ai l'impression que l'appel à $r->main() produit un effet secondaire
indésirable.

J'ai testé la même chose avec $r->is_main(), et j'obtiens les mêmes
problèmes mais inversés, ce qui est consistant avec la doc (cf le "!").

Une idée?

Vincent Lefevre

unread,
Sep 10, 2002, 3:38:15 PM9/10/02
to
J'ai essayé avec PerlFixupHandler au lieu de PerlTypeHandler. Je n'ai
pas ces problèmes de 404 Not Found ou d'index. En revanche, impossible
de changer le charset.

Note: j'ai mis un warn juste avant la ligne $r->content_type(...) pour
m'assurer à l'aide du fichier de log que l'encodage est bien lu.

Patrick

unread,
Sep 12, 2002, 5:51:59 AM9/12/02
to
On Tue, 10 Sep 2002 21:16:41 +0200, Vincent Lefevre wrote:

> Dans l'article <pan.2002.09.10.18....@gandi.net>,
> Patrick <patric...@gandi.net> écrit:
>
>> Je sais pas, ca me parait bizarre (vu le nom), mais j'ai pas encore
>> touché à mod_perl sous Apache 2 (qui n'est pas finalisé), donc je
>> prends un joker. Quoiqu'il en soit, vous avez tout compris dans la
>> phrase précédente (on décline pour les requêtes internes), donc suffit
>> de prendre ca comme ligne de conduite ;-)
>
> Dans les deux cas, il y a un problème:

D'abord: vous êtes en Apache 1.3 ou Apache 2.0 ?
Car c'est sûr de fonctionner en 1.3, alors qu'en 2.0 c'est encore
instable (mod_perl)

Je viens de vérifier dans le Eagle Book, y a un exemple *très* similaire.
C'est bien PerlFixupHandler qu'il faut.
Et il y a bien un:
return DECLINED if
!$r->is_main()
|| $r->content_type ne 'text/html'
|| !open(FILE,$r->filename);

Bref, assez similaire à ce que je vous disais.
Peut-être le test sur le content_type suffirait dans votre cas.
En Apache 1.3

> _ Avec "return DECLINED if $r->main();" après le "my $r = shift;",
> j'obtiens une erreur 404 Not Found pour <http://localhost/~lefevre/>.

Essayez en ajoutant le content_type plus haut.



> _ Avec "return DECLINED unless $r->main();" sur la même URL, j'obtiens
> l'index du répertoire, comme s'il n'y avait pas de fichier index.html.

Hum...

> En revanche, si j'écris "return DECLINED;" avant le "my $r = shift;",
> tout se passe bien!!!

Oui, mais le module sert à rien (il redonne immédiatement la main à
Apache)



> J'ai testé la même chose avec $r->is_main(), et j'obtiens les mêmes
> problèmes mais inversés, ce qui est consistant avec la doc (cf le "!").

use Apache::compat;
peut aider aussi, à continuer d'utiliser l'ancienne API même sous Apache
2.0

Patrick.

Vincent Lefevre

unread,
Sep 12, 2002, 5:50:53 PM9/12/02
to
Dans l'article <pan.2002.09.12.11....@gandi.net>,
Patrick <patric...@gandi.net> écrit:

> D'abord: vous êtes en Apache 1.3 ou Apache 2.0 ?

1.3

> Je viens de vérifier dans le Eagle Book, y a un exemple *très* similaire.
> C'est bien PerlFixupHandler qu'il faut.
> Et il y a bien un:
> return DECLINED if
> !$r->is_main()
> || $r->content_type ne 'text/html'
> || !open(FILE,$r->filename);

Merci, avec ça, tout fonctionne comme voulu. Enfin, bizarre tout
de même, car il y a toujours l'appel à main() qui ne fonctionnait
pas auparavant.

>> En revanche, si j'écris "return DECLINED;" avant le "my $r = shift;",
>> tout se passe bien!!!

> Oui, mais le module sert à rien (il redonne immédiatement la main à
> Apache)

C'était juste pour tester.

Vincent Lefevre

unread,
Sep 13, 2002, 5:00:44 AM9/13/02
to
Dans l'article <20020912214713$00...@vinc17.org>,
Vincent Lefevre <vincen...@vinc17.org> écrit:

> Merci, avec ça, tout fonctionne comme voulu. Enfin, bizarre tout


> de même, car il y a toujours l'appel à main() qui ne fonctionnait
> pas auparavant.

J'ai mis toutes les infos et le module sur mes pages web, au cas où
ça intéresserait d'autres utilisateurs...

0 new messages