Serving inline images

D

David Jaquay

I'm trying to get the following code to work. I'm using ActiveState
Perl 5.8.2, Tomcat 4.0.4 under Win2K, and using either Mozilla 1.5 or
IE 6. Running this script causes Perl to hang on the next to last
line, the 'print' line. (I moved the exit statement around to come to
this conclusion.) Running it from the command line appears to work
just fine, displaying the raw chars from the GIF.

It would seem from Googling that this is a FAQ, and that binmode is
the answer, but I've shuffed the binmode lines around to various
locations, and still get the same results, a hung perl.exe.

Any ideas as to what's going on? (And yes, I'm quite new to Perl.)

Thanks,
Dave

print("Content-type: Image/gif\n\n");

open(INFILE,'<d:\\sample.gif');
binmode INFILE;
undef $/;
my $img = <INFILE>;
close(INFILE);
binmode STDOUT;
print STDOUT $img;
exit;
 
G

Gunnar Hjalmarsson

David said:
I'm trying to get the following code to work. I'm using
ActiveState Perl 5.8.2, Tomcat 4.0.4 under Win2K, and using either
Mozilla 1.5 or IE 6. Running this script causes Perl to hang on
the next to last line, the 'print' line.

print("Content-type: Image/gif\n\n");

open(INFILE,'<d:\\sample.gif');
binmode INFILE;
undef $/;
my $img = <INFILE>;
close(INFILE);
binmode STDOUT;
print STDOUT $img;
exit;

It works fine for me with 5.8.0 on W98 and Mozilla 1.5, so your code
seems to be okay.
 
I

Iain Chalmers

I'm trying to get the following code to work. I'm using ActiveState
Perl 5.8.2, Tomcat 4.0.4 under Win2K, and using either Mozilla 1.5 or
IE 6. Running this script causes Perl to hang on the next to last
line, the 'print' line. (I moved the exit statement around to come to
this conclusion.) Running it from the command line appears to work
just fine, displaying the raw chars from the GIF.

It would seem from Googling that this is a FAQ, and that binmode is
the answer, but I've shuffed the binmode lines around to various
locations, and still get the same results, a hung perl.exe.

Any ideas as to what's going on? (And yes, I'm quite new to Perl.)

Nope, looks like it should be working to me, though I'm not too sure
about that "capital I 'Image'" in the Content-type, shouyldn't that be
"image/gif"? I can't see that causing the symptoms you describe though...
Thanks,
Dave

print("Content-type: Image/gif\n\n");

open(INFILE,'<d:\\sample.gif');
binmode INFILE;
undef $/;
my $img = <INFILE>;
close(INFILE);
binmode STDOUT;
print STDOUT $img;
exit;

Of course, you could "improve" it a bit like so - no need to read the
image into a scalar just to print it out, and the exit implicitly closes
INFILE. And, as Tad tells us "always (yes *always*) check the return
status of an open". (you might want to do something better in the die
statement though, probably not tell the world whats in $!, and log it
instead)

#!/usr/bin/perl -w
use strict;

open(INFILE,'<d:\\sample.gif')
or die "Content-type: text/plain\n\nopening image failed, $!\n";
binmode INFILE;
binmode STDOUT;
undef $/;
print "Content-type: Image/gif\n\n";
print <INFILE>;
exit;

cheers,

big
 
A

A. Sinan Unur

AFAIK, the correct type is image/gif.

Dunno if this has anything to do with anything, but I have personally
come to prefer the 3-argument form of open:

open(INFILE, '<', 'd:/sample.gif')

Yes, that / will work on Windows.

STDOUT is still buffered. With CGI scripts, make sure you have

$| = 1;

before you send anything to STDOUT.
open(INFILE,'<d:\\sample.gif')
or die "Content-type: text/plain\n\nopening image failed, $!\n";

While I applaud error checking, I do not think this is a good idea. Under
most servers, the argument to die will probably be written to the error
log, and the client will see only an "Internal Server Error".

You'll need something along the lines of:

open IMG, '<', $img or bailout($img, $!);

....

sub bailout {
my ($fn, $err) = @_;
print "Content-type: text/plain\n\nImage not found\n";
die "Cannot open $fn: $!";
}

Also, you should localize changes to $/.

Sinan.
 
R

Robert Wallace

google-google. goo-goo gaa-gaa.

David said:
I'm trying to get the following code to work. I'm using ActiveState
Perl 5.8.2, Tomcat 4.0.4 under Win2K, and using either Mozilla 1.5 or
IE 6. Running this script causes Perl to hang on the next to last
line, the 'print' line. (I moved the exit statement around to come to
this conclusion.) Running it from the command line appears to work
just fine, displaying the raw chars from the GIF.

It would seem from Googling that this is a FAQ, and that binmode is
the answer, but I've shuffed the binmode lines around to various
locations, and still get the same results, a hung perl.exe.

Any ideas as to what's going on? (And yes, I'm quite new to Perl.)

Thanks,
Dave

print("Content-type: Image/gif\n\n");

open(INFILE,'<d:\\sample.gif');
binmode INFILE;
undef $/;
my $img = <INFILE>;
close(INFILE);
binmode STDOUT;
print STDOUT $img;
exit;


I'm probably not solving anything but, here's my bastardized version:

#!/usr/bin/perl -wT
# url: http://www.example.com/image.cgi

#modules
use CGI qw('param');
use strict;

#variables
my $image =
"/dir1/dir2/dir3/you-get-the-drill/httpd/www/images/arrow01.gif";

# automatic variables
my $thisFileName;
if ($0 =~ /\//){$thisFileName=substr($0,rindex($0,'/')+1,length($0)-1);}
elsif($0 =~
/\\/){$thisFileName=substr($0,rindex($0,'\\')+1,length($0)-1);}


#parsed variables
my $option=param('option');


#directory
if ($option eq "image"){
image();
} else {
html();
}

sub html {
print "content-type: text/html \n\n";
print "<html><head><title>image</title></head><body>\n";
print "Inline image test:<br>\n";
print "<img src=\"$thisFileName?option=image\">\n";
print "</body></html>\n";
}

sub image {
print "content-type: image/gif \n\n";
open(INFILE, $image);
binmode INFILE;
undef $/;
my $img = <INFILE>;
close(INFILE);
binmode STDOUT;
print STDOUT $img;
}

print "anyone have a beef about this?\n";
 
T

Tad McClellan

Robert Wallace said:
open(INFILE, $image);
undef $/;
print "anyone have a beef about this?\n";


You should always, yes *always*, check the return value from open():

open(INFILE, $image) or die "could not open '$image' $!";


This is a much much better way of enabling slurp mode:

local $/;

or, if you must:

local $/ = undef;

The value of $/ will go back to "normal" outside of this subroutine's
block. Your code above is changing the global value everywhere.
 

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
474,145
Messages
2,570,825
Members
47,371
Latest member
Brkaa

Latest Threads

Top