Content-Length Header problem

#1
Hello,
I'm using LiteSpeed 4.1.12 and PHP 5.3.10.
When I try to send files greater than 2147483647 bytes (2GB) the download doesn't start.
Removing the header Content-Length the download does start but without file size.

It looks like a 32bits limitation but both programs and the OS (Linux 2.6.38-8-server Ubuntu x86_64) are 64 bits.

Any ideas what may be causing the problem?

Thanks.
 

webizen

Well-Known Member
#2
If the download go through php, then 2G is the limit.

Max Dynamic Response Body Size (bytes) (Admin Console => Configuration => Server => Tuning) has hard limit of 2047MB.

For upload, there is no limit for Max Request Body Size (bytes) on 64bit system.
 
#3
Thanks for the reply,
I think this isn't the problem. The content is sent in small pieces.
My Max Dynamic Response Body Size is set to 500M and I can usually set up to 2147483647, download size appears and download starts (and complete).
If I do not define the Content-Length header, download generally occurs without showing the file size.
I think it's a problem with the interpretation of Content-Length header.
Maybe a bug with integer type.

This is what I have:
PHP:
<?php
define('CHUNK_SIZE', 1024*1024); // Size (in bytes) of tiles chunk

// Read a file and display its content chunk by chunk
function readfile_chunked($filename, $retbytes = TRUE) {
	$buffer = '';
	$cnt =0;
	// $handle = fopen($filename, 'rb');
	$handle = fopen($filename, 'rb');
	if ($handle === false) {
		return false;
	}
	while (!feof($handle)) {
		$buffer = fread($handle, CHUNK_SIZE);
		echo $buffer;
		ob_flush();
		flush();
		if ($retbytes) {
			$cnt += strlen($buffer);
		}
	}
	$status = fclose($handle);
	if ($retbytes && $status) {
		return $cnt; // return num. bytes delivered like readfile() does.
	}
	return $status;
}

	$filename = '/media/Test/Files/BigFile.rar';
	$mimetype = 'application/x-rar-compressed';
	$sz= filesize($filename);
	header('Content-Type: '.$mimetype );
	header('Content-Disposition: attachment; filename="'.basename($filename).'"');
	header("Content-Length: ".$sz);
	readfile_chunked($filename);

?>
This will not start the download.

If I change
header("Content-Length: ".$sz); to header("Content-Length: ".(2147483647));
It works, and to
header("Content-Length: ".(2147483648));
don't work.

Please help me
 

NiteWave

Administrator
#4
lsws looks ok for large content-length.
I tested on 1 of lsws server:
~>curl -I xxx.com/nginxlogs/media5.access.log
HTTP/1.1 200 OK
Date: Wed, 27 Jun 2012 09:49:19 GMT
Server: LiteSpeed
Accept-Ranges: bytes
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
ETag: "183c7619aa-4f3a1dab-57741bb"
Last-Modified: Tue, 14 Feb 2012 08:39:07 GMT
Content-Type: application/octet-stream
Content-Length: 104093587882
its size is 104G or so.
so may relate to php limit or lsapi.
 
#6
Yes, directly download big files work. But when I send file with PHP, It doesn't work.
Can you help me to find where are the problem?
My PHP and LiteSpeed are 64 bits, I don't understand why this is happening.

Please look at this script:
PHP:
<?php
	$sz = 1024 * 1024 * (1024 * 2);
	//$sz-=1;
	//die($sz);
    $mimetype = 'application/x-rar-compressed';
    header('Content-Type: '.$mimetype );
    header('Content-Disposition: attachment; filename="test.rar"');
    header("Content-Length: ".($sz));
	for($i=0; $i<$sz; $i++){
		echo " ";
	}
?>
There is no file, and should display the download window and correct file size.
In Apache works fine. When I try this with LiteSpeed, download don't start and use 96 percent of CPU.

I need to run some code inside of the download loop to do some verifications when every chunk was send. (control download speed based on number of users downloading)
With the header X-LiteSpeed-Location I can't do this.

I've checked with Wireshark, when I request the page with this script, It doesn't receive response.
When I uncomment //$sz-=1; it works. (because works with files <2147483648)

Can you test this script in your LiteSpeed server and check if it works?
 
Last edited:
Top