使用 Django 和 lighttpd 提供文件服务
我正在尝试创建一种使用 Django 提供可下载内容的简单方法。这个想法是登录用户应该能够通过lighttpd下载(相当大的)文件。
这里有几篇关于此的文章,我还遇到了 博客文章提供了一个简单的解决方案。
我创建了一个如上述链接中的视图(并将“allow-x-send-file”=>“enable”添加到lighttpd配置中),并且它“有效”。当我使用 Firebug 检查标头时,我得到了正确的内容类型、文件长度和 200 OK,但没有下载任何文件。
然后我找到了一个解决方案这里发送额外的标头。现在提供了一个文件,但下载的文件是空的。标题仍然正确。
这是我的源代码(删除了 auth_decorators 并且不处理不存在的文件):
import os
import mimetypes
import django.http
from django.conf import settings
def get_absolute_filename(filename='', safe=True):
if not filename:
return os.path.join(settings.FILE_DOWNLOAD_PATH, 'index')
if safe and '..' in filename.split(os.path.sep):
return get_absolute_filename(filename='')
return os.path.join(settings.FILE_DOWNLOAD_PATH, filename)
def retrieve_file(request, filename=''):
abs_filename = get_absolute_filename(filename)
response = django.http.HttpResponse(mimetype='application/force-download')
response['X-Sendfile'] = abs_filename
response['Content-Disposition'] = 'attachment; filename=%s' % abs_filename
response['Content-Type'] = mimetypes.guess_type(abs_filename)
response['Content-Length'] = os.path.getsize(abs_filename)
return response
I'm trying to create a simple way of serving downloadable content with Django. The idea is that logged in users shall be able to download (rather large) files through lighttpd.
There are several posts about this here on SO and I came also across a blog post with a simple solution.
I created a view as in the abovementioned link (and added "allow-x-send-file" => "enable" to the lighttpd config), and it "works" sort of. When I check headers with Firebug I get the correct content type, file length and 200 OK, but no file is downloaded.
Then I found a solution here on SO, where additional headers are sent. Now a file is served, but the downloaded file is empty. Headers are still correct.
Here's my source (with removed auth_decorators and no handling of non-existent file):
import os
import mimetypes
import django.http
from django.conf import settings
def get_absolute_filename(filename='', safe=True):
if not filename:
return os.path.join(settings.FILE_DOWNLOAD_PATH, 'index')
if safe and '..' in filename.split(os.path.sep):
return get_absolute_filename(filename='')
return os.path.join(settings.FILE_DOWNLOAD_PATH, filename)
def retrieve_file(request, filename=''):
abs_filename = get_absolute_filename(filename)
response = django.http.HttpResponse(mimetype='application/force-download')
response['X-Sendfile'] = abs_filename
response['Content-Disposition'] = 'attachment; filename=%s' % abs_filename
response['Content-Type'] = mimetypes.guess_type(abs_filename)
response['Content-Length'] = os.path.getsize(abs_filename)
return response
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看您的来源 - 您没有发送文件,仅发送标头。
Look at your source - you send no file, only headers.
lighttpd 1.5 之前的版本使用
X-LIGHTTPD-send-file
标头。Pre-1.5 versions of lighttpd use the
X-LIGHTTPD-send-file
header instead.