PHP Content-Length header not working

13.2k views Asked by At

I am trying to use this code to download a .zip file

<?php
    $file = "something.zip";
    $size = filesize($file);
    header('Content-type: application/octet-stream');
    header("Content-length: $size");
    header('Content-Disposition: attachment; filename="downloaded.zip"');
    readfile($file);
?>

but it does not seem to work, even when I try to set the filesize to a number like header("Content-length: 567247784");. I only get a file that either has no size declared, or a small file size like 28 bytes.

I looked at this question, and I think I have the same problem as the poster, but his solution is "there was a server problem". I think I also have a server configuration issue, but his answer does not help me at all.

7

There are 7 answers

2
TeeraMusic On BEST ANSWER

it has to do with mod_deflate getting in the way. I spent a day messing with .htaccess and trying a million different things, in the end this fixed it but I can't really explain why:

    header('Content-Length: '.$filesize);
    header("Content-Range: 0-".($filesize-1)."/".$filesize);

I want to add that my PHP was configured with less than 256MB of memory.

0
Miralas On

Maybe the problem in this: header("Content-length:" . $size); but I could be wrong

1
Homer6 On

Try to remove the trailing ?> in cases like this. The newlines or whitespace after the ?> can alter the result.

Usually, the webserver will set the Content-Length header automatically.

For debugging, you can use the very awesome http://fiddler2.com/ to inspect the headers or even compose an arbitrary request to test your assumptions. Fiddler will warn if the content body is different from the Content-Length header.

0
chris On

Following on from TeeraMusic great analysis https://stackoverflow.com/a/30569921/820841 which identified mod_deflate as the culprit


Option 1: (Disable DEFLATE for this request)

apache_setenv('no-gzip', '1');

Proper way to stop mod_deflate for this request.


Option 2: (Disable DEFLATE for all requests of this Content-Type)

The option which controls which files are DEFLATE will most likely be in your .htaccess or httpd.conf:

AddOutputFilterByType DEFLATE "application/atom+xml" \
                              "application/javascript" \
                              ...
  1. Ensure you are actually setting the correct Content-Type for your response and it is not just matching as text/html.
  2. Remove the specific Content-Type from this list if you do not want it to be passed through mod_deflate.
0
Thompson On

I had the same problem, and in my case it was solved when I found in some php file included one escape character before <?php tag. Then, the returned by page is bigger than informed in $size = filesize($file); And this cause the error.

1
Charris Kefallinos On
$contentLength = -1 ;

The only way worked for me

0
محسن عباسی On

I think the easiest and the best way is:

$head = array_change_key_case(get_headers($file, TRUE));
                    $filesize = $head['content-length'];