bluedragon2 has asked for the wisdom of the Perl Monks concerning the following question:

I have a simple non cgi form and when the submit button is pressed, it runs as it should except for buffering the output data until it finishes processing. I have put $|=1 at the beginning of the script and in other places to no avail. Does anyone have any ideas? Thank You Blue

Replies are listed 'Best First'.
Re: unbuffer output
by almut (Canon) on Jul 29, 2008 at 20:14 UTC

    How did you diagnose that the script is buffering the output data until it finishes? (Hint: it might be something else, like the webserver, a proxy, or the browser.)  I.e., what exact behavior do you observe? What kind of output is the script producing? What are you trying to achieve, IOW, why is it relevant that the output is buffered? Is it a long-running script?

    Some runnable code together with info about which webserver, browser, OS, etc. would help us to help you...

      The script modifies several devices and would like the progress of each device printed when they are completed. The code resides on a SUN OS server using tomcat. The browsers tried are Netscape 9.0 and IE 7.0. The output of the script is not displayed until it completes. Here is the code:
      #!/usr/bin/perl use CGI qw(:standard); $bbslist = "/opt/BBSacct/bbslist.txt"; $bbs = "/opt/BBSacct/bbsacct.exe"; @bbspop = ("ALL"); $BBSPass = "!BBS4acct"; $| = 1; open(BBSL,$bbslist); @lines = <BBSL>; close(BBSL); foreach $line (@lines) { chomp($line); @s = split(/ /,$line); push(@bbspop,$s[0]); } print header; print "<FONT color=#006600><h1>BBS User Account Management</h1></FONT> +\n"; print start_html('BBS Account Management'), start_form, "User Name: ",textfield(-name=>'Uname',-size=>15), p, radio_group(-name=>'ad',-values=>['Add Account','Delete Account',' +Change Password'],-default=>'Add Account'), p, "BBS Hostname: ",popup_menu(-name=>'Host',-values=>[@bbspop],-defa +ult=>'ALL'), p, "New Password: ",textfield(-name=>'Npass',-size=>15)," (Minimum 8 +characters containing 1 upper, 1 lower, 1 number, and 1 special)", p, "Execute Password: ",password_field(-name=>'Epass',-size=>8)," ",s +ubmit(-name=>'Execute'), end_form, hr; if (param()) { $Epass = param(Epass); $Uname = param(Uname); $ad = param(ad); $Host = param(Host); $Npass = param(Npass); if ($Epass ne BBS) { print "<FONT color=red><TT><B>Invalid Execute Password</B></TT +></FONT>\n"; exit; } else { print "<TT><B>Processing</B></TT>\n"; print "<CENTER></CENTER>\n"; } stringcheck($Uname,"User Name"); if ($Host ne "ALL") { $pc = `ping $Host`; if ($pc =~ /alive/) { } else { print "<FONT color=red><TT><B>Could not connect to $Host</ +B></TT></FONT>\n"; print "<CENTER></CENTER>\n"; exit; } open(BBSF,$bbslist); @lines = <BBSF>; close(BBSF); foreach $line (@lines) { chomp($line); @s = split(/ /,$line); $hc = $s[0]; if ($Host =~ /$hc/) { $Pass = $s[1]; } } if ($ad eq "Add Account") { stringcheck($Npass,"New Password"); runexp($Host,$Pass,$Uname,$Npass,"a"); } if ($ad eq "Delete Account") { runexp($Host,$Pass,$Uname,$Npass,"d"); } if ($ad eq "Change Password") { stringcheck($Npass,"New Password"); runexp($Host,$Pass,$Uname,$Npass,"d"); runexp($Host,$Pass,$Uname,$Npass,"a"); } } else { open(BBSL,$bbslist); @lines = <BBSL>; close(BBSL); foreach $line (@lines) { chomp($line); @s = split(/ /,$line); $Host = $s[0]; $Pass = $s[1]; $pc = `ping $Host`; if ($pc =~ /alive/) { } else { print "<FONT color=red><TT><B>Could not connect to $Ho +st</B></TT></FONT>\n"; print "<CENTER></CENTER>\n"; next; } if ($ad eq "Add Account") { stringcheck($Npass,"New Password"); runexp($Host,$Pass,$Uname,$Npass,"a"); } if ($ad eq "Delete Account") { runexp($Host,$Pass,$Uname,$Npass,"d"); } if ($ad eq "Change Password") { stringcheck($Npass,"New Password"); runexp($Host,$Pass,$Uname,$Npass,"d"); runexp($Host,$Pass,$Uname,$Npass,"a"); } } } } sub stringcheck { my($nc,$em) = @_; if (length($nc) == 0) { print "<FONT color=red><TT><B>ERROR - Must input $em</B></TT>< +/FONT>\n"; exit; } } sub runexp { my($Ho,$Pa,$Us,$Na,$Wh) = @_; @f = `$bbs $Ho $Pa $Us $Wh $Na`; foreach $line (@f) { chomp($line); if ($line =~ /COMPLETE/) { @s = split(/Z/,$line); $em = $s[1]; print "<FONT color=green><TT><B>$em Complete</B></TT></FON +T>\n"; print "<CENTER></CENTER>\n"; } if ($line =~ /^ERROR/) { @s = split(/Z/,$line); $em = $s[1]; print "<FONT color=red><TT><B>$em</B></TT></FONT>\n"; print "<CENTER></CENTER>\n"; } } }
        I ran this on server running apache and it did run unbuffered. It appears to be the tomcat. To make this work, I printed the output to a file and created a frame that refreshed showing the output of that file. Works like a charm now.
Re: unbuffer output
by Your Mother (Archbishop) on Jul 29, 2008 at 21:34 UTC

    In addition to almut's Qs/feedback, "non cgi form" sounds fishy. What you've got probably is a CGI (which is not a module in this case but a standard). If you can present a minimal code sample that reproduces your problem, someone here can certainly help. Of course, trimming things down to the minimal case often makes bugs obvious so you might find the answer on your own.

Re: unbuffer output
by shmem (Chancellor) on Jul 29, 2008 at 22:43 UTC

    Is it the server that is buffering, or the client? It could be the 'charset' in the 'Content-type' line ( in $cgi->header(-charset => $charset) ).

    See the thread Autoflush and web browsers (was: Clever autoflush detail) and my response at Re: Clever autoflush detail.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}