http://qs321.pair.com?node_id=173438

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

Hello,
I have made a script for my website which catches 404 errors and logs them to a text file for later viewing, and shows a message to the person who made the error.
What I want to do now, is change the script slightly so that if it is an image that does not exist, the script will show another image that will appear instead of the image that was linked. I will show you what I have:

#!/usr/local/bin/perl $referer = $ENV{'HTTP_REFERER'}; $user = $ENV{'REMOTE_ADDR'}; $usercomp = $ENV{'REMOTE_HOST'}; $url = $ENV{'REDIRECT_URL'}; $gmt = gmtime(time); print "Content-type: text/html\n\n"; if($url =~ m/jpg|gif/ig){ print "<img src=\"http://www.queenfans.com/none.gif\">"; }else{ print "<h1>Whoops!</h1><h3>$url</h3>That page does not exist. Please p +ress your back button and try again."; } if($referer ne ''){ open(FILE2,">>public/404.txt"); print FILE2 "$url|$referer|$user|$usercomp|$gmt\n"; close(FILE2); }

This works fine for text, html, shtml, anything, really. But when I deliberately look for a jpg or gif that is not there, it shows me the default 404 page. Why does it do that, what have I done wrong?

Thank you in advance, you're all great,

Kat

Replies are listed 'Best First'.
Re: 404 image errors
by cLive ;-) (Prior) on Jun 11, 2002 at 12:31 UTC
    Something like this?
    use CGI; my $q = new CGI; my @image_extensions = qw(gif png jpg jpeg); for (@image_extensions) { if ($url =~ /\.${_}$/) { print $q->redirect(-uri=>'http://image.url/here.gif'); exit(0); } }
    Amend as you see fit if you want to return same file type - but I think most browsers can interpret the mime without needing the correct extension.

    You don't want to return html (the img tag) because that's text.

    Please learn CGI - it will make your life easier in the long run - honest!

    cLive ;-)

    ps - remember, you will need to send the redirect before outputting a text/html header to the browser.

    Update: pps - sorry, I should have stated - this was a snippet to go in your existing code (hmmm). I've expanded below...

    --
    seek(JOB,$$LA,0);

      That won't work as you forgot to initialise $url to $ENV{'REDIRECT_URL'}.

      I'd also suggest that

      for (@image_extensions) { if ($url =~ /\.${_}$/) {
      was changed to
      for my $ext (@image_extensions) { if ($url =~ /\.$ext$) {
      which makes things a bit more clear

      gav^

        This isn't necessary, but what if .jpg becomes a domain suffix?

        use URI; my $addr = URI->new($url); my $path = $addr->path; for my $ext (@image_extensions) { if ($path =~ /\.$ext$/) { ....

        Probably not worth it to add this in, but I thought I'd point it out anyways :).

      thank you... but.... I still get the default error page :(
        OK, here's a complete (non-tested :) version...
        #!/usr/local/bin/perl -w use strict; use CGI; my $q = new CGI; my @image_extensions = qw(gif png jpg jpeg); my $referer = $ENV{'HTTP_REFERER'}; my $user = $ENV{'REMOTE_ADDR'}; my $usercomp = $ENV{'REMOTE_HOST'}; my $url = $ENV{'REDIRECT_URL'}; my $gmt = gmtime(time); if ($referer) { open(FILE2,">>public/404.txt"); print FILE2 "$url|$referer|$user|$usercomp|$gmt\n"; close(FILE2); } for (@image_extensions) { if ($url =~ /\.${_}$/) { print $q->redirect(-uri=>'http://image.url/here.gif'); exit(0); } } print $q->header, $q->start_html, $q->h1('Whoops!'), $q->h3($url), $q->p('That page does not exist. Please press your back button a +nd try again.'), $q->end_html; exit(0);

        cLive ;-)

        --
        seek(JOB,$$LA,0);

Re: 404 image errors
by cjf (Parson) on Jun 11, 2002 at 12:45 UTC