Trying to run old CGI-scripts under FastCGI. Printing without extra parameters gives proper output: print $q->div( $q->param("text") )
But when printing out with extra parameters hash for CGI-methods print $q->div( {-id=>"id"}, $q->param("text") ), it ruins UTF-8 formed data (‘õäöüžš’ -> ‘õäöüžš’)
It happens only with CGI parameters, in script defined variables work fine (examples 3 and 4). Everything works perfecty under ordinary CGI (with “-utf8”-flag ).
FastCGI-turned example script, called as test.fcgi?text=õäöüžš should give four equal blocks:
#!/usr/bin/perl -w --
use strict;
use CGI::Fast qw(:all);
use locale;
use utf8;
BEGIN {
binmode(STDIN); # Form data
binmode(STDOUT, ':encoding(UTF-8)'); # HTML
binmode(STDERR, ':encoding(UTF-8)'); # Error messages
}
my ($q) = ();
my $test = "õäöüžš";
while ($q = new CGI::Fast) {
print $q->header(-type=>"text/html", -charset=>"utf-8"),
$q->start_html(-encoding=>"utf-8");
print "1: ",
$q->div( $q->param('text') ),
"<br />",
"2: ",
$q->div( {-id=>"id"}, $q->param('text') ),
"<br />",
"3: ",
$q->div( $test ),
"<br />",
"4: ",
$q->div( {-id=>"id"}, $test ),
$q->end_html();
}
First block is fine, second broken, 3rd and 4th also fine:
Ordinary CGI-example as that gives all 4 right way:
#!/usr/bin/perl -w --
use strict;
use CGI qw(:all -utf8);
use locale;
use utf8;
BEGIN {
binmode(STDIN); # Form data
binmode(STDOUT, ':encoding(UTF-8)'); # HTML
binmode(STDERR, ':encoding(UTF-8)'); # Error messages
}
my ($q) = ();
my $test = "õäöüžš";
$q = new CGI;
print $q->header(-type=>"text/html", -charset=>"utf-8"),
$q->start_html(-encoding=>"utf-8");
print "1: ",
$q->div( $q->param('text') ),
"<br />",
"2: ",
$q->div( {-id=>"id"}, $q->param('text') ),
"<br />",
"3: ",
$q->div( $test ),
"<br />",
"4: ",
$q->div( {-id=>"id"}, $test ),
$q->end_html();
It seems to me, that with FastCGI form-data has no utf8-flag on and i don’t understand, how to properly force it? Under CGI.pm i declare as:
use CGI qw(:all -utf8);
But how with FastCGI?
1) CGI::Fast is a subclass of CGI.pm, so you can specify the same import arguments.
2) FCGI streams are implemented using the older stream API, TIEHANDLE. Applying PerlIO layers using binmode() has no effect. The proper solution would be to encode your data before outputting it, but if thats not an option I can offer this hotpatch: