Question on using perl in a cgi script

Q

q-rious

This is a question about using perl in cgi. If this is not the proper perl forum, my apologies.

I want to build a cgi script using perl that will continously loop through the following:

a) read from a line from a one line file
b) draw something on the screen based on that value (using gd)

I can do this for one iteration of the loop. But how do I update the browser screen for multiple iterations? For other restrictions, I can not reload the entire page each time the script goes through the loop. I can only update the drawing (Step b).

Thanks in advance for your help.
 
M

Mart van de Wege

q-rious said:
This is a question about using perl in cgi. If this is not the proper
perl forum, my apologies.

I want to build a cgi script using perl that will continously loop
through the following:

a) read from a line from a one line file b) draw something on the
screen based on that value (using gd)

I can do this for one iteration of the loop. But how do I update the
browser screen for multiple iterations? For other restrictions, I can
not reload the entire page each time the script goes through the
loop. I can only update the drawing (Step b).
You can't do that with static HTML and CGI, period.

The only way to do this is using some sort of client side code to
repeatedly GET the CGI script and use the output to update the page.

The obvious candidate is JavaScript.

Mart
 
P

Peter J. Holzer

You can't do that with static HTML and CGI, period.

Yes, you can. Just include a Refresh header in the HTTP response.

That works at least for whole HTML pages. I'm not sure whether it works
for inline images. If it doesn't, you can still load the image into an
iframe.

The only way to do this is using some sort of client side code to
repeatedly GET the CGI script and use the output to update the page.

That client side code is called a "browser" ;-).
The obvious candidate is JavaScript.

That works, too (and it is more flexible than the refresh header).

hp
 
M

Mart van de Wege

Peter J. Holzer said:
Yes, you can. Just include a Refresh header in the HTTP response.
Nope.

Note that OP specifies that he can't reload the entire page.

Mart
 
C

ccc31807

I want to build a cgi script using perl that will continously loop through the following:

a) read from a line from a one line file
b) draw something on the screen based on that value (using gd)

I can do this for one iteration of the loop. But how do I update the browser screen for multiple iterations?

Your hypothetical CGI script might look something like this:
use warnings;
use strict;
use CGI;
my $what = param('what');
#present HTML form unless 'draw' is clicked
unless ($what eq 'draw')
{
print qq(<html><body><form><input type="submit" name="what"
value="draw" /></form></body></html>);
}
#draw lines from file if 'draw' is clicked
elsif ($what eq 'draw')
{
print qq(<html><body>);
open DRAW, '<', 'draw.txt' or die "$!";
while (<DRAW>) { print $_; }
close DRAW;
print qq(</body></html>);
}
else
{
print qq(<html><body><h1>ERROR!</h1></body></html>);
}
exit(0);

This script WILL NOT RETURN a resource to the HTTP server until it has
finished executing, IOW, until the entire file has been read, the HTML
has been generated in its entirety, and the script exits. At that
point, the web server will return the resource which consists of the
complete drawing.

I can think of several ways to do what you say you want to do, but
they are all ugly. Perhaps the simplest is to return a JavaScript file
that will programatically draw what you want, but that would run a
client side script rather than a server side script (which is what CGI
does).

You could write an Applet to do the same thing, but that's not CGI.

I don't think you want repeated HTTP requests and responses bouncing
back and forth between your browser and the server -- the latency
would kill you.

You might want to post a program or the pseudo code for what you want
if you think this does not respond to what you think you asked.

CC.
 
C

ccc31807

The else clause is unreachable, so it should not be there.

Yeah, and I also left out the
print "Content-type: text/html\n\n";
line as well. So, just regard it as what I said it was, a hypothetical
script written in Perlish pseudocode.

CC.
 
T

Ted Zlatanov

c> Yeah, and I also left out the
c> print "Content-type: text/html\n\n";
c> line as well. So, just regard it as what I said it was, a hypothetical
c> script written in Perlish pseudocode.

But that's not useful.

Please try to post complete working examples. This one was nearly so
which is much more confusing than actual pseudocode.

Ted
 
P

Peter J. Holzer

Peter J. Holzer said:
I want to build a cgi script using perl that will continously loop
through the following: [...]
I can do this for one iteration of the loop. But how do I update the
browser screen for multiple iterations? For other restrictions, I can
not reload the entire page each time the script goes through the
loop. I can only update the drawing (Step b).

You can't do that with static HTML and CGI, period.

