2010-10-22 2 views
9

Я использую mod_xsendfile (v0.12) для обслуживания статических файлов, в которых Django контролирует доступ к файлам на основе пользователей и разрешений.XSendFile не будет обслуживать файлы в Apache 2.2

В моем файле конф, у меня есть:

XSendFile On 
XSendFilePath e:/documents/ 

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

В моем Джанго коде я установить заголовки вроде так:

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 

И в моем файле журнала я получаю:

[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 

В этой версии mod_xsendfile,

XSendFileAllowAbove On 

генерирует ошибку:

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

Я предположил, что это потому, что они добавили XSendFilePath белый список. Кто-нибудь еще заработал?

ответ

13

Не устанавливайте контентную длину самостоятельно. В этом случае это только путают обработчики, такие как mod_wsgi. mod_xsendfile сам установит правильный Content-Length.

В Windows вы должны не только предоставить букву диска, буква диска должна быть фактически в верхнем регистре (IIRC)!

У меня есть конфигурация рабочего тест следующим образом:

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

Один из моих тестовых сценариев работы в E: /Apache2.2/htdocs/ выглядит следующим образом:

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

XSendFileAllowAbove был удален a назад назад в пользу XSendFilePath

+1

Другое, что я обнаружил во всем этом, что весь путь чувствителен к регистру, даже если вы находитесь на окнах.Если бы я был на Linux, который бы сразу пришелся на меня, но на окнах я отбросил эти проблемы. ПИСЬМО ПРИВОДА ДОЛЖЕН БЫТЬ ВЕРХНИЙ! – boatcoder

2

У меня была большая проблема в большинстве случаев, когда мне приходилось настраивать путь XSendfile.

Вот я тестирование нескольких сценариев Windows, чтобы увидеть, что было неправильным (скачок до конца этого поста, чтобы увидеть рекомендации заключение объявлений):

<?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(); 


?> 

Таким образом, в основном, для X-SendFile на Windows, , убедитесь, что:

  • Вы используете косые черты в своей конфигурации Apache для XSendfilePath (обязательно);
  • Уважайте дело на своих путях, хотя мы в Windows (обязательно);
  • Используйте абсолютные пути везде (рекомендуются)
  • Нет слеш для XSendfilePath (рекомендуется)

Надеется, что это помогает кто-то! Fabien

Смежные вопросы