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

I've learned just enough Perl to write the following program so I'm probably making a basic mistake. The program is designed to be called from a page by an image tag. It first checks for an existing cookie. If there's a cookie it just returns the GIF. If there's no cookie then it checks for the referer, sets the cookie and then returns the GIF. The problem comes when checking for an existing cookie. If I remove the conditional at 1 & 2 which checks for a cookie, the program runs fine. It sets the cookie and returns the image. If left in I get a "500" error.
#!/usr/bin/perl # cset.cgi - set a cookie use CGI::Carp qw(fatalsToBrowser); use CGI qw(:standard); # check for cookie, if no cookie then check for referer # and set cookie unless ($ENV{'HTTP_COOKIE'}) { # 1 if ($ENV{'HTTP_REFERER'} eq "") { $referer = "None" } else { $referer = $ENV{'HTTP_REFERER'} } $name = "Thanks"; $to_set = cookie(-name => $name, -value => $referer, -expires => "+30d", ); print header(-cookie => $to_set); } # 2 #print clear GIF $image = "logo.gif"; print img {src=>$image}; <IMG SRC=$image>

Replies are listed 'Best First'.
Re: Conditional statement problem
by chip (Curate) on Nov 14, 2001 at 07:05 UTC
    Simple problem: Even though sometimes $to_set isn't set, you're always passing it to header().

    Easy fix: Use an array @to_set instead:

    @to_set = (-cookie => cookie(-name => $name, ...)); # ... print header(@to_set);

    For extra future expansion points, use push() instead of array assignment.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

      Thanks for your reply, Chip. It turns out the problem was in my statements to print the image. For some reason they'd only work if the cookie was also set but not if it wasn't. I replaced the last three lines with the following and it works now. I don't have enlightenment but I do have results, so I'll go with that.
      my $image = 'logo.gif'; open(IMAGE, "<$image") or die "cannot open image file: $!"; my $no_bytes = (stat ($image))[7]; print "Content-type: image/gif\n"; print "Content-length: $no_bytes\n"; print "Pragma: no-cache\n\n"; print <IMAGE>; close(IMAGE) or die "cannot close image file: $!";
Re: Conditional statement problem
by rob_au (Abbot) on Nov 14, 2001 at 07:13 UTC
    Okay, without a bit more information, I'm unsure exactly could be causing the problem here, but I have a few ideas ...

    The program is designed to be called from a page by an image tag.

    Is this to mean that the CGI script is called in the following fashion?

    <img src="/cgi-bin/myscript.cgi" />

    If so, then this is where your problem is - Your browser will be expecting the result of the script to be of content image/gif or alike, whereas your script is returning text/html (check the CGI documentation on the header method for details).

    If indeed, this is how you are calling your script, you have two options as far as I can see:

    1. Assuming your web server is configured to support SSI, change the referencing of the CGI script to thus:

      <!--#include virtual="/cgi-bin/myscript.cgi" -->

      The result being the incorporation of the text/html content returned by your current script into the HTML document.

    2. Change your script so that the returned content is of type image/gif or alike based on the type of image returned, similar to the following *untested* code:

      print header( -cookie => $to_set, -type => "image/gif" ); eval { open (FH, $image); print <FH>; close (FH); } || die $!;

     

    Ooohhh, Rob no beer function well without!

      Yes, Rob it was the image causing the problem although I'm still not clear why as the image did get returned if the cookie was set. But I swiped the following subroutine code to print the image and now the program works fine. Thanks.
      my $image = 'logo.gif'; open(IMAGE, "<$image") or die "cannot open image file: $!"; my $no_bytes = (stat ($image))[7]; print "Content-type: image/gif\n"; print "Content-length: $no_bytes\n"; print "Pragma: no-cache\n\n"; print <IMAGE>; close(IMAGE) or die "cannot close image file: $!";