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

Hallo, I tried to show Word documents in the browser in a way that the real path isn't shown. So a Perl script such as:

use MIME::Base64 qw(encode_base64); if (open (INHOUD, "$regel")) { binmode INHOUD; $bufsize = 60*57; print << "EOT1"; MIME-Version: 1.0 Content-Type: text; boundary="_----------=_10167391557129230" --_----------=_10167391557129230 Content-Transfer-Encoding: base64 Content-Type: application/msword; filename="bw051122.doc" EOT1 while ($bufsize == 60*57) { read (INHOUD, $buffer, $bufsize); print encode_base64($buffer); }; close (INHOUD); print <<"EOT6"; --_----------=_10167391557129230-- EOT6 }

And so please help me. Do you have a question I'm willing to answer, if I know the answer.
Greetings, Ernst Verster

Edit: g0n - code tags

Edit: porterjohn - moved main content out of signature div

Replies are listed 'Best First'.
Re: Showing Word document in browser
by Celada (Monk) on Dec 12, 2005 at 16:42 UTC

    It looks like you are trying to build a multipart MIME entity containing the document (because of your use of boundaries) but you haven't got the right type on it. But:

    • It's not done correctly (the Content-Type: for a multipart would be multipart/mixed, not text, which is not a valid MIME type.
    • You do not need a multipart because it looks like you are trying to send only one thing (the document).
    • Browsers won't support receiving a multipart MIME message anyway over HTTP (this facet of MIME is reserved for email, not HTTP, especially Content-Transfer-Encoding: base64.

    Also, you get $bufsize to 60*57 (any special reason to pick this number 3420?) and you loop as long as it is still equal to 3420, which it always is since you never change it. It will loop forever.

    What you need to do is far simpler:

    if (open (INHOUD, "$regel")) { binmode INHOUD; print << "EOT1"; Content-Type: application/msword; filename="bw051122.doc" EOT1 while (read(INHOUD, $buffer, 4096) { print $buffer; }; close (INHOUD);

    As a bonus, if you always send the same document, you could add Last-Modified and Expires headers to enable the client to cache the result just like if you have been able to do if the web server had served the file directly.

      Thank's but I think I didn't tell it right. Let say there is a Word document /docs/word/wordfile.doc but I don't like that visitors can see this path. So I make a Perlscript showdoc.pl?wordfile.doc What does that Perl script had to do. Now I hope I said it in a good way Greeting Ernst
      Greetings, Ernst Verster

        It seems to me that Celada's reply fully answers your question: the only difference here is that now you want pass the name of the file to download as a parameter, whereas he hardcoded it. You only have to modify his code accordingly, obviously adding the necessary checks as needed.

        Since you're using user input to return something from your local file system, I recommend you read some relevant document related to security issues. You may check the Tutorials section or Ovid's course.