PHP Content Length Mismatch with custom content delivery script

时间:2016-03-02 11:02:15

标签: php nginx header filesize

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();

2 个答案:

答案 0 :(得分:3)

这最终是一个比PHP脚本更深层次的问题。当连续加载图像时,PHP5-fpm会创建一个缓存,从中可以更快地处理请求。这里的问题是在测试以root身份运行的nginx的配置文件时生成了缓存文件夹。当我切换到'生产'时,PHP5-fpm和nginx都可以通过用户获得对该文件夹的完全读/写访问权限: www-data 。当图像下载请求重复多次时,PHP5-fpm尝试访问缓存文件夹,但它不能,因此没有完成请求,因此只返回65,536字节回客户端。简单的解决方法是删除位于 / etc / nginx / fastcgi_temp 的缓存文件夹,让PHP5-fpm重新生成它,一切正常。

阅读nginx日志文件确实帮助了我

答案 1 :(得分:0)

  
    

而不是filesize($ file);使用filesize($ fileLocation)。同名     ReadFile的($ fileLocation);     这对我有用。

  
    header('Content-Length: '.filesize($fileLocation)); 
    ob_clean();
    flush();
    readfile($fileLocation);