Search code examples
phpnginxheaderfilesize

PHP Content Length Mismatch with custom content delivery script


Good day everyone,

When developing a hobby website I encountered the following problem. To prevent unauthorized users from accessing image files on the server I set the folder containing the images to deny-all in nginx. This works fine but when I use the following PHP script to access the image files in the folder, Chrome randomly refuses to load them giving the following error: 'net::ERR_CONTENT_LENGTH_MISMATCH'. With random I mean that sometimes the images will load fine. I have tried to flush the output buffer before and after the readfile() call but nothing seems to solve the problem. Thanks in advance for helping me out!

PS: If you would like to see more source code/configuration files just let me know.

The PHP script:

<?php
if(!empty($_GET['tconst'])) {

        //Included login script contains this method
        if(login_check($mysqlisecure)) {
            $tconst = preg_replace( '#[^.\w]#', '', $_GET['tconst'] );

            $file = "{$_SERVER['DOCUMENT_ROOT']}/content/posters/{$tconst}.jpg";

            if (file_exists($file)) {

                $filesize = filesize($file);

                header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + (60 * 60 * 24)));
                header("Content-Type: image/jpeg");
                header("Content-Length: ".$filesize);

                readfile($file);
            }
        }
}
exit();

Solution

  • This was eventually a deeper problem than just the PHP scripts. When loading images consecutively, PHP5-fpm creates a cache from which it can probably process requests faster. The problem here was that the cache folder was generated while testing config files for nginx running as root. When I switched to 'production', PHP5-fpm nor nginx could gain full read/write access over that folder with user: www-data. When an image download request was repeated several times, PHP5-fpm tried to access the cache folders but it couldn't and therefore did not complete the request thus sending only 65,536 bytes back to the client. The simple fix was to delete the cache folder located at /etc/nginx/fastcgi_temp, let PHP5-fpm regenerate it and everything worked.

    Reading the nginx log files really helped me out this time