[cgiapp] Problem displaying French, sometimes

Mike Tonks fluffymike at googlemail.com
Sun Sep 7 04:33:08 EDT 2008


I don't have a full explanation, but the second character looks like a
wrongly encoded double-byte utf8 issue, i.e. utf8 character (double
byte) being displayed as two characters.  Do you see 'wide character
in print anywhere?

This can happen when you concatenate two string together if the uft8
flags are not set correctly or if corruption has occurred.  For
example I recently had a mysql table with badly encoded utf8 stored in
it, which caused similar things to appear.

The DBI function data_string_desc may be useful to debug the status of
your strings.

What character set is your database using?

cheers, mike

2008/9/6 Ron Savage <ron at savage.net.au>:
> Hi Folks
>
> Here is the set up (details below):
> o An fcgid scripts calls...
> o A module based on CGI::Application::Dispatch, which calls...
> o My module, which reads country names from Postgres and displays them
>
> This works, so Ivory Coast is displayed as 'CÔte D'ivoire' (ignoring the
> upper-case O with caret for the moment).
>
> But when the first module above is installed as a mod_perl handler,
> and /that/ calls my module, the output is 'CÃ"te D'ivoire'.
>
> I find this scary, and would love an explanantion.
>
> Note: Commenting out CGI::Simple makes no difference, and commenting out
> 'use locale' makes no difference.
>
> Details:
> (1) OS:
> Debian
>
> (2) Web server:
> Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.8g
> mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0
>
> (3) httpd.conf:
> # Warning:
> # PerlOptions -GlobalRequest
> # won't work with CGI::Application::Dispatch.
>
> PerlOptions  +GlobalRequest
> PerlOptions  -SetupEnv
> PerlSetEnv   PGCLIENTENCODING LATIN1
> PerlSwitches -I/home/ron/perl.modules/Local-Sites/lib
> PerlSwitches -T
> PerlPostConfigRequire /home/ron/httpd/prefork/conf/startup.pl
>
> #PerlInitHandler Apache2::Reload
> #PerlSetVar ReloadAll Off
> #PerlSetVar ReloadModules Local::*
>
> <Location /test>
>    SetHandler perl-script
>    PerlResponseHandler Local::Sites::Test::Dispatcher
>    Order deny,allow
>    Deny from all
>    Allow from 127.0.0.1
> </Location>
>
> <Location /search>
>    SetHandler fcgid-script
>    Options ExecCGI
>    Order deny,allow
>    Deny from all
>    Allow from 127.0.0.1
> </Location>
>
> (4) startup.pl:
> # /home/ron/httpd/prefork/conf/startup.pl
>
> #use Apache::DBI;
> #use Apache2::Reload;
>
> #use Apache2::RequestRec  ();
> #use Apache2::RequestUtil ();
> #use Apache2::Response    ();
> use CGI::Application::Dispatch;
> use CGI::Simple;
> use HTML::Template;
> use Local::Sites::Base::DB;
> use Local::Sites::Config;
> use Local::Sites::Rose::Countries::Manager;
> use Local::Sites::Test::Dispatcher;
> use Local::Sites::Test::Sites;
> use Log::Dispatch;
> use Log::Dispatch::DBI;
>
> 1;
>
> (5) sites.fcgi, working when called as:
> http://127.0.0.1/search/sites.fcgi
>
> #!/usr/bin/perl
>
> # Mandatory use lib for FCGID.
>
> use lib '/home/ron/perl.modules/Local-Sites/lib';
> use strict;
> use warnings;
>
> use CGI::Fast;
> use FCGI::ProcManager;
> use Local::Sites::Test::Dispatcher;
>
> # -----------------------------------------------
>
> # Mandatory env var for FCGID. The value in httpd.conf is ignored.
>
> $ENV{PGCLIENTENCODING} = 'LATIN1';
> my($proc_manager)      = FCGI::ProcManager -> new({processes => 2});
>
> $proc_manager -> pm_manage();
>
> my($cgi);
>
> while ($cgi = CGI::Fast -> new() )
> {
>                $proc_manager -> pm_pre_dispatch();
>                Local::Sites::Test::Dispatcher -> dispatch();
>                $proc_manager -> pm_post_dispatch();
> }
>
> (6) Local::Sites::Test::Dispatcher:
> package Local::Sites::Test::Dispatcher;
>
> use base 'CGI::Application::Dispatch';
> use strict;
> use warnings;
>
> our $VERSION = '1.00';
>
> # -----------------------------------------------
>
> sub dispatch_args
> {
>        return
>        {
>                prefix => 'Local::Sites::Test',
>                table  =>
>                [
>                 ''         => {app => 'sites', rm => 'display'},
>                 ':app'     => {},
>                 ':app/:rm' => {},
>                ],
>        };
>
> } # End of dispatch_args.
>
> # -----------------------------------------------
>
> 1;
>
> (7) mod_perl activity, failing when called as:
> http://127.0.0.1/test/sites
>
> (8) My module:
> package Local::Sites::Test::Sites;
>
> # Author:
> #       Ron Savage <ron at savage.net.au>
>
> use base 'CGI::Application';
> use locale;
> use strict;
> use warnings FATAL => 'all', NONFATAL => 'redefine';
>
> use CGI::Simple;
> use DBI;
> use Local::Sites::Base::DB;
> use Local::Sites::Config;
> use Local::Sites::Rose::Countries::Manager;
> use Log::Dispatch;
> use Log::Dispatch::DBI;
>
> our $VERSION = '1.00';
>
> # -----------------------------------------------
>
> sub cgiapp_get_query
> {
>        my($self) = @_;
>
>        return CGI::Simple -> new();
>
> }       # End of cgiapp_get_query.
>
> # -----------------------------------------------
> # Convert, for example, AUSTRALIA to Australia.
>
> sub nice_name
> {
>        my($name) = @_;
>        $name     = ucfirst lc $name;
>        $name     =~ s/([ .(])([a-z])/$1\U$2/g;
>        $name     =~ s/(.+) \(See Also.+/$1/;
>        $name     =~ s/Of(\)|$)/of$1/;
>
>        return $name;
>
> } # End of nice_name.
>
> # -----------------------------------------------
>
> sub display
> {
>        my($self)     = @_;
>        my($country)  = Local::Sites::Rose::Countries::Manager ->
> get_countries();
>        my($template) = $self -> load_tmpl('country_state.tmpl');
>
>        $template -> param(country_loop => [map{ {name => nice_name($_ ->
> name() )} } @$country]);
>        $template -> param(encoding => $ENV{'PGCLIENTENCODING'});
>
>        for (@$country)
>        {
>                $self -> log($_ -> name() ) if ($_ -> name() =~ /IVOIRE/);
>        }
>
>        return $template -> output();
>
> } # End of display.
>
> # -----------------------------------------------
>
> sub log
> {
>        my($self, $s) = @_;
>
>        $$self{'_log'} -> log(level => 'info', message => $s ? "CGIApp: $s" :
> '');
>
> }       # End of log.
>
> # -----------------------------------------------
>
> sub setup
> {
>        my($self)      = @_;
>        my($config)    = Local::Sites::Config -> new();
>        my($host)      = $$config{'host'};
>        $$self{'_db'}  = Local::Sites::Base::DB -> new();
>        $$self{'_log'} = Log::Dispatch -> new();
>
>        $$self{'_log'} -> add
>        (
>                Log::Dispatch::DBI -> new
>                (
>                 dbh       => $$self{'_db'} -> retain_dbh(),
>                 min_level => 'info',
>                 name      => 'Sites',
>                )
>        );
>
>        $self -> log('-' x 30);
>        $self -> log($self -> query() -> url() );
>        $self -> param(config => $config);
>        $self -> run_modes({display => 'display'});
>        $self -> start_mode('display');
>        $self -> tmpl_path($config -> get_tmpl_path() );
>
> } # End of setup.
>
> # -----------------------------------------------
>
> 1;
>
> (9) The HTML template:
> <html>
>
> <head>
>  <title>Test Country and State</title>
> <!--  <meta http-equiv="Content-Type" content="text/html;
> charset=iso-8859-1" /> -->
> </head>
>
> <body>
>
> <h3 align="center" style="{color: #80c0ff;}">Test Country and State</h3>
>
> <form action="/search/local/sites/<tmpl_var name=run_mode>"
> name="search">
>
> <table align="center">
> <tr>
>                <th>Country (Encoding: <tmpl_var name=encoding>)</th>
> </tr>
> <tmpl_loop name=country_loop><tr><th><tmpl_var name=name></th></tr>
> </tmpl_loop>
> </table>
>
> </body>
> </html>
>
>
> --
> Ron Savage
> ron at savage.net.au
> http://savage.net.au/index.html
>
>
>
> #####  CGI::Application community mailing list  ################
> ##                                                            ##
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://lists.openlib.org/mailman/listinfo/cgiapp    ##
> ##                                                            ##
> ##  Web archive:   http://lists.openlib.org/pipermail/cgiapp/   ##
> ##  Wiki:          http://cgiapp.erlbaum.net/                 ##
> ##                                                            ##
> ################################################################
>
>


More information about the cgiapp mailing list