2009年3月31日星期二

nginx基于域名的rewrite实现

工作中需要将一台server从lighttpd环境迁移到nginx上.
遇到一个问题,原来lighttpd.conf配置中:

$HTTP["host"] =~ "^([^.]+)\.test\.com" {
server.document-root = "/docroot"
url.rewrite = ( "^/$" => "/index.php?username=%1")
}

访问 http://abc.test.com/ rewrite 到 http://abc.test.com/index.php?username=abc

nginx 配置没有lighttpd灵活,rewrite 只能对url中path部分操作.

查看nginx 文档 发现,新版本已经内置了变量可以直接读取host了
设置如下:

http {
servername *.test.com;
...

if ($http_host ~* "^(.+)\.test\.com") {
set $user $1;
rewrite ^/$ /index.php?username=$user last;
}

...
}

搞定,收工!

后话: 根据文档 $host 和 $http_host 应该是等价的,但是开始的时候我用$host不成功,不知道为什么,没时间研究下去了,有人看看源码告诉我结果吧,嘿嘿.

2009年3月16日星期一

proftpd开发module 小记

工作中遇到一个需求,通过ftp server实现文件hard link.

首先想到的是找找有没有已经提供这个功能的ftp server,google了一圈,找不到.

自己动手,丰衣足食,既然找不到那就自己写吧.

服务器上面正在使用的是proftpd, 接下来要做的就是开发一个module来实现hark link了

以前没写过,先找开发资料看看吧.

再次google 一下 "proftpd develop", 找到http://www.castaglia.org/proftpd/

资料挺多的,要看好一会了了.

顺藤摸瓜 又找到这里 "On the FTP commands supported" .

SYMLINK
Used to create a symbolic link (a.k.a. a symlink) from the source path (src) to the destination path (dest).
Example:

SITE SYMLINK src dest
Supported by the mod_site_misc module.

OMG ,原来proftpd支持symbol link!! hard link实现近在咫尺了.

在proftpd source 目录 ,contrib/mod_site_misc.c 里面顺利找到 具体代码实现函数 site_misc_symlink
copy and modify增加一个函数 site_misc_link, 除了一些提示,日志信息修改(SYMLINK 改成 LINK)之外,就只需把最后做symlink 的调用改成 link调用.

略读了一下mod_site_misc.c 代码,发现跟apache module结构极其相似, 由此猜测增加一个命令实现函数,需要在某处钩子加上我新增的函数. search site_misc_symlink,找到:

static cmdtable site_misc_cmdtab[] = {
{ CMD, C_SITE, G_WRITE, site_misc_mkdir, FALSE, FALSE, CL_MISC },
{ CMD, C_SITE, G_WRITE, site_misc_rmdir, FALSE, FALSE, CL_MISC },
{ CMD, C_SITE, G_WRITE, site_misc_symlink, FALSE, FALSE, CL_MISC },
{ CMD, C_SITE, G_WRITE, site_misc_utime, FALSE, FALSE, CL_MISC },
{ 0, NULL }
}

site_misc_symlink 下面增加一行

{ CMD, C_SITE, G_WRITE, site_misc_link, FALSE, FALSE, CL_MISC },

按照 这里 的方法编译通过, 测试功能一切正常.

后记,mod_site_misc module并没有日志功能,为了提供日志,还改写了大量代码.实现过程比主功能(文件hard link)实现复杂多了, 感觉怪怪的.不过日志功能必不可少,也没办法了.