Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^4: CGI::Application... flushing output to browser?

by Anonymous Monk
on May 04, 2012 at 11:06 UTC ( #968908=note: print w/ replies, xml ) Need Help??


in reply to Re^3: CGI::Application... flushing output to browser?
in thread CGI::Application... flushing output to browser?

Sorry about that. See below. It's a bit long, but it's a complex issue, and I can't find a shorter way of expressing all the things I have tried.

package SimpleApp; use base 'CGI::Application'; use strict; ################################################################### # # This script is an attempt at "subverting" CGI::Application into # running modes that print HTML directly to STDOUT, instead of # cumulating it into a string and returning it. # # It seems possible to do that, as long as you don't use the # Authentication plugin, as illustrated below. # # In this App, we have two versions of each of the run modes. # # The 'print_at_very_end' version implements the standard # CGI::Application # approach, namely, it collects the HTML output in a string # variable, and returns it. # # The 'print_as_you_go' version prints the HTML directly to # STDOUT, as soon as it is generated. These versions of the run # modes need to print headers themselves instead of letting # CGI::Application, because the later generates the headers AFTER # the body method has been called (and it prepends them to the body +). # But by that time, it's too late to print the headers, because # the body has already been printed to STDOUT. # # To switch between the 'print_as_you_go' and 'print_at_very_end' # versions, simply set $print_when to 'at_very_end' or 'as_you_go'. # # You can also run the application with, or without Authentication plu +gin. # Simply set $use_authentication to 1 or undef; # # Try the following scenarios. # # Scenario 1: 'print_at_very_end', with authentication # - Set $print_when = 'at_very_end' and $use_authentication = 1 # - Clear cookies # - go to simple_app.cgi # - login as u=guest, p=1234 # - notice how the Welcome page takes about 2 secs before it displays # anything (because it sleeps for 1 sec between generating each line + # and doesn't print anything until all the lines have been generated +) # - click on Help link # - notice how you're brought to the Help page without being asked # to login again # # Scenario 2: 'print_as_you_go', without authentication # - Set $print_when = 'as_you_go' and $use_authentication = undef # - Clear cookies # - go to simple_app.cgi # - no need to login (there is no authentication) # - notice how the content of the Welcome page starts being displayed # immediatly, without the 2 secs delay. # - click on Help link # - notice how you're brought to the Help page without being asked # to login again. # # Scenario 3: 'print_as_you_go', with authentication # - Set $print_when = 'as_you_go' and $use_authentication = 1 # - Clear cookies # - go to simple_app.cgi # - login as u=guest, p=1234 # - notice how the content of the Welcome page starts being displayed # immediatly, without the 2secs delay. # - click on Help link # - notice how you're asked to login again. # - login again as u=guest, p=1234 # - Notice how you are brought to the Welcome page again, # as opposed to the Help page you were trying to go to. # - This seems to be due to the fact that the session cookies # were not output correctly (they are part of the headers, # and we are mocking around with them in non-standard ways.) # ################################################################### my $print_when; BEGIN { # #$print_when = 'at_very_end'; $print_when = 'as_you_go'; my $use_authentication = 1; # my $use_authentication = undef; if ($use_authentication) { use CGI::Application::Plugin::Authentication; SimpleApp->authen->config( DRIVER => [ 'Generic', { guest => '1234'} ], POST_LOGIN_RUNMODE => 'welcome', LOGOUT_RUNMODE => "logout" ); SimpleApp->authen->protected_runmodes(':all'); } } sub setup { my $self = shift; $self->start_mode('welcome'); $self->run_modes( 'welcome' => "welcome_print_$print_when", 'logout' => "logout_print_$print_when", 'help' => "help_print_$print_when", 'strea_file' => "stream_file" ); $self->mode_param('dlg'); } sub welcome_print_as_you_go { my $self = shift; $self->header_type("none"); $| = 1; print $self->query()->header(); # Get CGI query object my $q = $self->query(); print $q->start_html(-title => 'Welcome to SimpleApp!'); my $user_name = $self->authen->username; print $q->h3("Hello, '$user_name'"); my $sleep_for = 1; print $q->p("The next few lines will be printed at $sleep_for sec +s intervals."); for (my $ii=0; $ii < 2; $ii++) { print "Line $ii<br/>\n"; sleep($sleep_for); } print $q->p()."\n"; print "<a href=\"simple_app.cgi?dlg=help\">Help</a><br/>\n"; print "<a href=\"simple_app.cgi?authen_logout=1\">Logout</a><br/> +\n"; print $q->end_html(); return ''; } sub welcome_print_at_very_end { my $self = shift; # Get CGI query object my $q = $self->query(); my $output = ''; $output .= $q->start_html(-title => 'Welcome to SimpleApp!'); my $user_name = $self->authen->username; $output .= $q->h3("Hello, '$user_name' (print as batch)"); my $sleep_for = 1; $output .= $q->p("The next few lines will be printed at $sleep_fo +r secs intervals."); for (my $ii=0; $ii < 2; $ii++) { $output .= "Line $ii<br/>\n"; sleep($sleep_for); } $output .= $q->p()."\n"; $output .= "<a href=\"simple_app.cgi?dlg=help\">Help</a><br/>\n" +; $output .= "<a href=\"simple_app.cgi?authen_logout=1\">Logout</a +><br/>\n"; $output .= $q->end_html(); return $output; } sub logout_print_at_very_end { my ($self) = @_; # Get CGI query object my $q = $self->query(); my $output = ''; $output .= $q->start_html(-title => 'You have been logged out!'); $output .= $q->h3("You have been logged out."); $output .= $q->p()."\n"; $output .= "<a href=\"simple_app.cgi?dlg=welcome\">Home</a><br/> +\n"; $output .= "<a href=\"simple_app.cgi?dlg=help\">Help</a><br/>\n" +; $output .= $q->end_html(); return $output; } sub logout_print_as_you_go { my ($self) = @_; $self->header_type("none"); $| = 1; # Get CGI query object my $q = $self->query(); print $self->query()->header(); my $output = ''; print $q->start_html(-title => 'You have been logged out!'); print $q->h3("You have been logged out."); print $q->p()."\n"; print "<a href=\"simple_app.cgi?dlg=welcome\">Home</a><br/>\n"; print "<a href=\"simple_app.cgi?dlg=help\">Help</a><br/>\n"; print $q->end_html(); return $output; } sub help_print_as_you_go { my ($self) = @_; $self->header_type("none"); $| = 1; my $q = $self->query(); print $q->header(); print $q->start_html(-title => 'SimpleApp Help'); my $user_name = $self->authen->username; print $q->h3("Dear '$user_name', how may I help you? (print as yo +u go)"); print "<a href=\"simple_app.cgi?dlg=welcome\">Home</a><br/>\n"; print "<a href=\"simple_app.cgi?authen_logout=1\">Logout</a><br/> +\n"; my $sleep_for = 1; print $q->p("The next few lines will be printed at $sleep_for sec +s intervals."); for (my $ii=0; $ii < 2; $ii++) { print "Line $ii<br/>\n"; sleep($sleep_for); } print $q->end_html(); return ''; } sub help_print_at_very_end { my $self = shift; # Get CGI query object my $q = $self->query(); my $output = ''; $output .= $q->start_html(-title => 'SimpleApp Help'); my $user_name = $self->authen->username; $output .= $q->h3("Dear '$user_name', how may I help you? (print +as batch)"); my $sleep_for = 1; $output .= $q->p("The next few lines will be printed at $sleep_fo +r secs intervals."); for (my $ii=0; $ii < 2; $ii++) { $output .= "Line $ii<br/>\n"; sleep($sleep_for); } $output .= $q->p()."\n"; $output .= "<a href=\"simple_app.cgi?dlg=welcome\">Home</a><br/> +\n"; $output .= "<a href=\"simple_app.cgi?authen_logout=1\">Logout</a +><br/>\n"; $output .= $q->end_html(); return $output; } sub stream_file { my ($self) = @_; } 1; # Perl requires this at the end of all modules


Comment on Re^4: CGI::Application... flushing output to browser?
Download Code
Re^5: CGI::Application... flushing output to browser?
by Anonymous Monk on May 05, 2012 at 09:20 UTC

    Hmm, regarding buffering/autoflush/$|=1, adding  eval { Apache2::RequestUtil->request->rflush; }; before sleep works for me

    but according to the docs  local $|=1 should have also worked, but I don't have the latest mod_perl2/apache2 here :/

    Regarding the missing cookies, I fear you're right , the module definitely needs updating , bummer :(

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://968908]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2014-09-19 22:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (151 votes), past polls