一个小项目中web小项目中使用的框架是 lighttpd 和 python cgi . 对于下载文件要做一个权限的管理。在网上找了很多资料,没有现成的方案。所以自己研究了下, 写篇博客记录下来。
首先对于下载文件做权限管理的时候,就不能放在网站的根目录或其根目录的子目录下。因为如果用户获悉路径后,就能直接下载。 也谈不上权限控制。
首先采用的方法将文件放在特殊目录下。然后让 python直接读文件,然后返回文件内容。这样做的话python 需要完整的读取下载文件, lighttpd 也需要开辟足够大的内存,处理整个文件下载的过程。对整个服务器的消耗比较大。基本代码如下:
<iframe id="frame" style="display:none"></iframe>
<a href="download.py">download</a>
print 'Content-Type: text/html'
print 'Status: 200'
print "Content-Type: application/octet-stream"
print "Content-Disposition: attachment; filename=\"log.tar.gz\" "
f = open("/root/log.tar.gz", "r")
print(f.read())
网上找了一些资料:
而lighttpd收到X-sendfile信息以后,就会找到硬盘该文件,以静态资源文件的下载方式处理,丝毫不消耗lighttpd的内存。lighttpd会以sendfile方式下载,文件内容就会被操作系统内核直接送到网卡的buffer里面,既不消耗python 进程,也不消耗lighttpd。 从里面看出lighttpd X-sendfile功能很强大。 至于为什么有这样的效果,会在后续的blog中加以说明。现在还没有完全研究明白。
lighttpd 支持X-sendfile 需要怎么做呢, 网上的资料是关于fastcgi的, 我的还不属于这个范畴,用的还是以前的cgi。为了实现这个功能,就只能查看下lighttpd的源码是否支持。
中间经历了一番周折,最后还是有所收获。把相关的代码和结果写下来,希望对大家有所帮助。
说明: 我看的lighttpd的版本是1.4.51 。不同版本的代码会有所区别。 lighttpd 1.4.29就不支持 cgi 使用X-sendfile功能,只支持fastcgi。
看下http-http-header-glue.c下有一个 http_response_parse_headers 接口,这个从字面上看就是解析 http的headers。
if (opts->xsendfile_allow) {
buffer *vb;
/* X-Sendfile2 is deprecated; historical for fastcgi */
if (opts