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

Hi folks,
What I'm trying to do is write a CGI script that will later be referenced by a javascript sniglet to load a random image from an inventory of images in a set directory. The random selection part is working just fine, but what is driving me crazy is the part where we send the images to the browser is misbehaving. What further infuriates me is I know I got this to work before so I know I'm probably missing something fairly obvious. Here is the offending sniglet of code:

use strict; use CGI qw/ :all /; use Image::Info; use GD; | | much handwaving for parts that already work fine. | my $imgStream; if ( $type eq 'PNG' ) { $imgStream = GD::Image->newFromPng($image); } else { $imgStream = GD::Image->newFromJpeg($image); } exec $0 if not $imgStream; print header(-type=>$mime); my $png_data = $imgStream->png; binmode STDOUT; print $png_data; close STDOUT; exit(0);

What I'm seeing at the browser is that oh-so-useful Error 500 error. Checking the server error logs I see:

[Tue Aug 7 14:21:59 2007] [error] [client 68.37.143.39] Premature end + of script headers: /home/bcdcweb/public_html/cgi-bin/sendRandomImage +.pl
If I play around with the script a little run it as a command line script the right data is being generated for the image and can be loaded by Eye Of Gnome just fine. It just doesn't seem to work as a CGI.

What am I missing here???


Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

Replies are listed 'Best First'.
Re: Using GD in a CGI script to randomly select images fails...
by ikegami (Patriarch) on Aug 07, 2007 at 20:04 UTC

    A common mistake is to assume the current directory is the directory in which the script resides. If that's the case here, you could be attempting to load images which cannot be found.

    One solution is to explicitely switch the current directory to the one containing the script.

    use File::Basename qw( dirname ); use File::Spec::Functions qw( rel2abs ); BEGIN { chdir(dirname(rel2abs($0))); }

    By the way, could you explain what exec $0 if not $imgStream; accomplishes (besides introducing a potential infinite loop)?

          If that's the case here, you could be attempting to load images which cannot be found.

      I thought of that.

      # further up in the code: my $dir = $ENV{HOME} . "/www/pix/gallery"; # this points to the only place we should be loading # images from. | | Loop through the directory and populate all the valid | file names into an array my $image=sprintf( "%s/%s",$dir,$imageStack[rand($top)]); # that picks a single name out of the list and prepends # the full path of the gallery directory to the name.
      At one point in my development of this script I did actually have a chdir to the gallery and eliminated it thinking there was some funky-delic permissioning issue going on with the server itself. The random selection code works. I'm just getting those nasty premature header ending errors.


      Peter L. Berghold -- Unix Professional
      Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Using GD in a CGI script to randomly select images fails...
by moritz (Cardinal) on Aug 07, 2007 at 19:42 UTC
    Did you try use CGI::Carp qw(fatalsToBrowser);?

    You don't guard ->new against potential failures (e.g. wrong pathes).

    And try to print the header as early as possible (it's always 'Content-Type: image/png', it seems) to facilitate debugging.

Re: Using GD in a CGI script to randomly select images fails...
by Cody Pendant (Prior) on Aug 07, 2007 at 21:59 UTC
    Since your problem is almost certainly with the header, what's in $mime here?
    print header(-type=>$mime);


    Nobody says perl looks like line-noise any more
    kids today don't know what line-noise IS ...
SOLVED: Using GD in a CGI script to randomly select images fails...
by blue_cowdawg (Monsignor) on Aug 08, 2007 at 17:43 UTC

    This turned out to not be a Perl problem at all. Turns out there were two issues that were causing the problem:

    1. The value for $ENV{"HOME"} is undefined when running the script as a CGI due to the way the hosting company sets up its server environment. I solved this by hardcoding the pasth. (I hate doing that)
    2. Turned out the server was configured such that there is a restriction on the mime types a CGI script can send. The hosting company's philosophy is if you aren't smart enough to ask for an exception you don't get the exception. Once they added "image/png" to their list for my virtual server all was good.
    What was partially tripping me up was the script ran fine from the command line even remotely as in
    ssh ${server} ${path}/sendRandomImage.pl
    and did what I expected.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg