Download Link to File - 4 MB File Woos

I have a script that takes a special link and prompts you to download a file. It works, however it seems on my live server it hangs and then claims that the file doesn’t exist. I did already try changing the ending to do fopen and fread but that didn’t seem to solve it.

It worked fine on local, not sure what the problem is… It’s almost a 4MB zip file that should be downloaded.


            ini_set("memory_limit", "16M");

            if (ini_get('zlib.output_compression')) {
              ini_set('zlib.output_compression', 'Off');
            }
        
            $file_extension = strtolower(substr(strrchr($params['filename'],"."),1));
        
            switch( $file_extension ) {
              case "pdf": $ctype="application/pdf"; break;
              case "exe": $ctype="application/octet-stream"; break;
              case "zip": $ctype="application/zip"; break;
              case "doc": $ctype="application/msword"; break;
              case "xls": $ctype="application/vnd.ms-excel"; break;
              case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
              case "gif": $ctype="image/gif"; break;
              case "png": $ctype="image/png"; break;
              case "jpeg":
              case "jpg": $ctype="image/jpg"; break;
              default: $ctype="application/force-download";
            }
        
            header("Pragma: public"); // required
            header("Expires: 0");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Cache-Control: private",false); // required for certain browsers 
            header("Content-Type: " . $ctype);
            
            // change, added quotes to allow spaces in filenames, by Rajkumar Singh
            header("Content-Disposition: attachment; filename=\\"".$params['filename']."\\";" );
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: " . filesize($PROTECTED_DIR . $params['filename']));

            //readfile($PROTECTED_DIR . $params['filename']);
                $f = fopen($PROTECTED_DIR . $params['filename'], 'rb');
                fpassthru($f);
                fclose($f);
            exit;

Is your directory set to write? You will need to use an ftp program like FileZilla to view what the params are for the diredtory, you can also use the Cpanel.

It should be set to 755, so only the owner can write to the folder.

That didn’t work unfortunately. I did a test using a txt document, and downloaded that fine, opening it up and reading my message. But the zip refuses to download or even show me a corrupted 0 byte file. I made a small zip file, about 1 MB and i’m having troubles with that downloading. Just timing out… So i think my method to read the file for a zip is wrong.

I’ve tried:


            // Method 1
            readfile(ROOT . $PROTECTED_DIR . $params['filename']);

            // Method 2
            $f = fopen(ROOT . $PROTECTED_DIR . $params['filename'], 'rb');
            fpassthru($f);
            fclose($f);

            // Method 3
            $chunksize = 1*(1024*1024); //you may want to change this

            $handle = fopen(ROOT . $PROTECTED_DIR . $params['filename'], 'rb');

            if ($handle) {

                while (!feof($handle)) {

                    echo fread($handle, $chunksize);

                    //ob_flush();

                    //flush();

                }
            }
            else {
                die("File couldn't be opened");
            }

            fclose($handle);

This is the line you need…


24.236.167.57 - - [06/Sep/2010:23:47:45 -0400] "GET /development/download/HeaI.5.c88YJR7Xv/free-track.zip HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"

But I got it fixed. Simply a path issue. Forgot a /… :slight_smile:

Yup, it’s 0755.

Ok, I don’t know if the root directory needs to be set to 0755 aswell but I had the same problem. In the end I used a different code which I’m happy to share, but first could you try this?

Find and change the line:


header("Content-Type: " . $ctype);

And change it to:


header("Content-Type: application/download);

This works for me when downloading a text file, but I have not tried it with a zip file.

You need to tell us the output of your error log, or turn error logging on on your live server.

Dont output errors, send them to your logfile.

On Centos I do this from the command line with:


tail -20 /var/log/httpd/error_log.1

show last 20 lines of my http daemon error log.

Only problem I’m having now is the file that gets downloaded is 0 bytes. So looking into that now. So far I fixed the content-length returning 0, so it says the right size now.

My setup is a subfolder with the file, and an .htaccess to protect the files from direct access:


#Prevent User From Accessing these Files
Order allow,deny
Deny from all