Yes, you can. Just include a Refresh header in the HTTP response.
Nope.

Note that OP specifies that he can't reload the entire page.

I guess you didn't read the second paragraph before replying.

Here is a simple demonstration:

http://www.hjp.at/tests/refresh_html2.cgi

hp
 
M

Mart van de Wege

Peter J. Holzer said:
Peter J. Holzer said:
I want to build a cgi script using perl that will continously loop
through the following: [...]
I can do this for one iteration of the loop. But how do I update the
browser screen for multiple iterations? For other restrictions, I can
not reload the entire page each time the script goes through the
loop. I can only update the drawing (Step b).

You can't do that with static HTML and CGI, period.

Yes, you can. Just include a Refresh header in the HTTP response.
Nope.

Note that OP specifies that he can't reload the entire page.

I guess you didn't read the second paragraph before replying.

Here is a simple demonstration:

http://www.hjp.at/tests/refresh_html2.cgi
OK, so at least Firefox refetches and redraws just the image when you
serve it up with Refresh header.

Huh. Didn't know that one. Live and learn, I guess.

Mart
 
C

ccc31807

Please try to post complete working examples.  This one was nearly so
which is much more confusing than actual pseudocode.

I couldn't post a working example because I have no idea of the kind
of file the OP wanted to print. In my example, I assumed that it was
some kind of ASCII file (maybe ASCII are) but it could have been
something else.

Working code also requires a working HTTP server set up to serve CGI
scripts. I just dashed this off at work, while waiting on some other
processes to complete, and didn't have access to such. If I had, I
would have picked up on the omission of the Copntent-type header right
away.

Still, none of that prevented me from making the point that the OP
really couldn't use CGI for doing what he said he wanted to do. I just
wanted to illustrate that point as well as I could while taking a
short break at work.

CC.
 
M

mittra

Hi Peter,

Thanks for your reply and example. Will you be able to post the code for refresh_img.cgi so that I or if anyone else who may have similar question inthe future understand the process better?

Thanks again.
 
P

Peter J. Holzer

Hi Peter,

Thanks for your reply and example. Will you be able to post the code
for refresh_img.cgi so that I or if anyone else who may have similar
question inthe future understand the process better?

The code is really trivial, but here it is:


#!/usr/bin/perl
# refresh_html2.cgi

use warnings;
use strict;

print "Content-Type: text/html; charset=utf-8\n";
print "\n";
print "<html>\n";
print " <head>\n";
print " <title>Refresh header test</title>\n";
print " </head>\n";
print " <body>\n";
print " <h1>Refresh header test</h1>\n";
print " <p>This script tests the effect of a Refresh header on an\n";
print " embedded image. The page should not be reloaded, but the\n";
print " image should.</p>\n";
print " <p>Time: ", scalar(gmtime), "</p>\n";
print " <iframe width='200', height='200' src='refresh_img.cgi'></iframe>\n";
print " <p>Time: ", scalar(gmtime), "</p>\n";
print " </body>\n";
print "</html>\n";
__END__


#!/usr/bin/perl
# refresh_img.cgi

use warnings;
use strict;

use Imager;
use Math::Trig qw(deg2rad);

print "Content-Type: image/png\n";
print "Refresh: 1\n";
print "\n";

my $img = Imager->new(xsize=>200, ysize=>200, channels=>4);

my ($sec, $min, $hour) = gmtime;

my $red = Imager::Color->new(255, 0, 0);
my $black = Imager::Color->new(0, 0, 0);

$img->circle(x => 100, y => 100, r => 99, color => $black, filled => 0);
$img->line(x1 => 100, y1 => 100,
x2 => 100 + sin(deg2rad($sec * 6)) * 90,
y2 => 100 - cos(deg2rad($sec * 6)) * 90,
color => $red);
$img->line(x1 => 100, y1 => 100,
x2 => 100 + sin(deg2rad($min * 6)) * 80,
y2 => 100 - cos(deg2rad($min * 6)) * 80,
color => $red);
$img->line(x1 => 100, y1 => 100,
x2 => 100 + sin(deg2rad($hour * 15)) * 70,
y2 => 100 - cos(deg2rad($hour * 15)) * 70,
color => $red);

$img->write(fh => \*STDOUT, type => 'png');
__END__

The relevant parts are the use of an iframe in the first script (it
doesn't work with <img/>, at least not with Firefox) and the Refresh
header in the second script.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top