博客

CHINA 之爱,同予者何人

(很久没有更新,没想到更新一次是这个内容)

今日一大早就收到这样一条消息

转发:msn名字后面请加( L )CHINA (括弧里 L 前后的空格去掉) 让全世界看看华人的团结。
请转发您的msn朋友。

到了下午一个同事与我的 msn 对话

BruceCHINA 说:
你改成love money得了。。

FreeSoftware qyt(又要msn大站队了) 说:
说老实话,我想改成FUCK 或者M

BruceCHINA 说:
...........
BruceCHINA 说:
没人比你个性了

FreeSoftware qyt(又要msn大站队了) 说:
我个人觉得这种站队的方式让我想起文革
FreeSoftware qyt(又要msn大站队了) 说:
非常不支持

BruceCHINA 说:
没那么严重,这是对外,不是对内

FreeSoftware qyt(又要msn大站队了) 说:
我觉得差不多。这种行为哪天对内也是一样的。 只不过现在是对外而已。
FreeSoftware qyt(又要msn大站队了) 说:
所以我改成现在这个样,潜台词就是提醒大家要容忍别的声音。

BruceCHINA 说:
有道理有道理

FreeSoftware qyt(又要msn大站队了) 说:
谢谢:)


链接里的对比很直观

Topic: 文化 社会

wbr 是一个很酷的标签

首先参考一下我的这一篇文章,里面有一个很酷的 url link 的折行效果。哦,没错,这就是 wbr 魔术。

事实上昨天我还在为原来的丑陋布局懊恼不已:

不过今天在查找 webmail 的一个 pre 标签里很长一行文字如何强制折行的显示问题的时候,意外的从老韩那里知道了 gmail 的这个处理链接的方案,非常巧妙!

具体妙用,看看那篇文章的源代码就知道。或者用 firebug 看看 gmail 是如何没有发现空格断词的话就猥琐得时不时插入一个wbr标签的。

这个世界上靠精通 HTML 吃饭的家伙除了 W3C 和做浏览器的那帮人外,应该就是 google 这种搜索引擎公司了吧。

关于 pre 的折行问题,也有相应的 css 解决方案,我这里做了一个简单的测试页面

Topic: 技术

近几日记事

1. "If the only tool you have is a hammer, you tend to see every problem as a nail"

觉得自己所学还是远远不够

2. Google App Engine 发布。所谓未来的五台超级计算机,Amazon 的S3/EC2/SimpleDB 已经出现一段时间了,Google 现在也有了...

下一个会是谁?IBM 还是 MS?

3. 连续三天了,本周早上骑车出门,发现学清路居然不堵车了!!!感觉是新通了一条路,不错不错。

Topic: 技术 生活

Python 的一个 TypeError: unbound method ... 问题

碰到这个问题的时候,网上找到最接近的案例是 http://mail.python.org/pipermail/python-list/2002-July/154968.html, 可惜没有下文。后来在 http://www.nabble.com/TypeError-in-base-class-__init__-after-reload-td15058502.html 的帮助下找到了原因。

不太好描述,写具体例子吧,一共需要三个 py 文件:
module1.py

  1. class Super:
  2.     def __init__(self):
  3.         pass

module2.py

  1. import module1
  2.  
  3. class Sub(module1.Super):
  4.     def __init__(self):
  5.         module1.Super.__init__(self)

run.py

  1. from imp import load_source
  2.  
  3. x = load_source("module2", "module2.py")
  4. #load_source("module1", "module1.py")
  5. print x.Sub()

这三个文件放在同一个目录下,然后运行 run.py,结果看起来很好;但如果我们去掉 run.py 里面的那个注释,就得到错误:
TypeError: unbound method __init__() must be called with Super instance as first argument (got Sub instance instead)

用人家的解释就是:there are some real problems with reloading modules when you have references to objects in the module object. The module is reloaded but the references are not automatically rebound to the new module.

当应用需要从一个目录下 import 所有的模块的时候,如果忘了这个依赖问题,就可能出错了;而且这个错误和遍历目录获得的文件顺序有关,有可能在开发环境下好好的,但部署到生产系统后问题才暴露。切记切记

Topic: 技术

十月怀胎

实在想不出更合适的题目了,贴个图纪念一下

如何用 nginx 做 postfix 的 SMTP 反向代理,以及 XCLIENT 的支持

作为 lighttpd 的竞争者,轻量级web服务器 nginx 最近才开始崭露头角,知道它还可以用来做 pop3/imap4 反向代理的估计就比较少了,至于用 nginx 做 smtp 的反向代理,估计全中国现在和我一样想到这个需求的人一只手就能数过来。

需要 smtp 反向代理是因为我们的 vip 邮箱是可以免费试用的,希望在策略上对已交费用户和免费试用用户(其中有相当部分是 spammer)做出不同处理。前面用 nginx 把不同的用户请求代理到后台不同的 postfix 上,然后 postfix 再各自配置不同的 Milter Server 做过滤。另外需要前台能支持 XCLIENT,这样 postfix/milter 可以得到客户端的 IP,对于 anti-spam 来说是很有意义的。

