Stay Hungry.Stay Foolish.
使用nginx实现文件只允许被下载一次

文件下载流程 client->nginx->nginx->webroot

实现思路

用户下载文件需要带上一个token,当文件被判断为完整下载之后,token实效,在body filter和log阶段我们都可以获取到nginx发送给客户端的实际大小字节数。所以可以用这个值去和文件实际大小对比,如果相等,就判断为文件被完整下载过,token失效;

实际遇到问题一

如果client->nginx和nginx->nginx之间网络传输速率相差较大,会存在水位问题,所以我们需要在最前端的nginx加上proxy_buffering off,防止nginx->nginx数据传输完成,client->nginx还需要一个较长的传输,这时候如果client主动断开下载,也会被误判为完整下载;

实际遇到问题二

在body filter和log 两个阶段不允许使用nginx.socket API, 所以想用redis作为token存储是不行了,退而求其次,我们使用nginx自带的nginx.shared.dict;

实际遇到问题三

默认nginx支持断点续传,客户端通过这个特性实际可以绕过完整下载,因为我们判断的依据是发送的字节大小,每次重新链接下载的大小都小于文件实际大小,所以这种方式的token会多次有效,为了避免,需要加上max_ranges 0;来禁用第二台nginx代理的断点功能,;

自由转载-非商用-非衍生-保持署名(创意共享3.0许可证
评论

暂无评论~~