当前位置

技术

技术

编译了一个 FastCGI 的 Apache 2.2 模块


下一个项目打算采用 FastCGI 部署,对于习惯在 Windows 桌面环境里开发的程序员,开发环境计划配置成 Apache + mod_fastcgi/mod_rewrite,通过 FastCGIExternalServer 配置连接到本机的 fastcgi 进程。

现在 Apache 主流版本已经是 2.2.x,但 http://www.fastcgi.com/dist/ 里提供的 dll 不晓得为什么配置成禁止下载。于是就从源码(mod_fastcgi-SNAP-0709231442)编译了一份(见附件 http://www.dup2.org/files/mod_fastcgi.dll
for Apache 2.2.x win32)

以前写过一篇里面提到如何在 Win32 下编译的 apache module 的...

cl /MD /D "WIN32" /c fcgi_buf.c
cl /MD /D "WIN32" /c fcgi_config.c
cl /MD /D "WIN32" /c fcgi_pm.c
cl /MD /D "WIN32" /c fcgi_protocol.c
cl /MD /D "WIN32" /c fcgi_util.c
cl /MD /D "WIN32" /c mod_fastcgi.c

link /DLL mod_fastcgi.obj fcgi_util.obj fcgi_protocol.obj 
 fcgi_pm.obj fcgi_config.obj fcgi_buf.obj 
 libhttpd.lib libapr-1.lib libaprutil-1.lib ws2_32.lib

用更复杂的编译选项可以获得一个稍微小一些的 dll (参考 apache win32 的编译参数)
cl /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "SHARED_MODULE" /FD /c *.c
link /DLL /nologo /subsystem:console /incremental:no ......

附件大小
文件 mod_fastcgi.dll60 KB
Topic: 

web.py 的最新消息

1. session 支持已经完成 (很难想象一个 web framework 居然以前一直没有 session, 是不是? )

这个是在 0.21 branch 上开发的,我已经在俺业余写的一个 web 工具上应用。马马虎虎,对于我自己的一个需求——登录后浏览器会话周期内 session 有效——需要额外配置几个参数才能工作,不是太直观;而且还没有找到全局配置后自动应用在每个 ctx 里的办法

2. web.py 已经全部转换为 bazaar 进行管理,抛弃了以前的 svn。

bazaar 是一个 pure python 应用,Ubuntu 好像是主要支持者之一

3. web.py 0.3 roadmap 前两天公布了,老代码不兼容,“There will be some changes to API, which breaks the backward compatability. But I promise, it is not going to change very much.”

不过我喜欢 0.3 用 return 代替了 print, 这是否意味着我以后可以用 print 来向 console 上输出了?有时间的话打算尝试一下

session 支持已经合并进入了主干,虽然还不能正常工作,但可以确认 0.3 版本将正式带上 session 支持

Topic: 

如何突破 kmalloc 的限制

周五有人通过某渠道知道俺曾经做过 Linux 内核模块,于是特意来请俺午饭,问了我这个问题。kmalloc 好像是总共只能使用 2M 内存的,如果用更多的就只能用 vmalloc,但其性能很糟糕;我所知道解决办法非常简单:启动系统的时候增加一个 mem=xxx 启动参数,让内核不去管理后面的那部分内存,然后在模块里面把后面的内存映射过来获得一大块连续的地址,以后根据自己的需要在那块空间上操作就可以了。

不过说到后来,映射地址的函数是什么记不得了,回到计算机前 google 了好几个关键词,最后终于确认是 ioremap 这个函数,赶快记在 blog 里,避免下次遗忘。

回想起来作为一个 C 程序员其实挺幸运的:这意味着在计算机上你可以做任何事情(前提是一个 Linux or BSD 操作系统);而且随着经验增长,去理解其他语言不是难事——由 C 入 script 易,由 script 入 C 难。

再转载一篇好玩的报导:某人做了个统计,2.6.22 内核代码中共有 151,809 的结尾空白字符;如果提交 patch 把它们全部去掉的话,那么大概需要一个 15M,共 455437 行 的 patch。然后有人指出,在 2001 的统计是有 224,654 个结尾空白,看来这几年黑客们确实是在卖力地去除空格。突然想到一个问题,vim 或 emacs 都应该能配置成自动去除尾空格吧?

