Category Archives: 32-bit

Apache rewrites the Content-Length header to 32bit limit

I have the following proof-of-concept PHP script that sends a file for downloading:

<?php
header('Accept-Ranges: bytes');
header('Content-Type: application/octet-stream');
header('Content-Length: 2347483647');
header('Connection: close');
header('Content-Disposition: attachment; filename="filename.ext"');
header('Content-Transfer-Encoding: binary');

$out = fopen('php://output', 'wb');
$file = fopen('/home/user/files/2.3g.img', 'rb');

stream_copy_to_stream($file, $out);

fclose($out);
fclose($file);

I must mention that I'm on a 32bit system and this cannot change! Also re-compilation of PHP/Apache is out of the question.

The file that I want to send over the network has ~2.3GB, so I set the Content-Length appropriately, but when I inspect the response headers from Firefox I can see that Content-Length was set to 2147483647 (2^31 -1).

I think this can only happen because of Apache , since it wouldn't make sense for PHP to parse the headers.

What are my options here, is there a way to make apache use an unsigned int? My file is bigger than 2^31-1 bytes and it seems that Apache limits the Content-Length to that number (signed 32bit int).

$ uname -a Linux ubuntu 3.2.0-90-generic-pae #128-Ubuntu SMP Fri Aug 14 22:16:51 UTC 2015 i686 i686 i386 GNU/Linux

[email protected]:/etc/apache2$ ls mods-enabled/ alias.conf autoindex.conf mime.conf rewrite.load alias.load autoindex.load mime.load setenvif.conf auth_basic.load cgi.load negotiation.conf setenvif.load authn_file.load deflate.conf negotiation.load status.conf authz_default.load deflate.load php5.conf status.load authz_groupfile.load dir.conf php5.load authz_host.load dir.load reqtimeout.conf authz_user.load env.load reqtimeout.load