Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

CGI-Perl:: Location for saving the GD output

by cool (Scribe)
on Sep 10, 2006 at 07:16 UTC ( #572199=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks,

These problema are not pertaining to Perl but CGI. I am using a Fedora Core3 OS and Apache as webserver. Now after taking input from user, my script generates two things

(A) Some texts (B) A graph (using GD) in jpg format.

For (A) I am saving in /tmp and able to send directly to user from there.

Prob is with (B).. 1 If I save it in /tmp then my server is not able to find it even I give the path print "<img src=\"/tmp/upload/$tag.jpg\">"; or even if I use print "<img src=\"http://127.0.0.1/../../../tmp/upload/$tag.jpg\">"; It is not able to locate and send the jpg img. 2 Now it is sending from src=\"http://127.0.0.1/image/$tag.jpg\">"; means if jpg is in /var/www/html/image it is happily working but then the problem is my CGI is not able to write the graph in /var/www/html/image location.

One more doubt is about HTML headers in the scripts. So far I am only providing

print "Content-type:text/html\n\n";

Please help me sorting out these issues. Thank you for reading this much..

  • Comment on CGI-Perl:: Location for saving the GD output

Replies are listed 'Best First'.
Re: CGI-Perl:: Location for saving the GD output
by gellyfish (Monsignor) on Sep 10, 2006 at 08:41 UTC

    It would appear that you have two non-perl-related choices: either change the Apache configuration so you can serve images from somewhere where the user that the CGI application runs as can write to, or change the permissions on the existing images directory so that you can create files there.

    A third option would be to continue to write the files to the non server accessible directory as you currently are and instead of referencing the image directly in your <img /> element you use a small program to output directly with the appropriate header - something like:

    #!/usr/bin/perl -T # use strict; use warnings; use File::Spec; use CGI qw(:standard); my $upload_path = '/tmp/upload'; my $filename = param('image'); if ( $filename =~ /([\w.]+\.jpg)$/ ) { $filename = File::Spec->catfile($upload_path, $1); my $image = do { open IMAGE, $filename or die "Bad image $filename $ +!\n"; binmode IMAGE; select IMAGE; local $/; <IMAGE>; }; binmode STDOUT; print STDOUT header('image/jpeg'),$image; } else { print header('text/plain'),"Bad image name - try again"; }
    (This is bare bones for testing purposes you might want to make it a bit more robust for production.) And the use <img src="/cgi-bin/image.pl?image=$tag.jpg" /> in your output HTML.

    /J\

Re: CGI-Perl:: Location for saving the GD output
by shmem (Chancellor) on Sep 10, 2006 at 09:16 UTC
    The web server's root and your OS's root are different. The web server won't look outside it's tree. If you write your image file to a location outside the server's DocumentRoot, your web server can't find it.

    You can

    1. use the Alias directive to have a location point to some path outside the DocumentRoot
    2. allow the webserver process to write to some images directory inside the tree rooted at DocumentRoot
    3. use a CGI script to serve the image. Provide e.g. the tag
      <img src="/cgi-bin/image.pl?img=$tag.jpg">
      in the page referencing the image, and have it served thusly:
      #!/usr/bin/perl -T use CGI; use strict; my $q = new CGI; if($q->param('img') =~ /^([\w\.\-]+)$/) { # untaint my $file = $1; if(-f "/tmp/$file") { if(open(I,'<',"/tmp/$file")) { print $q->header(-content_type => "image/jpeg"); print while <I>; close I; exit; } } } print $q->header(-status => '404 Not found'); print "<h1>Not found.</h1>\n";
    As for 1. and 2. - if you allow your web server to write to some path, you should limit the methods POST, PUT and DELETE for that directory (or location).

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Dear Shmem,

      I tried the third one.. and is giving output but not as image.. its all Greek and Latin..

      Below are the lines of code, where I am generating the image..
      my $png_data = $im->png; #open (DISPLAY,"| display -") || die; print $query->p("$tag : Free energy curve of forward strand and shu +ffle sequence"); #open (DISPLAY,">/var/www/html/upload/$tag.jpg") ||error ($query, "C +ant open GRAPH:") ; open (DISPLAY,">/tmp/upload/$tag.jpg") ||error ($query, "Cant open +GRAPH:") ; binmode DISPLAY; print DISPLAY $png_data; close DISPLAY;
      and just to try with your piece of code, I am trying with this.
      open (I, '<', "/tmp/upload/$tag.jpg"); #print $query->header(-content_type => "image/png"); print while <I>; close I; exit;
      What u say ?? pl help!!
        open (DISPLAY,">/tmp/upload/$tag.jpg") ||error ($query, "Cant open +GRAPH:") ;

        Why are you appending .jpg as extension, if the image is PNG?

        binmode DISPLAY;

        Try using binmode I; for reading and binmode STDOUT for writing the file.

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: CGI-Perl:: Location for saving the GD output
by hawtin (Prior) on Sep 10, 2006 at 08:19 UTC

    The issue is that there are two different namespaces. The one used within the server OS and the one that the browser sees.

    In the past I have created a "Dynamic Images" directory (say ~/web_pages/tmp) which is mapped by Apache (say to to "//dyn_images/"). Then the file I create is ~/web_pages/tmp/2006Sep09_01.jpg and the <img> refers to "/dyn_images/2006Sep09_01.jpg"

    The Alias directive in Apache is what you need.

Re: CGI-Perl:: Location for saving the GD output
by tinita (Parson) on Sep 10, 2006 at 19:00 UTC
      Its indeed a good advise Monk.. will try using it and get back to you.. Thank you
        To use this I tried installing

        HTML-Template-Compiled-Plugin-InlineImage-0.02 It asked to install this HTML-Template-Compiled-0.73 and then to install this, it asked to install build module.. for which i tried this.. Acme-Hello-0.03

        But this is showing error while installing.. :( and too in my system C compiler.. so its a long way to go.. but anyway thanks for your time and suggestion
Re: CGI-Perl:: Location for saving the GD output
by wfsp (Abbot) on Sep 10, 2006 at 07:41 UTC
    ...the problem is my CGI is not able to write the graph in /var/www/html/image location.

    Could you show us the part of the code that is not able to do that? What are the error messages?

      Here is the part of complete code that is of around 2000 lines.
      my $png_data = $im->png; print $query->p("$tag : Free energy curve of forward strand and shu +ffle sequence"); open (DISPLAY,">/var/www/html/upload/$tag.jpg") ||error ($query, "C +ant open GRAPH:") ; binmode DISPLAY; print DISPLAY $png_data; close DISPLAY; } print "<p> "; # print "<img src=\"http://localhost/../../../tmp/upload/$tag.jp +g\">"; # print "<img src=\"http://127.0.0.1/upload/$tag.jpg\">"; print "<img src=\"upload/$tag.jpg\">"; # print "<img src=\"http://localhost/image.jpg\"> "; print "</p>";
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: CGI-Perl:: Location for saving the GD output
by prodevel (Scribe) on Sep 11, 2006 at 12:00 UTC
    As a former anal-retentive admin, it's always better to write to the web doc-root than to system directories, esp. when upgrades come around, unless of course you're there when the upgrades happen and remember to let them know about the files unless they're unimportant...

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2020-08-05 11:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which rocket would you take to Mars?










    Results (35 votes). Check out past polls.

    Notices?