Topic: 

这段时间和人闲聊的只字片语

问:为什么用 apr 而不是 glib
答:因为 glib 没有网络封装,倒是有一个 gnet,但 RH AS4 没有包括其 RPM.. 这是我选择 apr 的三个原因之一

zhb:给空中网的 J2ME 定制一个程序2个月就在几百款手机上测试通过;但给三星或中兴做项目,5个C++程序员半年都搞不定
qyb:这个世界上只有这么几种平台——Win32、Windows Mobile、J2ME、S60、J2EE、PHP(或者准确说是 AMP)、Linux...现在浏览器也可以算是一种平台了。只有针对平台做开发,才能以最小的代价获得尽可能高的收益

以前我总说“浏览器即桌面”,以后要更正成“浏览器即平台”了。这意味这 JavaScript 程序员是一个严肃的职业,正如十年前在 Win 3.1 上用 OWL 开发一样

平台意味着标准化,这就又意味着低成本和高质量

Joel 所言,Python 大概算是半个平台

今天 Facebook 发布了 FBJS... 谁会是中国第一个发布自己 js 库的互联网公司呢?

对 webmail 这样应用来说,服务器端选择怎么样的语言已经无所谓——因为重点是在前端的 AJAX 和强健的后端服务——即使是用 C++ 来输出 XML or JSON 也没有什么好奇怪的。

Topic: 

发现 gmail 的线索功能并不是依赖 Message-ID, In-Reply-To, References 标准实现的

sohu.com 内部开发的 MUA 部分已经能支持这个标准了。

特意在邮件列表上试了一下,修改了缺省的标题后发出,邮件列表自己能正确的归档,见:http://python.cn/pipermail/python-chinese/2007-September/thread.html

但是在 gmail 里面把它和别的区分开了..

联想起这段时间用邮件向 google groups 发信,总是不能和回信正确的排在一起,看来 google 即使是自己的产品也没有完全打理好.

莫非 google 的实现方式是首先排序近似主题,然后再根据 Message-ID 等字段做进一步处理 ???

Topic: 

解决 apr.h:270: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘apr_off_t’

尝试 apr 开发,什么都没有做,就是 include 了一下 apr.h,就出了这个错误.

上网搜了一下,很多人都碰到该故障,包括 xjb 同学

质疑 apache 的代码而动手改之可不是我的风格,仔细在 google 里面查找结果,发现编译应该用 pkg-config 来自动配置编译参数

cc foo.c -o foo `pkg-config apr-1 --cflags` 

联想到另外一个很常见的库 glib 也是用 pkg-config 来自动的配置的,所以建议在引用别人的库之前(尤其是这种系统预编译好的),先检查一下 /usr/lib/pkgconfig/ 目录下,看看有没有对应的 .pc 存在

Update: 我系统上 pkg-config 的结果就是 -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -I/usr/include/apr-1.0

Topic: 

Milter 协议(2)

先贴一段 twisted 框架下实现 Milter 协议解析的核心函数 :)

  1. class MilterServer(Protocol):
  2.     def init_dataReceived(self):
  3.         self.lastdata = ""
  4.         self.len = 0
  5.  
  6.     def __init__(self):
  7.         self.init_dataReceived()
  8.  
  9.     # 注意:实践中发现一次 recv 中包括了两个完整的 packet; 而且理论上存在
  10.     # 一个 packet 需要两次 recv 才能取出来的可能
  11.     def dataReceived(self, data):
  12.         if len(data): print len(data)
  13.         if self.lastdata != "":
  14.             data = self.lastdata + data
  15.         if self.len != 0:
  16.             if self.len <= len(data):
  17.                 next = data[self.len:]
  18.                 self.proc(data[:self.len])
  19.                 self.init_dataReceived()
  20.                 if len(next) > 0:
  21.                     self.dataReceived(next)
  22.             else: #继续等待输入
  23.                 self.lastdata = data
  24.         else:
  25.             if len(data) < 4:
  26.                 self.lastdata = data
  27.             else:
  28.                 self.len = struct.unpack(">i", data[:4])[0]
  29.                 self.lastdata = data[4:]
  30.                 print self.len, len(self.lastdata)
  31.                 self.dataReceived("")
  32.  
  33.     def proc(self, data):
  34.         ...
  35.         ...

