Dr. Mu has asked for the wisdom of the Perl Monks concerning the following question:

I'm using PDF::Create in a CGI environment. It interfaces via either a file name or file handle so, by using STDOUT, I can just stream the PDF file back to the user. However, users of Internet Explorer 4.01 and 5.5 are unable to receive files in this fashion due to a confusion between file extensions and MIME types (another stupid Microsoft trick). Anyway, I want to email the PDF as an attachment to these users. But to do so using Mail::Send and MIME::Parse requires having the entire PDF file in a variable. It's a short PDF, and I would prefer not having to write it to a file and read it back again just to get it into a variable, due to the requisite file locking and/or cleanup I'd have to do. Is there a simple way to associate a file handle with a string, so that any writes to the file handle (e.g. through PDF::Create) will just concatenate the written data to the string?

Replies are listed 'Best First'.
Re: Printing to a Variable
by zengargoyle (Deacon) on Mar 13, 2002 at 07:30 UTC
      Thanks! I knew it had to be something simple, but none of my O'Reilly books mention this one, and none of my online searches popped it up, either. 'Needed a better-formed query, I guess...
Re: Printing to a Variable
by rjray (Chaplain) on Mar 13, 2002 at 07:37 UTC

    Have a look at the section on tying file-handles in the perltie man page. I did something similar with XML::Writer a while back, which also expect a file-handle for output.

    Odds are good, given the simple nature of the problem at hand, you can get away with writing only the TIEHANDLE, PRINT, CLOSE and DESTROY methods. You may not even need the DESTROY. But not knowing what the PDF libs are doing, you may have to provide PRINTF and WRITE (the method called when syswrite() gets called). Point is, you shouldn't need to bother with the read-oriented methods, at least.

    --rjray

Re: Printing to a Variable
by dreadpiratepeter (Priest) on Mar 13, 2002 at 15:14 UTC
    You can get around the IE stupidiy in a file download by explicitly setting the content-type to "application/download". Here is the code I use (using Mason, but I'm sure you can extrapolate):
    my $subr = $r->lookup_file($file); return 404 unless -f $file and $subr->status == 200; $r->content_type("application/download"); $r->header_out('Content-disposition' => "attachment; filename=\"$fil +e\""); $r->send_http_header; return 200 if $r->header_only; $subr->run; $m->abort;

    Hope that helps

    -pete
    "I am Jack's utter lack of disbelief"
      Yes, it did help -- for IE5.5 anyway -- and that was my main concern. Frankly, I wasn't expecting it to, as I've tried more HTTP header mumbo-jumbo than you can imagine. The PHP folks are up against the same problem, and there's a plethora of similar incantations in their newsgroups -- none of which worked for me.

      But yours did. Thank you!

        No problem, I'm glad my wrestling match with it is saving others from having to wrestle it.

        -pete
        "I am Jack's utter lack of disbelief"