Web server serves up PDF file as wrong mime type

Posted on

Web server serves up PDF file as wrong mime type – Problems with loading a website are often blamed on the Internet connection, but even the most perfectly set up network cannot help if there is no service to reply at your destination. One of the most popular HTTP servers used for this task is Apache2. Much of Apache’s popularity can be attributed to its easy installation and use, but never the less it is possible to run into problems with even the easiest of the software. If you’ve encountered an issue loading your web page, follow these simple troubleshooting methods outlined in this guide to attempt to get your web server back up and working again. Below are some tips in manage your apache2 server when you find problem about apache-2.2, php, http-headers, joomla, mime-type.

Following an upgrade to the latest version of Joomla, downloads from a website I am working on are being served incorrectly.

Example page: http://www.pacificpolicy.org/index.php?option=com_content&view=article&id=259:mic-paper&catid=39:rokfeature

They are being served up with the correct content-disposition on first visit, but any further visits PDF files are being loaded as text/html (i.e. displaying the file’s contents on screen).

How can I force the browser to load the PDF correctly on each visit? My knowledge of PHP & http headers is pretty rudimentary, so I could use some help diagnosing this.

The host is a LAMP server, Joomla is 1.5.22, doc management plugin is Rubberdoc.

Response header on second visit reads:

Date: Thu, 16 Dec 2010 04:29:03 GMT
Server: Apache/XXx
X-Powered-By: PHP/xxx
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
Etag: db71388c6fc952682ae2fd733d4b09c5
Content-Encoding: gzip
X-Content-Encoded-By: Joomla! 1.5
Expires: Mon, 1 Jan 2001 00:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Host
Last-Modified: Thu, 16 Dec 2010 04:29:03 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

And the download docs are called from a PHP file, which goes thusly:

<?php

// Check to ensure this file is included in Joomla!
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.application.component.view');

/**
 * HTML View class for the RubberDoc component
 *
 * @static
 * @package     Joomla
 * @subpackage  RubberDoc
 * @since 1.0
 */
class RubberDocViewDoc extends JView
{
    public function display($tpl = null)
    {
        global $mainframe, $option;

        $id = JRequest::getInt('id');


        if(!$id)
        {
            JError::raiseError(404, 'Page Not Found');
            return;
        }

        $model =& $this->getModel('doc');
        $model->hit();

        $data       =& $model->getData();
        $fileName   =& $data->get('file');
        $dirname    = $mainframe->getParams('com_rubberdoc')->get('rubberdoc_dir', 'rubberdoc');
        $filePath   = JPath::clean( JPATH_SITE.DS.$dirname.DS.$fileName );

        if( !JFile::exists( $filePath ) )
        {
            JError::raiseError(404, 'Page Not Found');
            return;
        }

        $fileName = $data->get('file');
        $extension = array_pop( explode('.', $fileName) );
        $fileName = $data->get('alias').'.'.$extension;
        $fileContent  = JFile::read( $filePath );
        $fileSize     = strlen($fileContent);
        require(JPATH_COMPONENT.DS.'helpers'.DS.'mime.mapping.php');
        $mime         = $mime_extension_map[$extension]; //application/octet-stream

        // required for IE, otherwise Content-disposition is ignored
        if(ini_get('zlib.output_compression'))  {
            ini_set('zlib.output_compression', 'Off');
        }

        $doc =& JFactory::getDocument();
        $doc->setMimeEncoding( $mime );
        $doc->setModifiedDate( $data->get('modified') );
        $doc->render();

        header('Content-Disposition: attachment; filename="'.$fileName.'" ');
        header('Content-Length: '. $fileSize);

        header('Pragma: public');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Content-Transfer-Encoding: binary');

        if( ! ini_get('safe_mode') ) { // set_time_limit doesn't work in safe mode
            @set_time_limit(0);
        }

        echo $fileContent;
    }
}

Thanks,
Nick
Port Vila, Vanuatu

It’s hard to say for sure, but I would suspect that on the first visit they are being served by the java code, which sets the correct mime type. After that, there’s likely some caching going on which is not setting the correct mime type. See if you have any PDF files floating around on disk. If so, you need to look at apache’s configuration, not your code.

Leave a Reply

Your email address will not be published. Required fields are marked *