[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] Is binmode needed in MacPerl?



>#!perl
>open(GIF, ":Images:picture.gif") || die "oops!\n";
>
>print "HTTP/1.0 200 OK";
>print "Server: MacHTTP";
>print "MIME-Version: 1.0";
>print "Content-type: image/gif";
>
>while ($image=<GIF>) {
>   print $image;
>}
>close(GIF);

First of all, CGIs don't send the HTTP status in return;  you start with 
the headers and trust the server to send the 200.  I don't know about 
those "Server:" and "MIME-Version:" headers -- it might work with them, 
but they're unnecessary.

Here's the actual code I use;  it assumes that $ct has been set up with 
the content type of the data, which in this case would be "image/gif", 
and that $fpath contains the pathname of the file, which in your case 
would be ":Images:picture.gif" (I guess).

sub print_file_raw
{
   if (-r $fpath and $size = -s $fpath) {
         #
         # shove another header in there, just for fun -
         # some browsers make use of this
         #
      $ct .= "\nContent-length: $size";
   }
   if (!open(FPATH, $fpath)) {
      &print_file_cant_open();
   } else {
      &print_content_type($ct);
      while (read(FPATH, $buffer, 16384)) {
         print $buffer;
      }
   }
}

sub print_content_type
{
   local($ct) = @_;
   $ct = "text/html" if !$ct;
   print "Content-type: $ct\n\n";
}

Reading to and printing from a buffer of fixed size will give more 
predictable results than "while ($image=<GIF>)".  If you do it that way, 
and you're reading a GIF that happens to have a huge chunk of bytes 
between a pair of carriage returns, it may try to read more into RAM than 
you want (could abort the script if you run out of RAM).  Or, if your GIF 
happens to have ten thousand carriage returns in a row, it will run 
significantly less efficiently.


--
 Jamie McCarthy          http://www.absence.prismatix.com/jamie/
 jamie@voyager.net        Co-Webmaster of http://www.nizkor.org/
 Hate mail will be posted.