January 28, 2010 at 12:10 am · Filed under Program
栋力博客使用的是wpmu, 不过版本比较低了, 因此wp-content/blogs.php中还没有用X-Sendfile或者X-Accel-Redirect头来处理静态文件的代码.
于是乎, 很久以前做了一个基于nginx和X-Accel-Redirect的hack, 不过今天bluef提醒我说静态文件的Content-Type有问题,
回头去看了下NginxXSendfile模块的文档, 才发现里面提到:
You should also know that the following headers aren’t modified by nginx:
Content-Type
Content-Disposition
Accept-Ranges
Set-Cookie
Cache-Control
Expires
于是把wpmu原来的处理mimetype的函数加了回去.
当然, wpmu 2.9.1.1的这个blogs.php已经很完善了, 可以直接通过配置, 支持X-Sendfile, X-Accel-Redirect头的同时, 也有了较好的缓存控制.
改天有空可以考虑把栋力博客迁移到新版本上去, 最担心的还是栋力博客启用的大量自定义插件的兼容性问题.
·· Tags: nginx·php·wordpress·wpmu
April 8, 2009 at 10:57 am · Filed under Gossip
- 需要断点续传吗?
断点续传需要HTTP服务器的支持, 之前是est大神实现的s1完成的对PUT协议的支持.
client可以通过Google Gears, 不过服务器端还有很多可以考虑的地方.
首先, 如何识别一个需要resume的upload request呢?
我想用cookie应该是比较好的方法, 每次用户提出一个上传请求, 就建立一个cookie, 上传完成后删除此cookie.
这样避免了在最初的demo中, 使用随机的nonce带来的关闭浏览器就无法继续的bug.
- 如何实现?
我想把判断abortive的上传的部分交给前台和cookie去做, 而不是在nginx内部实现.
否则不仅仅会使得开发效率降低, 而且还得额外引入SQLite的代码, 有些古怪.
nginx的module应该是只负责处理PUT请求就可以了, 如果发现一个不存在的续传请求,
简单的抛出 400 Bad Request就ok.
- 目标?
tuna的目标是实现一个类似rapidshare这种下载站, 每个文件有一个默认的expiration,
下载可以推迟这个deadline.
下载被理解为一个dormforce id所发起的一个成功的GET行为.
一个dormforce id在不同IP产生的多次request均计算为一次.
- 架构?
准备采用nginx + php-fpm + php + mysql 实现, 因为是服务器上已经有的生产环境.
从209的那块新的SCSI硬盘上再单独划出一个逻辑卷做repository,
这样管理起来灵活方便些.
nginx 挂上 upload module 和 accesskey module, 用作大文件上传的hash, 和防盗链的控制.
下载的时候用php通过X-SendFile提供访问控制和请求转发.
因为upload module把文件的文件名都命名为了数字格式, 没有extension,
所以需要php提供Content-Type和Content-Disposition头.
防盗链这块, 用referer做第一级的过滤.
第二级用accesskey, 使用在GET参数里的nonce值, 请求文件, IP做一个MD5的accesskey保证这个地址在一个时间戳上, 对应一个文件和一个IP是唯一的.
第三级在php这里, 判断这个做nonce值的timestamp是否已经过期(比如300s), 如果okay则放行.
整体上应该大体就是这样.
唯一需要更改的地方就是让nginx的upload module支持PUT协议和续传.
中间需要改的地方还需要仔细看下.
·· Tags: Linux·nginx·php
April 7, 2009 at 10:36 pm · Filed under Gossip
今天准备装上nginx的upload module做些测试的, 结果发现自己的nginx 0.7.44下,
upload module没法通过编译, 问题出错在ngx_http_upload_module.c的1152行左右.
ngx_conf_merge_path_value(conf->store_path,
prev->store_path,
NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
ngx_garbage_collector_temp_handler, cf);
查看 ngx_conf_merge_path_value()的定义发现新的nginx中这个函数的变化很大,
改为了: char *ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev, ngx_path_init_t *init);
所以修改为了下代码:
static ngx_path_init_t ngx_init_temp_path = {
ngx_string(NGX_HTTP_PROXY_TEMP_PATH), { 1, 2, 0 }
};
// for nginx 0.7.x, hack by killkeeper
ngx_path_t *_path = ( ngx_path_t *) malloc( strlen(NGX_HTTP_PROXY_TEMP_PATH) );
memcpy ( _path, &NGX_HTTP_PROXY_TEMP_PATH, strlen(NGX_HTTP_PROXY_TEMP_PATH) );
ngx_conf_merge_path_value( cf, &_path, prev->store_path, &ngx_init_temp_path);
本来想加一个预编译头的, 不过发现nginx没有定义NGX_VERSION类似的的这种宏,
就算了.
恩, 目前编译是通过了, 明天具体测试下工作正常不.
·· Tags: C++·Linux·nginx
April 3, 2009 at 10:08 pm · Filed under Program, Tech
wpmu使用php处理静态文件的模式一直让我很不舒服,
结果今天研究了N久如何绕开php来做静态文件的处理.
先选取了自己以为最简单的实现方法, 用squid做反向代理.
装上了squid 3.1, 发现网上的config教程都是2.6的, 完全不适用,
研究了manual后, 配好了反向代理,
接着, 尴尬的事情就发生了, 因为是本地做反向代理,
无疑通过nginx来进行proxy_pass的结果就是死循环…
nginx –[proxy_pass]–> squid –[http request]–> nginx –[proxy_pass]–> squid…
太糟糕了, 要解决这个问题只有通过实现两个virtual server, 并且重写host来实现反向代理.
庞大的工程. 遂放弃.
后来转向nginx的X-SendFile功能,
原理是捕捉到特定的X-Accel-Redirect头后,
通过实现一个内部的location, 来完成一个重定向.
不过事情没有这么简单, 现有栋力博客的重写规则是:
rewrite ^.*/files/(.*) /wp-content/blogs.php?file=$1;
而静态路径里也含有 /files/ , 所以会被同时重写, 最后返回一个500 Internal Error,
并且这个error是没法通过FireBug或者日志来trace的.
研究了下nginx的判断逻辑, 加了一条URL判断后终于搞定.
详细的步骤如下:
Read the rest of this entry »
·· Tags: Linux·nginx·php·squid·wpmu
February 28, 2009 at 10:00 am · Filed under Program
众所周知, 某b是懒人, 当然这个前提与本文无关.
某b搭建的nba视频站虽然和NBA官方的版权声明冲突不小, 不过每天的PV还是能有大概17k,
不过这个统计的方法很可怕, php里先建立一个数组, 把每条访问数据push进去,
序列化, 扔到memcached里. 再一个访问来了, 反序列化, 再push, 再序列化…
后来干脆就准备写个实时的日志记录和处理的python程序, 不然序列化都会吃掉大量的脚本运行时间.
先很白痴的准备用FastCGI来做, 做一个webservice, php请求一次, 我就完成一次日志.
后来还是打webserver的主意, 不过FastCGI行不通, 就转而研究管道了.
mkfifo创建named pipeline后, 让nginx把日志输出到管道, 就可以通过python阻塞读取日志了,
不过这里python脚本要先阻塞读取, 再kill -HUP掉nginx, 让配置重新生效.
此后的处理就可以按照需要的配置来进行了,
处理后的日志数据存放在sqlite3数据库里, 方便进行查询和索引.
每条进来的日志先写在内存的数据库里, 达到一定数目时再用事务写到硬盘的实体表里.
昨天晚上大概写了个DEMO出来, 在本地调试管道,
发现一切都正常, 唯有打开事务后插入要出错,
后来Google了下, 发现也有人提到这个.
按照方法修正了, 就ok了.
继续完善了准备拿到209生产环境实践下, 然后扔到svn repoistory上去.
·· Tags: nginx·Python·sqlite·日志处理
July 20, 2008 at 5:23 pm · Filed under Gossip, Tech
最近的几次, 每每我一回华阳,
总会天色骤变, 应验了数次, 屡试不爽.
今天在摇晃的504上摇晃到了目的地,
竟然就在车拐弯进站的时候, 开始飘雨了.
(于是这让我哀伤的想起每次出门, 大抵到达一处, 便见得一出天色渐渐阴沉下来, 最后不免瓢泼作雨)
当然这天气实在是闷热的太难受, 哪怕是倾盆如柱, 加上狂风几个时辰我也不会说半个不字.
车上还在想 类Rapidshare应用的问题, 回到家顺便搜了搜nginx防盗链的东西,
就找到了这个好东西: NginxHttpAccessKeyModule, 对于某文件, 必须根据请求的用户IP生成特定的signature才能正常下载.
如 files 目录下有一 foo.zip, 则必须请求 http://domain/files/foo.zip?key=09093abeac094 才能正常下载文件, 而key值由salt和用户的remote_addr的hash值决定(SHA1或MD5).
P.S. 据说这玩意儿现在也可以防迅雷的盗链了,
由此看来, 用nginx来做 类rapidshare 的文件服务器也不是不可以的.
·· Tags: nginx·假期·盗链·闲聊