nginx 在大约一年前增加了对 XCLIENT 的支持,对于 webmail 服务来说,nginx 可以说是再完美不过的反向代理前台了。

nginx 配置 smtp 反向代理需要在配置文件里加这么一段:

mail {
    auth_http http://127.0.0.1/auth;
    server {
        listen 26;
        protocol smtp;
        proxy on;
        smtp_auth login plain;
    }
}

用 python 写一个简单的 auth 服务来做测试:

  1. import SimpleHTTPServer
  2.  
  3. class handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  4.     def do_GET(self):
  5.         if (self.path == '/auth'):
  6.             # verify 'Auth-User', 'Auth-Pass', 'Client-IP'
  7.             if self.headers.get('Auth-Protocol') == 'smtp':
  8.                 self.send_response(200)
  9.                 self.send_header("Auth-Status", "OK");
  10.                 self.send_header("Auth-Server", "127.0.0.1");
  11.                 self.send_header("Auth-Port", "25");
  12.                 self.end_headers()
  13.                 return
  14.  
  15. addr = ('', 80)
  16. httpd = SimpleHTTPServer.BaseHTTPServer.HTTPServer(addr, handler)
  17. httpd.serve_forever()

修改 postfix 的 main.cf 配置,允许 nginx 代理服务器发送 XCLIENT 命令。

smtpd_authorized_xclient_hosts = 127.0.0.0/8

理论来说,到这里就应该就都配置好了。但是 nginx 会带上一个 LOGIN=foobar 的属性发给后台,而 postfix 是不支持该属性的,这将导致 postfix 报告一个 Bad XCLIENT attribute name: LOGIN 的 501 错误。很疑惑当初贡献这段代码的人是用什么 smtp server 做后台的,总之和 postfix 配合的话,必须修改 nginx 的程序(比修改 postfix 要简单些): 找到 src/mail/ngx_mail_proxy_module.c 里 "case ngx_smtp_helo:" 的那一部分,把和 "LOGIN" 相关的代码去掉就好了

附:最后决定利用周末时间写一个 patch,希望会被 nginx 接纳.
nginx-0.5.35-xclient.patch

最近二三事

长期以来,达达拉完臭臭后都是让她爹妈擦屁股,偶们也就一直忍气吞声了。直到前两天,她又在厕所里大叫:“拉完了!!!”,老婆和我都忙着,被骚扰得不胜其烦,于是问她:在幼儿园不是都自己擦吗?怎么回家后还要爸爸妈妈来??达达等了好长时间只得我们这样的质问,坐在马桶上痛心疾首的回答:自己擦好恶心啊~~~~


翻出一个迷你三脚架,于是用2秒的快门对学清路拍了张照片

达达吃饭,如果吃饭途中打嗝,她会说:打了一个还要吃的嗝,如果吃完饭后打嗝,她就说:打了一个吃饱了的嗝

星期天,带达达去故宫溜达了一圈,从天安门口出来,看见一些身穿奇怪服装的警察,胸口和上臂衣服上的 LOGO 是 SWAT,咳咳,相当的装
星期天晚上第一次炒猪肝,仍然是相当的成功,自我感觉已经完全超过了我妈的水平。今天和老婆讨论下次再做什么挑战自我的项目,已经把八珍豆腐列入人生目标之一,哈哈

Topic: dada 生活

json-py、simplejson、cjson

最开始我们的 web 项目的时候,因为 json-py 最易使用——只有一个独立的文件,无需安装,放在开发目录下直接 import 即可,而且当时我醉心于 pure python 的概念,所以就这么一直用下来。

直到上周对代码做压力测试,某个流程中 json encoder 的时间居然耗掉了整整 1/3,而这个流程是最常用的功能之一,于是就寻找 json-py 的替代物。

首先想到的是 simplejson。由于 django 的内置,它可能是 python 界用得最广泛的 json 库了,而且其最新版本还包括了一个 c 的扩展以提高性能。一开始我也是对它寄予厚望,但 profiling 结果很让人郁闷:它的 decode 速度的确是比 json-py 快了不少(大概速度是3倍),但 encode 速度提升及其有限。

最后只好选择了 cjson,效率非常让人满意。
但接口友好程度就比上面两个差远了:一方面是 encode 对非 unicode 的数据类型支持不太好(比如 UTF-8 字符串里高8位字符都escape),我们只好把数据统统 str.decode('utf-8') 一下后再交给它;另一方面是它对中文 unicode 字符串的 decode 实现好像也是有问题,不过还好能想恶心办法绕过去。

结论:cjson效率最好,但兼容性一般;通常来说 simplejson 可能就足够了;如果不是 js 端会传来海量数据要 decode,json-py 也可以将就用,而且就一个文件,简单易import

附:写到本文的时候,发现一个叫 demjson 的项目四个月前刚发布新版本,而且号称自己是最快的纯python解决方案,也是一个文件就可用,看来值得一试。
而且为什么有了 _speedups.c 的 simplejson 速度和 json-py 比起来差别不大,也挺让人疑惑,啥时候有时间再重新测试看看。

Topic: 技术

links for 2008-03-15

Topic: del.icio.us
订阅 RSS - 博客 | BT的花