2010-10-22 24 views
9

Estoy usando mod_xsendfile (v0.12) para servir archivos estáticos donde Django controla el acceso a los archivos según los usuarios y permisos.XSendFile no servirá los archivos en Apache 2.2

En mi archivo de configuración, que tengo:

XSendFile On 
XSendFilePath e:/documents/ 

<Directory e:/Documents> 
    Order allow,deny 
    Allow from all 
</Directory> 

En mi código de Django, que establezca las cabeceras de este modo:

assert(isinstance(filename, FieldFile)) 

xsendfile = filename.name 
if(platform.system() == 'Windows'): 
    xsendfile = xsendfile.replace('\\', '/') 

response = HttpResponse() 
response['X-Sendfile'] = xsendfile 
mimetype = mimetypes.guess_type(xsendfile)[0] 
response['Content-Type'] = mimetype 
response['Content-Length'] = filename.size 

Y en mi archivo de registro me sale:

[Fri Oct 22 08:54:22 2010] [error] [client 192.168.20.34] (20023)The given path 
was above the root path: xsendfile: unable to find file: 
e:/Documents/3/2010-10-20/TestDocument.pdf 

En esta versión de mod_xsendfile,

XSendFileAllowAbove On 

genera el error:

Invalid command 'XSendFileAllowAbove', perhaps misspelled or defined by a module 
not included in the server configuration 

supuse que era porque se han añadido al XSendFilePath lista blanca. ¿Alguien más consiguió que esto funcione?

Respuesta

13

No establezca Content-Length usted mismo. Esto solo confundirá a los manejadores como mod_wsgi en este caso. mod_xsendfile establecerá la Content-Length correcta.

En Windows, no solo debe proporcionar la letra de la unidad, ¡la letra de la unidad debe estar realmente en mayúscula (IIRC)!

que tienen una configuración de prueba de trabajo, así:

<Directory "E:/"> 
    XSendFile on 
    XSendFilePath E:/localhosts 
</Directory> 

Una de mis scripts de prueba de trabajo en E: /Apache2.2/htdocs/ se parece a esto:

<?php 
    header('X-SendFile: E:/localhosts/archive.tar.bz2'); 
    header('Content-type: application/octet-stream'); 
    header('Content-disposition: attachment; filename="blob"'); 
?> 

XSendFileAllowAbove fue removido Hace un tiempo a favor de XSendFilePath

+1

Otra cosa que descubrí en todo esto es que toda la ruta distingue entre mayúsculas y minúsculas, incluso si está en Windows.Si hubiera estado en Linux, eso se me habría ocurrido de inmediato, pero en Windows descarté esos problemas. ¡La LETRA DE CONDUCCIÓN DEBE SER MAYÚSCULA! – boatcoder

2

He tenido un montón de problemas la mayoría de las veces tuve que configurar la ruta de XSendfile.

Aquí soy yo probando varios escenarios en Windows para ver lo que estaba mal (salto al final de este post para ver las recomendaciones conclusión de anuncios):

<?php 

/* X-SENDFILE 
* This can be a b*tch to configure. So I'm writing various scenarios here so that I can rely on them in the future. 
* Example use: after re-installing XAMPP, after changing config file, in a new script, after some time without using it... 
* Tested on Windows 7 + XAMPP (Apache/2.4.3, PHP/5.4.7) + mod_xsendfile 1.0-P1 for Apache 2.4.x Win32 
*/ 

/** Environment Debug **/ 
//echo dirname(__FILE__); die(); 
//echo $_SERVER['DOCUMENT_ROOT']; die(); 

/** The damn fucking path, with comments **/ 

// Local file in execution directory. 
// Tested with: *no* XSendFilePath inside of the Apache config 
// Result: works fine. 
//header("X-Sendfile: " . 'localfile.zip'); 

// Local file in execution directory + relative path 
// Tested with: *no* XSendFilePath inside of the Apache config 
// Result: works fine. 
//header("X-Sendfile: " . '../xsendfile/localfile.zip'); 

// Local file in execution directory + absolute pathS 
// Tested with: *no* XSendFilePath inside of the Apache config 
// Result: works fine and a lot of flexibility on the slash and letter drive format combinations *BUT* case-sensitive 
//header("X-Sendfile: " . 'D:\Dropbox\XAMPP\web\tests\Languages\Apache\xsendfile\localfile.zip'); // works fine 
//header("X-Sendfile: " . '\Dropbox\XAMPP\web\tests\Languages\Apache\xsendfile\localfile.zip'); // works fine 
//header("X-Sendfile: " . 'D:/Dropbox/XAMPP/web/tests/Languages/Apache/xsendfile/localfile.zip'); // works fine 
//header("X-Sendfile: " . '/Dropbox/XAMPP/web/tests/Languages/Apache/xsendfile/localfile.zip'); // works fine 
//header("X-Sendfile: " . '/dropbox/XAMPP/web/tests/Languages/Apache/xsendfile/localfile.zip'); // FAILS (case-sensitive) 

// File in the XSendFilePath directory + Absolute path 
// Tested with: XSendFilePath D:\Dropbox\XAMPP\web -- Mind the backward slashes 
// Result: FAILS! error.log => [Wed Feb 20 19:08:02.617971 2013] [:error] [pid 15096:tid 1768] (20023)The given path was above the root path: [client ::1:56658] xsendfile: unable to find file: D:\\Dropbox\\XAMPP\\web\\xsfile.zip 
//header("X-Sendfile: " . 'D:\Dropbox\XAMPP\web\xsfile.zip'); 

// File in the XSendFilePath directory + Absolute path 
// Tested with: XSendFilePath D:/Dropbox/XAMPP/web <== mind the forward slashes this time 
// Result: WORKS! Conclusion: XSendFilePath needs use forward slashes on Windows AND we don't need any trailing slash in it. 
header("X-Sendfile: " . 'D:\Dropbox\XAMPP\web\xsfile.zip'); 

/** We might wanna test also: 
* - How does backward slashes in both XSendfilePath and the header combine? 
* - The use of subdirectories. 
*/

/** The rest of the headers (until otherwise stated, nothing special) **/ 
header("Content-Type: application/zip"); 
header("Content-Disposition: attachment; filename=\"" . 'blah.zip' . "\""); 
header("Content-Transfer-Encoding: binary"); 
header("Pragma: public"); 
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Cache-Control: public"); 
header("Content-Description: File Transfer"); 

/** Tell the script to stop (so the file download may start) **/ 
die(); 


?> 

Así que, básicamente, para X-Sendfile en Windows , asegúrese de que:

  • Utiliza barras inclinadas en la configuración de Apache para XSendfilePath (obligatorio);
  • Respeta el caso en tus rutas, a pesar de que estamos en Windows (obligatorio);
  • utilizar rutas absolutas en todas partes (recomendado)
  • Sin barra final de XSendfilePath (recomendado)

espero que ayude a alguien! Fabien

Cuestiones relacionadas