php - Las descargas de xsendFile tienen 0 bytes
yii2 response (2)
Asegúrese de que la ruta al archivo que se va a XSendFilePath
es la misma que está utilizando en la directiva XSendFilePath
en httpd.conf
o h ttpd-vhosts.conf
O bien, ¿está enviando archivos que están fuera de la carpeta pública? Si es así, agrega XSendFileAllowAbove a la configuración de apache
En la pila LAMP, no puedo hacer que xSendFile funcione. El problema es que las descargas tienen 0 bytes.
Para estar seguro de tener instalado xSendFile, lo he agregado a mi archivo .htaccess
:
<IfModule mod_xsendfile.c>
SetEnv MOD_mod_xsendfile 1
</IfModule>
(No puedo probar esto con apache_get_modules()
porque estoy ejecutando PHP como fastCGI).
Luego tengo el siguiente código PHP:
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;
}
}
Este código se ejecuta como se esperaba; de lo cual concluyo que xSendFile debe estar instalado y / o habilitado. Luego ejecuto este script tanto con Yii xSendFile
como con PHP simple. En ambos casos, se abre la ventana de descarga, pero siempre con 0 bytes.
Estoy en el extremo de mi ingenio. ¿Qué estoy haciendo mal?
En aras de una divulgación completa, aquí está la parte relevante de httpd.conf
:
<IfModule mod_xsendfile.c>
XSendFile on
XSendFilePath /home/infar
</IfModule>
Editar:
La compresión de salida está desactivada:
ini_get("zlib.output_compression"); // returns "Off"
Chrome me muestra los siguientes encabezados:
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
Actualización 26 de marzo de 2014
Al probar la sugerencia de @gabrieloliveira, descubrí lo siguiente:
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;
Este script (donde he añadido echo ''12345678901234567890'';
) produjo una descarga para un archivo que contiene la siguiente serie de 16 caracteres 1234567890123456
. 16 caracteres coinciden con el tamaño de archivo de hello.txt
. Entonces parece que podemos concluir lo siguiente
- Content-Length y Filesize se manejan correctamente.
- O X-SendFile no encuentra el archivo, o:
- X-SendFile no procesa el archivo.
De hecho, al comentar X-SendFile, así:
// header(''X-Sendfile: ''.$path.$file);
produce el mismo resultado; indiscernible de ejecutar el encabezado X-Sendfile
.
Prueba con PHP puro editando esta parte:
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
Editar:
Prueba el cambio:
header(''application/octet-stream'');