in reply to perl -COE and, for example, CGI::Application

What I usually use for output encoding is just:

binmode STDOUT, ':utf8';

If you run in under FastCGI, put this line in cgiapp_prerun. In the mode where you output the binary data insert

binmode STDOUT,':raw';

If you expect unicode data from forms, you could put this code in your cgiapp_prerun stage:

my $vars = $self->query->Vars; while ( my($k,$v) = each %$vars ){ next unless defined $v; next if $self->query->upload($k); # uploads are binary next if $k eq 'auth_password'; # else MD5 crashes; $self->query->param( -name=>$k, -value=>Encode::decode_utf8($v) ); }

Using applications written with CGI::Application under FastCGI is a little bit troublesome. The recommended in the documentation method of programatically switching runmodes with "prerun_mode" leaves the object further unusable. So the the plugins that use this method (Forward, Redirect, Session, Authentication, Authorization) I find them unusable in fast-cgi environment.

Replies are listed 'Best First'.
Re^2: perl -COE and, for example, CGI::Application
by isync (Hermit) on Sep 23, 2008 at 10:29 UTC
    So, you would advocate for not using any switches on the perl shebang, right?

    Putting binmode STDOUT, ':utf8'; in cgiapp_prerun and doing binmode STDOUT,':raw'; just on runmodes where I output binary data is a very elegant solution, I think, as it resets STDOUT to :utf8 on every new cycle. -Right?

    In regards to "automatic decode_utf8($v) on form input with detection of uploads" I am conservative. Had a bit of trouble with it, thus falling back to doing it on a per runmode basis. Are your experiences more consistent (would this be production code)?

    I can't share your last comment: Might be that I do things less efficient but I have my fastcgi loop far enough around everything, so I can use the normal runmode switching facility and all mentioned plugins work under CGI::Fast.

      I think that it is better to do this with "binmode" but not with switches. One reason for this is that using "binmode" you could run the same cgi-app module under mod-perl.

      I use the decode_utf8() in prerun stage approach in production code. Initially I had some troubles caused by interaction of utf8 and MD5, but I escape this case. Pay attention that "auth_login/auth_passwword" is what I use for authentication, the default in CGI::Application::Plugin::Authentication is different.

      Now I see why you does not have problems with CGI::Fast - because you create new object for every request. My initial experience was with CGI::Application::FastCGI where the run handler is :

      sub run { my $self = shift; my $request = FCGI::Request(); $self->fastcgi($request); while ($request->Accept >= 0) { $self->reset_query; $self->SUPER::run; } }

      In your approach you have "new,run,new,run,new,run...". In my case I have "new,run,run,run...". Actually the difference in performance is not quite big but usually I have some heavy initialization in init stage that is run only once (on new object creation), so I see some benefit in using this approach.