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

I'm working on a program that uses CGI::Application as its base. Just about everything is working except I am unable to display an Acrobat file to the user. I've read descriptions of how to do this and have followed them, but am having no luck getting it to actually work.

Here's some snippets of code:

sub view_file { my ($self) = @_; my $cgi = $self->query; my $cgi_vars = {$cgi->Vars}; my $order = EN::OrdersDB::OrdersUpdate->retrieve( $cgi_vars->{order_id} ); my $filename = $order->dlc_file_num . ".pdf"; my $file_blob = $order->pdf_files->pdf_file; my $file_size = length ($file_blob); $self->header_props( -type => "application/pdf", -attachment => $filename, -Content_Length => $file_size, -Content_Transfer_Encoding => "binary", ); return $file_blob; }

The resulting output looks something like this in the web browser:


Content-Disposition: attachment; filename="DLC12345.pdf" Content-lengt +h: 8741 Content-transfer-encoding: binary Content-Type: application/p +df %PDF-1.4 %âãÏÓ 8 0 obj << /Linearized +1 /O 10 /H ( 694 170 ) /L 8741 /E 6007 /N 2 /T 8464 >> endobj xref 8 +14 0000000016 00000 n 0000000624 00000

... and so on. All of the expected stuff appears to be there, but it is displayed in the browser as if the Content-Type had not been changed to application/pdf.

Any suggestions?

Wally Hartshorn

(Plug: Visit JavaJunkies, PerlMonks for Java)

update (broquaint): added <code> tags to the output

Replies are listed 'Best First'.
Re: Displaying PDF files via CGI::Application
by bobn (Chaplain) on Sep 02, 2003 at 21:32 UTC

    You are seeing the headers in your browser window, indicating that some process has already sent a set of headers to your browser before the headers you are intendinign to be the headers (including the application/pdf header).

    If you have lynx handy (say on a Linux or *BSD box - there may be a PC version - try:

    lynx -head -dump your_URL_here
    to see what the headers are.

    --Bob Niederman, http://bob-n.com

    All code given here is UNTESTED unless otherwise stated.

      You are seeing the headers in your browser window, indicating that some process has already sent a set of headers to your browser before the headers you are intending

      Absolutely correct. CGI::Application has a special method for defining headers; if you don't follow it, it will send 'text/html' as the doctype.

      To override the headers, the OP used the appropriate construct:

      • $self->header_props(-type=>'application/pdf'...);
      The only thing I would add is that the CGI::Application POD says that header_props should be used in conjunction with header_type:
      • $self->header_type('header');
      might do the trick; however, that's the default value.

      My only other suggestion to the OP is to look and see if another print statement might be happening somewhere earlier in the process -- try running the application from the command line and look at the output for any whitespace preceding the headers.

Re: Displaying PDF files via CGI::Application
by Mr_Person (Hermit) on Sep 02, 2003 at 23:28 UTC
    Are you running this under mod_perl? There's a possiblility it's generating your headers for you and then CGI::Application is doing it again so the browser sees the mod_perl headers and you see the ones you want to send as plain text. If that's the case, take a look at the PerlSendHeader option for mod_perl.
Re: Displaying PDF files via CGI::Application
by cLive ;-) (Prior) on Sep 03, 2003 at 10:30 UTC
    Another useful hint is to go ahead and install MozillaFirebird browser if you haven't already, and then install the LiveHTTP Headers extension

    .02

    cLive ;-)

    ps - I also recommend these extensions to help you with development:

    • Web Developer
    • Checky
    • Pref Buttons
    • UA String Widget

    And these to stay sane in everyday browsing :)

    • Nuke Image
    • Flash click to view - invaluable in everyday life :)

    --

Re: Displaying PDF files via CGI::Application
by Anonymous Monk on Sep 03, 2003 at 00:06 UTC
    Try `HEAD url' (basically `lwp-request -m head')
Re: Displaying PDF files via CGI::Application
by Wally Hartshorn (Hermit) on Sep 03, 2003 at 13:50 UTC

    Thanks to everyone who replied with ideas for helping solve this riddle. Unfortunately (or fortunately, depending on your point of view), the solution was embarrassingly easy. This will definitely be one to put in my "Doh!" files.

    At the top of my program, I had my standard bit of code, activated in all of my CGI programs during debugging:

    BEGIN { $|=1; if (1) { print "Content-type: text/html\n\n"; # Doh! use CGI::Carp qw(fatalsToBrowser); } }

    Doh! While debugging, I start off by printing a text/html content-type, so that if something burps out some text unexpectedly, I'll be seeing the text rather than a mysterious "server 500" error in my browser. That works fine when I'm displaying HTML (I see the extra content-type header at the top of the page, of course), but not when I'm trying to display a PDF.

    Once again, with feeling: Doh!

    Thanks again to everyone who replied. (And I'm going to look into those Mozilla extensions ASAP!)

    Wally Hartshorn

    (Plug: Visit JavaJunkies, PerlMonks for Java)