简体   繁体   中英

PHP or Apache limiting Content-Length in HTML Header?

I have to distribute a huge file to some people (pictures of a prom) via my Apache2/PHP server which is giving me some headaches: Chrome and Firefox both show a filesize of 2GB but the file is actually >4GB, so I started to track things down. I am doing the following thing in my php script:

header("Content-Length: ".filesize_large($fn));
header("Actual-File-Size: ".filesize_large($fn)); //Debug
readfile($fn);

filesize_large() is returning the correct filesize for >4gb files as a string (yes, even on 32-bit PHP). Now the interesting part; the actual HTTP header:

Content-Length: 2147483647
Actual-File-Size: 4236525700

So the filesize_large() method is working totally fine, but PHP or Apache somehow limit the value of Content-Length?! Why that?

Apache/2.2.22 x86, PHP 5.3.10 x86, I am using SSL over https

Just so you guys believe me when I say filesize_large() is correct:

function filesize_large($filename)
{
    return trim(shell_exec('stat -c %s '.escapeshellarg($filename)));
}

Edit:

Seems like PHP casts the content length to an integer when communicating with apache2 over the sapi interface on 32-bit systems. No workaround sadly except not including the Content-Size in case of files >2GB

Workaround (and actually a far better solution in the first place): Use mod_xsendfile

You have to use 64-bit operation system in order to support long integers for Content-length header. I would recommend to use Vagrant for development.

Header based on strings, but content length based on int . If take a look here https://books.google.com/books?id=HTo_AmTpQPMC&pg=PA130&lpg=PA130&dq=ap_set_content_length%28r,+r-%3Efinfo.size%29;&source=bl&ots=uNqmcTbKYy&sig=-Wth33sukeEiSnUUwVJPtyHSpXU&hl=en&sa=X&ei=GP0SVdSlFM_jsATWvoGwBQ&ved=0CDEQ6AEwAw#v=onepage&q=ap_set_content_length%28r%2C%20r-%3Efinfo.size%29%3B&f=false you will see example of ap_set_content_length(); function which was used to serve content-length response. It accepts file length from system function. Try to call php filesize() and you'll probably see the same result.

If you take a look into ap_set_content_length declaration http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga7ab393c56cf073ce7aadc3b7ca3db7b2 you will see that length declared as apr_off_t .

And here http://svn.haxx.se/dev/archive-2004-01/0871.shtml you can read, that this type depends from compiler options which is 32bit in your case.

I would recommend you to read source code of Apache and PHP projects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM