Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Not Strictly A perl question.

by kb2yht (Acolyte)
on Jun 30, 2001 at 22:20 UTC ( [id://92938]=perlquestion: print w/replies, xml ) Need Help??

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

SO, I have directory full of JPEG images used as a large part of the Human interface "GUI " to to a MySQL query output, Embeded in a page. I can not make the dir accessable to the world via the web server, But a script running on the server can easly see the images, Is there a way to use a small CGI to open and send the image to the cliant? like....
 <img src=$myscript/$image_filename>
in as the img source , then have

myscript.pl

#!/usr/local/bin/perl -W use CGI qw/:all/; my $query = CGI::new(); my $file = $query->path_info(); open ( IMAGE, $file ); while ( <IMAGE> ) { print $_; } exit ;


to open and then print the file ?? , This does not work, but I think its only because of an over sight in the perl or in the way I'me pointing the WEb-cliant to the link.
Perhaps One of the older and wiser Monks may have a answer, ( or maby just a Wiser monk will thel me to FIYS )
Thanks
Bill Nolan,

Replies are listed 'Best First'.
(ar0n) Re: Not Strictly A perl question.
by ar0n (Priest) on Jun 30, 2001 at 22:34 UTC
    That would almost work, provided you'd send the correct headers:
    #!/usr/bin/perl -wT use strict; use CGI ':all'; my $q = new CGI; my $imagedir = "/path/to/images"; my $file = $q->path_info(); $file =~ s!^.*/!!gi; print header("image/jpeg"), do { local *ARGV; @ARGV = "$imagedir/$file"; <> };
    Be sure to use taint checking on your path info, as you wouldn't want anyone to view files they shouldn't be viewing... :)

    ar0n ]

Re: Not Strictly A perl question.
by jepri (Parson) on Jun 30, 2001 at 22:35 UTC
    It's Perl enough for me. I'm a bit tired so you don't get the full answer, but here's the quick rundown.

    When you put a link in a webpage, the browser loads the HTML, then loads the images as if you were following links to the images. In short, an <img src="lalala"> tag acts exactly like a <a href="lalala"> tag. There is no problem at all with having the target of a img tag being a cgi.

    So your img tag becomes <img src="image_server.pl?image=goodpic.jpg>.

    The CGI becomes:

    #!/usr/local/bin/perl -w use CGI qw/:all/; my $query = CGI::new(); my $file = $query->param("image"); open ( IMAGE, $file ); while ( <IMAGE> ) { print $_; } exit ;

    You are on the right track. A lot of sites have "image servers" - web servers that just host images. Cuts down the load on any one server. I'll let someone else shout about security, but consider what could happen if someone typed "image_server.pl?image=/etc/password" into their browser...

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      I'll fill out some of the bits jepri left out

      As it stands the code has a classic cgi security hole. It trusts user input for file system locations (e.g. ?image=/etc/passwd). Here is a safer rewrite:

      #!/usr/local/bin/perl -wT use strict; use CGI qw/:all/; my %images = ( 'tophat'=> { 'path'=>"/usr/somewhere/way/out/of/reach/Top Hat.jpeg", 'mime'=>"image/jpeg"}, 'racecar'=> { 'path'=>"/usr/somewhere/way/out/of/reach/Bugatti.png", 'mime'=>"image/png"}, #etc... ); my $query = CGI::new(); my $file = $query->param("image"); $|=1; if (defined $images{$file}) { print $query->header({-type=>$images{$file}{'mime'}});} open ( IMAGE, $images{$file}{'path'} ); print while ( <IMAGE> ); close(IMAGE); } else { print $query->header({-type=>'text/html', -status=>"404 File Not Found"}); } exit ;

      This is a forgiving approach to bad input, more BOFHish to log and play games.

      After Compline,
      Zaxo

Re: Not Strictly A perl question.
by epoptai (Curate) on Jun 30, 2001 at 22:50 UTC
    On unix systems the answers you've gotten will work. But if your image server runs under MSWin32 you need to add binmode IMAGE; immediately after opening the image file.

    --
    Check out my Perlmonks Related Scripts like framechat, reputer, and xNN.

Re: Not Strictly A perl question.
by bikeNomad (Priest) on Jun 30, 2001 at 22:27 UTC
    You can have a CGI that outputs an image. Just make sure that you send out the right HTTP headers, including (and especially) Content-Type: image/jpeg . It wouldn't hurt to put the Content-Length: header in, too, since you know the size of your JPG. Then follow the headers with a couple of CRLF pairs and the contents of the JPG. Make sure that you set your file to binary mode using binmode if you're using an OS that cares (like Windoze).
Re: Not Strictly A perl question.
by Beatnik (Parson) on Jun 30, 2001 at 22:28 UTC
    You have to generate a good HTTP header...
    print $query->header(-type=>'image/gif'); #or whatever format you're using Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.
Re: Not Strictly A perl question.
by kb2yht (Acolyte) on Jul 07, 2001 at 19:10 UTC
    Thank You All For The help,
    I greatly Appreciate It,
    Bill N.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://92938]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-04-19 10:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found