← 返回内容列表

[译]利用Nginx的X-Accel-Redirect头实现下载控制(附带php和rails实例)

[译]利用Nginx的X-Accel-Redirect头实现下载控制(附带php和rails实例)

有时你可能需要实现控制下载:即将下载文件的请求转发到某脚本, 然后由这脚本决定怎么做:发送这个文件给用户,出现决绝访问页,或着其他的事。在lighttpd服务器里可以通过从脚本传回X-Sendfile头实现;而Nginx是通过使用X-Accel-Redirect头实现的。在这篇文章里我会尽量简捷地描述在php和rails里如何使用这一特性。

<pre> 有时你可能需要实现控制下载:即将下载文件的请求转发到某脚本, 然后由这脚本决定怎么做:发送这个文件给用户,出现决绝访问页,或着其他的事。在<a href="http://lighttpd.net/" target="_blank">lighttpd</a>服务器里可以通过从脚本传回X-Sendfile头实现;而<a href="http://sysoev.ru/en/">Nginx</a>是通过使用X-Accel-Redirect头实现的。在这篇文章里我会尽量简捷地描述在php和rails里如何使用这一特性。

假设你使用Apache运行PHP或Rails产生动态内容,而用Nginx作为前台反向代理(bianbian注:反向代理又称为服务器加速(Server accelerate),原理是将用户的请求转发到目标服务器,然后将结果转发给用户。好处有很多:保护目标服务器安全、负载均衡容易实现、有点类似防火墙;坏处我认为就是要传递用户的IP的时候多了些步骤)。你就达到了两个目标:</pre>

<ol> <li> <pre> 因为Nginx服务器会改善所有对动态内容的缓慢请求,能节省服务器的资源(细节正在这里). (bianbian注:凭我对Nginx的理解,这个就是Nginx会缓存客户端的请求,等全部发送完毕了才一起转发给后台脚本,比如在上载文件的时候。好处是减少后台脚本等待的时间,确实对性能有一定改善;坏处就是在脚本里时时显示上载进度的功能是不可能实现了[当然,以后Nginx如果自己开放这个进度API也是可能的,不过也不是脚本级的,好在显示进度的功能不常用])</pre> </li> <li> <pre> 你能对静态文件的下载做出控制.(bianbian注:后面的一大段都是说这个啦!)</pre> </li> </ol>

<pre> 在这里,假设网站位于 /var/www 目录,而一些静态文件(类似电影、歌曲、或其他)位于 /var/www/files 目录。Apache监听8080端口。

首先,让我们看一看nginx配置:

<code>http { &nbsp; &nbsp; .... &nbsp; &nbsp; server { &nbsp; &nbsp; &nbsp; &nbsp; listen &nbsp; &nbsp; &nbsp; 80; &nbsp; &nbsp; &nbsp; &nbsp; server_name &nbsp;your-domain.com;

&nbsp; &nbsp; &nbsp; &nbsp; location / { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rewrite ^/download/(.*) /down.php?path=1 last; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_pass &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; http://127.0.0.1:8080/; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_redirect &amp;nbsp; &amp;nbsp; off; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header &amp;nbsp; Host &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;host; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header &nbsp; X-Real-IP &nbsp; &nbsp; &nbsp; &nbsp;remote_addr; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header &amp;nbsp; X-Forwarded-For &amp;nbsp;proxy_add_x_forwarded_for;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client_max_body_size &nbsp; &nbsp; &nbsp; 10m; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client_body_buffer_size &nbsp; &nbsp;128k;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_connect_timeout &nbsp; &nbsp; &nbsp;90; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_send_timeout &nbsp; &nbsp; &nbsp; &nbsp; 90; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_read_timeout &nbsp; &nbsp; &nbsp; &nbsp; 90;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_buffer_size &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4k; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_buffers &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 32k; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_busy_buffers_size &nbsp; &nbsp;64k; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proxy_temp_file_write_size 64k;

&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; location /files { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; root /var/www; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; internal; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; } }</code>

关键字&ldquo;internal&rdquo;指明了哪些目录需要通过X-Accel-Redirect头与后台脚本进行内部转向。我们的脚本只需要完成下载控制的部分,至于分段下载等其他特性跟一般的静态文件一样,都由Nginx服务器实现。 这里是 down.php 的内容:

<code><!--?php // 得到要下载的文件名 path=path =_GET["path"];

//... // 这里完成权限校验、下载统计等等 //...

// 重定向完成下载 header("X-Accel-Redirect: /files/" . $path); ?-->

在 Rails 里可以在控制(controller)里写如下代码(bianbian注:Rails是约定好的MVC架构):

得到要下载的文件名

path = @params[&quot;path&quot;]

...

这里完成权限校验、下载统计等等

...

重定向完成下载

@response.headers[&#39;X-Accel-Redirect&#39;] = &quot;/files/&quot; + path</code>

这样就完成了!用上述方法我们就能创建非常灵活又极度高效的文件分发系统。

原文链接:<a href="http://blog.kovyrin.net/2006/11/01/nginx-x-accel-redirect-php-rails/" target="_blank">Using X-Accel-Redirect Header With Nginx to Implement Controlled Downloads (with rails and php examples)</a>

标签: <a href="http://bianbian.org/tag/nginx/">nginx</a>, <a href="http://bianbian.org/tag/x-accel-redirect/">X-Accel-Redirect</a>, <a href="http://bianbian.org/tag/%e6%8e%a7%e5%88%b6/">控制</a>

</pre>

评论 (0)

加载评论中…