Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xsendFile downloads have 0 bytes

On LAMP stack, I can not get xSendFile to work. The problem is that the downloads have 0 bytes.

In order to be sure that I have xSendFile installed, I have added this to my .htaccess file:

<IfModule mod_xsendfile.c>
  SetEnv MOD_mod_xsendfile 1
</IfModule>

(I can not test this with apache_get_modules() because I am running PHP as fastCGI.)

I then have the following PHP code:

 if (1 != getenv('MOD_mod_xsendfile'))
    {
        echo 'mod_xsendfile is not installed';
    }
    else
    {
        $path = '/home/infar/';
        $file = 'hello.txt';
        if (file_exists($path.$file) && strlen($path.$file)>1)
        {
            if (true) // change to false to go around Yii
            {
                Yii::app()->request->xSendFile($path.$file,array(
                    'saveName'=> 'hello.txt',
                    'mimeType'=> 'plain/text',
                    'terminate'=> true,
                ));
            }
            else
            {
                //set proper Content-Type
                header('Content-Type: plain/text');
                //force download box with the filename hello.txt
                header('Content-Disposition: attachment;filename=hello.txt');
                header('X-Sendfile: $path.$file');
                exit;      
            }  
        }
        else
        {
            echo 'file not found at: '.$path.$file;
        }
    }

This code runs as expected; from which I conclude that xSendFile must be installed and/or enabled. I then run this script both with Yii xSendFile and with plain PHP. In both cases the download window opens, but always with 0 bytes.

I am at my wits' end. What am I doing wrong?

In the interest of full disclosure, here is the relevant part of httpd.conf:

<IfModule mod_xsendfile.c>
    XSendFile on
    XSendFilePath /home/infar
</IfModule>

Edit:

Output compression is turned off:

ini_get("zlib.output_compression"); // returns "Off"

Chrome shows me the following headers:

Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Disposition:attachment;filename=hello.txt
Content-Length:0
Content-Type:plain/text
Date:Sun, 23 Mar 2014 18:22:49 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=2, max=100
Pragma:no-cache
Server:Apache
X-Sendfile:/home/infar/hello.txt

Update March 26th, 2014

When testing @gabrieloliveira suggestion, I discovered the following:

header('Content-Type: plain/text');
header('Content-Disposition: attachment;filename=hello.txt');
header('X-Sendfile: '.$path.$file); // $path.$file outside quotes
header('Content-Length: '.filesize($path.$file)); // Filesize
echo '12345678901234567890';
exit;  

This script (where I have added echo '12345678901234567890';) produced a download for a file containing the following 16 character string 1234567890123456. 16 characters matches the filesize of hello.txt. So it seems we can conclude the following

  1. Content-Length & Filesize are handled correctly.
  2. Either X-SendFile does not find the file, or:
  3. X-SendFile does not process the file.

In fact, commenting out X-SendFile, like so:

// header('X-Sendfile: '.$path.$file);

produces the same result; indiscernible from executing the X-Sendfile header.

like image 925
Ivo Renkema Avatar asked Mar 19 '14 14:03

Ivo Renkema


2 Answers

Test with pure PHP editing this part:

header('Content-Type: plain/text');
//force download box with the filename hello.txt
header('Content-Disposition: attachment;filename=hello.txt');
header('X-Sendfile: '.$path.$file); // $path.$file outside quotes
header('Content-Length: '.filesize($path.$file)); // Filesize

Edit:

Try change:

header('application/octet-stream');
like image 140
gabrieloliveira Avatar answered Nov 18 '22 00:11

gabrieloliveira


Make sure the path to the file to serve is the same path you're using on the XSendFilePath directive on httpd.conf or httpd-vhosts.conf

Or: Are you sending files which are outside the public folder? If so then add XSendFileAllowAbove on to apache config

like image 2
Meetai.com Avatar answered Nov 18 '22 02:11

Meetai.com