上述代码在线上曾短时间的跑了跑,协议解析的逻辑部分应该是没有问题滴(稳妥起见,目前我们实际用的还是 libmilter 的 python binding)

实现 Milter Server 需要注意的一个事情就是:和 SMTP 一样,是要能支持在一次
connection 中完成多次 transaction 的!!还有 abort 命令,实际上就是一次 RSET 请求。

由于相当然的以为 eom (EndOfMessage) 事件后会话就应该结束了,结果碰到了问题怎么也想不出头绪,绕了一个多星期的弯路才找到程序的毛病所在。

另外在 Postfix 实现里面,自定义的 replymsg 的格式要求严格遵循 RFC,格式是:
"%s %s %s" % (code, Enhanced-Status-Code, msg)
E-S-C 的第一个数字要和 code 的第一个数字保持一致,见 postfix 源代码 milter8.c 里 SMFIR_REPLYCODE 的处理

仔细阅读了一下 sendmail 的 Milter Technical Overview,原来在 DATA 阶段,MTA 是需要把信件整个接受下来以后,再依次发给各个 Milter 的,而且是给一个 Milter 完整的传送完一个 message 后,再接着向下一个 Milter 发送。以前一直理解有误,觉得应该是 on-the-fly 的把数据依次传递给 Milter,这样效率最高.

今日发现之:分布式版本控制

今天发现目前开源界除了 cvs、svn、svk、git(知道 svk 和 git 的人现在恐怕也不多吧) 外,一下子又冒出 MercurialBazaarmonotone 等一大票源码控制系统...

git、svk、mercurial、bazaar、monotone 等新秀都是 distributed version control system虽然俺还没有具体了解 distributed 是个什么概念,但猜测是允许开发人员在把代码提交到远程服务器之前,可以在本地不断的 check in 来管理正在开发中的代码,确实是非常非常的有用。

linux kernel 已经开始使用 git,而 Mozilla 决定转向 mercurial ...

如果你在考虑是否把项目从 cvs 转到 svn 的话,那么这里强烈建议也评估一下这些更 IN 的东东.

Topic: 

FT 中文网的邮件列表服务不错

亲爱的会员:您好!

    感谢您曾经注册为FT中文网的会员。然而,在过去的两个月内,我们发现您
很少从您订阅的《今日焦点》或是《周五文摘》邮件中进入FT中文网的文章页面
进行浏览。不知道是因为繁忙的工作使您无暇阅读,还是 我们的邮件内容不够吸
引您?还是您更习惯通过自己登陆首页去浏览而不是通过邮件的标题进入文章页
面?

    虽然目前我们暂时中止了为您发送邮件,但我们希望给您善意的提醒:如果
您希望继续保留《今日焦点》邮件的订阅服务或是改为订阅 《周五文摘》,只需
点击以下按钮,我们将会重新为您发送,并在今后为您提供更多精彩的内容与丰
富多彩的会员活动。而如果您不再需要任何邮件服务,而是习惯直接通过登陆FT
中文网浏览文章,您可以直接点击以下的退订按钮,从此,我们将不再为您发送
邮件。

   在您不常登陆FT中文网的这段时间,我们增加了不少新的内容与功能:由FT
中文网经济评论员陈旭敏撰写的专栏《第一时间解读》及《财富管理》专题,
涵盖了当今经济社会中诸多热点问题,引起了读者的强烈反响;根据读者点击
量排列的十大热门文章中,与中国股市密切相关的文章内容精辟、眼光独到;
近期,我们还开设了名为"FT中文网博客"的栏目,邀请众多读者加盟。在功能
方面,我们增设了RSS功能,以便您随时定制个性化内容,把FT中文网变成完全
符合您口味的权威财经资讯源。

    我们期待您尽快回到FT中文网!

    P.S如果您有任何技术上或其它方面的疑问与意见,烦请您写信至foo@bar,
我们将立刻为您解决。

所以请放心订阅 FT 中文网的列表吧

订阅 RSS - 技术