XSendFile не будет обслуживать файлы в Apache 2.2
Я использую mod_xsendfile (v0.12) для обслуживания статических файлов, где Django контролирует доступ к файлам на основе пользователей и разрешений.
в моем файле conf, у меня есть:
XSendFile On
XSendFilePath e:/documents/
<Directory e:/Documents>
Order allow,deny
Allow from all
</Directory>
в моем коде django я устанавливаю заголовки следующим образом:
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
белый список. У кого-нибудь еще это работает?
2 ответов
Не устанавливайте длину содержимого самостоятельно. Это только запутает обработчики, такие как mod_wsgi в этом случае. mod_xsendfile сам установит правильную длину содержимого.
в 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 был удален некоторое время назад в пользу XSendFilePath
У меня было много проблем в большинстве случаев, когда мне приходилось настраивать путь 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 (рекомендуется)
надеюсь, это поможет кому-то! Фабьен!--2-->