在 SBCL 等开源 Lisp 平台上运行 CL-HTTP (part 1)

标签: sbcl 开源 lisp | 发表时间:2011-07-07 12:32 | 作者:冰河 旺旺
出处:http://tianchunbinghe.blog.163.com
在开源 Common Lisp 平台上运行 CL-HTTP - 冰河 - Chun Tian (binghe)

现在我来说明在 4 种开源 Common Lisp 平台上运行 CL-HTTP 的方法,四种平台分别是 SBCLClozure CLCMUCL 和 Macintosh Common Lisp (MCL)我相信我所提供的这些信息对某些 Common Lisp 爱好者来说将是梦寐以求的。

背景

过去我也曾在博客里多次提到 CL-HTTP,多年来也一直在实际地学习和使用这个软件。概括地说,CL-HTTP 是一个纯 Common Lisp 实现的高级 Web 应用服务器。和 Common Lisp 社区的其他流行 HTTP 服务器,例如 Hunchentoot 和 AllegroServe 相比,CL-HTTP 不仅提供了 HTTP 1.1 协议的完整实现,还提供了一体化的解决方案,包括基于 Lisp 宏的动态 HTML/XHTML 代码生成,面向对象的 Web 交互设计,权限控制,HTTPS 和 HTTP Proxy 支持(带有缓存)等,另外它还提供 HTTP 客户端,SMTP/POP3/FTP 支持以及其他数不清的高级特性。CL-HTTP 是目前开源 Common Lisp 项目中规模最大、最复杂的,其核心 server 模块源代码 5 万多行,所有模块连同各种平台的移植在内共计 35 万行 Common Lisp 代码(bz2 压缩一下其实只有不到 7M),可谓是浩如烟海,Lisp 新手往往迷失在其庞大的目录树里。

CL-HTTP 最初是在 Symbolics Lisp Machine 上开发的,1994 年开始公开了源代码。作者是 MIT AI 实验室 (CSAIL) 的教授 John C. Malley,目前主要维护者还包括 Rainer Joswig 和来自几个商业 CL 平台的专家,尤其是 LispWorks 公司的 Martin Simmons。CL-HTTP 的开发工作非常缓慢,但也极度稳定可靠,不过主要是在上一代的很多商业平台上。CL-HTTP 的源代码 SVN 是不公开的,仅少量核心开发者具有访问权限,但是一般可以通过发信给邮件列表向开发者索取最新的源代码。这给追踪其源代码变化带来了一定困难,因此我自己维护了一个私有的 SVN 库将历史上获得的所有代码快照全部提交在里面,再注入我自己的一些补丁。

获得最新的 CL-HTTP 源码

CL-HTTP 网站上目前公开下载的最后版本 70.190a 已经是很老的版本了,目前的最新版本是 70.218,SVN revision 至少为 436。Rainer Joswig 定期将 SVN 上的最新版本打包放在它的个人主页上,下载地址是:


其中目前的最新版本的下载文件名是 cl-http-70-218-s436.tar.gz。不过由于上游合并补丁的速度非常慢,即便是这个最新版本仍然有一些问题导致 SBCL 下无法顺利加载。推荐使用的是本文附件中的版本,它来自我自行维护的 CL-HTTP 私有 SVN 库,修复了很多 bug,补丁已提交到上游但尚未被合并。有兴趣的读者可以同时下载两个文件然后自行比对其中的差异。 

源代码结构

CL-HTTP 的源代码可以大致分为下列 7 个部分:
  1. 平台无关的核心代码,包括 HTTP/HTTPS 协议本身的实现和 HTML、URL 等标准的实现代码;
  2. 平台无关的周边代码,包括 HTML 解析器、客户端、SMTP/FTP 等协议的实现等;
  3. 平台无关的用户贡献代码,包括 POP3 客户端、XML 工具箱以及最重要的可移植模板 (port-template) 代码等;
  4. 平台相关的核心代码,包括适用于 CMUCL、LispWorks、MCL、SCL 等主要平台的网络和工具性代码等;
  5. 平台相关的周边代码,例如 LispWorks 和 MCL 下的图形界面控制台等;
  6. 平台相关的用户贡献代码,例如 LispWorks 下的 UTF-8 支持、远程 Listener 和数据库认证接口等;
  7. 示例站点的源代码和静态文件。

以下简要介绍 CL-HTTP 的源代码目录结构,最顶层各目录的说明如下表所示:

目录名类别用途说明
 acl 平台相关代码 Allegro CL 移植
 client 平台无关的周边代码 HTTP 客户端
 clim 平台无关的周边代码 基于 CLIM 的图形控制台
 cmucl 平台相关代码 CMU Common Lisp 移植
 contrib 平台无关的用户贡献代码 各种有用的扩展,尤其包括可移植模板 (port-template)
 examples 示例站点 示例站点的源代码
 ftp 平台无关的周边代码 FTP 客户端(代理)
 html-parser 平台无关的周边代码 HTML 解析器
 lambda-ir 平台无关的周边代码 全文索引
 lcl 平台相关代码 Lucid/Liquid Common Lisp 移植
 lispm 平台相关代码 最初在 Symbolics Lisp Machine 上开发的全部代码
 lw 平台相关代码 LispWorks 移植
 mcl 平台相关代码 Macintosh Common Lisp 移植
 proxy 平台无关的核心代码 HTTP Proxy(正反向都有)
 scl 平台相关代码 Scieneer Common Lisp 移植
 server 平台无关的核心代码 核心 HTTP 协议实现和 HTML 生成代码等
 smtp 平台无关的周边代码 SMTP 协议实现
 standards 静态文件 相关 RFC 标准的文本,通过示例站点可访问到
 w3p 平台无关的周边代码 W3P (Presentation-based Interface)
 w4 平台无关的周边代码 W4 Constraint-Guided Web Walker
 www 示例站点 示例站点的静态页面和其他数据文件

在 SBCL 上启动 CL-HTTP 的方法

正确在 SBCL 上启动 CL-HTTP 的先决条件是必须拥有一个支持多线程 (sb-thread) 的 SBCL,其次一定要使用比较新的版本(目前最后发布的 1.0.49 经测试是可用的)。遗憾的是,目前 SBCL 官方站点提供的二进制版本只在 Linux/x86 和 Linux/AMD64 上默认打开了多线程支持,其他平台要么不支持多线程,要么就是默认关闭的。SBCL 目前官方的 Windows 版本多线程支持不好,推荐改用 Anton Kovalenko 维护的 sbcl-win32-threads 分支,遗憾的是,我一时找不到预编译版本的下载地址了。Mac OS X 用户需要先安装官方的二进制版本,然后使用 SBCL 源代码重新编译支持多线程的版本。这需要在源代码顶层目录里放置一个名为 customize-target-features.lisp 的文件,内容如下所示:

(lambda (features)
  (flet ((enable (x)
           (pushnew x features))
         (disable (x)
           (setf features (remove x features))))
    (enable :sb-thread)))

具体的编译和安装方法可参见 SBCL 源代码目录里的 INSTALL 文件。以下假设一个支持多线程的 SBCL 已顺利安装。

在 SBCL 下编译 CL-HTTP 最重要的一环是加载启动文件,它的相对路径是 contrib/kpoeck/port-template/load.lisp。

首先进入 CL-HTTP 源代码根目录,然后启动一个 SBCL 环境并加载上述文件:

binghe@binghe-mac:~/Lisp/self/cl-http$ sbcl
This is SBCL 1.0.49, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (load "contrib/kpoeck/port-template/load.lisp")

; loading #P"/Users/binghe/Lisp/self/cl-http/contrib/kpoeck/port-template/load.lisp"
;; loading #P"/Users/binghe/lib/sbcl/sb-introspect/sb-introspect.asd"
;; loading #P"/Users/binghe/lib/sbcl/sb-introspect/introspect.fasl"
;; loading #P"/Users/binghe/Lisp/self/cl-http/contrib/kpoeck/port-template/translations.lisp"

; file: /Users/binghe/Lisp/self/cl-http/contrib/kpoeck/port-template/load.lisp
; in: DEFUN LOAD-THE-THING
;     (POTENTIALLY-COMPILE-FILE VALUE)
; caught STYLE-WARNING:
;   undefined function: POTENTIALLY-COMPILE-FILE
; compilation unit finished
;   Undefined function:
;     POTENTIALLY-COMPILE-FILE
;   caught 1 STYLE-WARNING condition

; in: DEFUN LOAD-CL-HTTP-FILES
;     (LOAD-CL-HTTP-FILES-INTERNAL *FILES-CL-HTTP*)
; caught STYLE-WARNING:
;   undefined function: LOAD-CL-HTTP-FILES-INTERNAL
; compilation unit finished
;   Undefined function:
;     LOAD-CL-HTTP-FILES-INTERNAL
;   caught 1 STYLE-WARNING condition

Excecute (COMPILE-ALL) to compile the system. 

Excecute (LOAD-CL-HTTP-TESTER) to test the system without sockets. 

To start the simple-server do (http::start-examples) .
T

忽略那些警告,注意结尾处的三句话:执行 (COMPILE-ALL) 可以编译整个系统,执行 (LOAD-CL-HTTP-TESTER) 可以在不使用网络的情况下测试整个系统;使用 (HTTP::START-EXAMPLES) 启动示例站点。

正确的启动方法是,首先执行 (COMPILE-ALL) 然后跳过测试,直接使用 (HTTP::START-EXAMPLES) 来启动示例站点。一次完全编译可能需要花几分钟时间,并且每次只能做完全编译(以后会说明怎样节省时间)。启动成功后有类似下面的提示:

[2011-06-30 23:42:32]  HTTP Proxy Service Enabled on port 8000 for NIL.
[2011-06-30 23:42:32]  HTTP service enabled for: http://localhost:8000/

如果顺利走到这一步了,那么恭喜你,可以打开浏览器访问 http://localhost:8000/,然后就可以看到本文插图中的示例站点 Web 页面了。

(后记:附件的源代码有所更新,修复了一个 port-template 下的小问题,请看到的读者下载新版本 (r75))

新的下载地址:


(未完待续)

相关 [sbcl 开源 lisp] 推荐:

在 SBCL 等开源 Lisp 平台上运行 CL-HTTP (part 1)

- 旺旺 - Chun Tian (binghe)
现在我来说明在 4 种开源 Common Lisp 平台上运行 CL-HTTP 的方法,四种平台分别是 SBCL、Clozure CL、CMUCL 和 Macintosh Common Lisp (MCL). 我相信我所提供的这些信息对某些 Common Lisp 爱好者来说将是梦寐以求的. 过去我也曾在博客里多次提到 CL-HTTP,多年来也一直在实际地学习和使用这个软件.

在 SBCL 等开源 Lisp 平台上运行 CL-HTTP (part 2)

- Sungelina - Chun Tian (binghe)
在 Clozure CL 上启动 CL-HTTP. CL-HTTP 在 Clozure CL (CCL) 上跑得比 SBCL 更好一些,因为 CCL 的多线程 API 特性更加丰富,与 CL-HTTP 的可移植兼容层的吻合度也比较高. CCL 是我最喜爱的开源 Common Lisp 实现. 它由商业公司维护,性能稳定可靠,并且在所有支持的 OS/CPU 组合上都有多线程支持以及 32/64 位版本 (ARM 除外,只有 32 位),在 Mac OS X 上甚至还有一个 IDE.

《Practical Common Lisp 中文版》样章

- 夜深 - Chun Tian (binghe)
(注:我的译作《Practical Common Lisp 中文版》将由人民邮电出版社图灵公司出版,不过由于种种原因目前该书还在紧张的编辑之中,最后确定的出版时间为 10 月底之前. 由于拖得比较久,个人感到愧对读者,因此经过和出版社的协商,现公开其中的一章供读者预览. 内容直接来自未经编辑的原始译稿,因此本文和最后出版的内容将在细节上有所出入,还请读者见谅) 第五章 函数 (英文原版).

使用Lisp搭建独立博客

- Linker Lin - loop_in_codes
使用Lisp搭建独立博客Author:Kevin LynxDate:9.29.2011Contact:kevinlynx at gmail dot com. 本文描述如何使用Lisp工具集搭建一个完整的个人博客站点. 一个搭建好的例子站点可以参看我的个人博客:http://codemacro.com.

《实用 Common Lisp 编程》译者序

- yat - Chun Tian (binghe)
最近忙得脚打后脑勺,但博客还要持续更新,所以无奈之下只好把我给《实用 Common Lisp 编程》一书撰写的译者序重新发表在这里,以方便那些尚未读过该书的潜在读者们. 说实话,今天重读了一遍以后,我被我自己写的文字给深深打动了,因为我的写作能力很不稳定,一篇好文不是随时都可以写得出来的. 也许这就是会写字的人和职业写手的区别所在吧.

至今听到关于 Lisp 最迷人的故事

- Ben - 译言-每日精品译文推荐
来源Amazing Lisp story ever heared. 在 ILC 2002 大会上前Lisp大神,当今的Python狂热者Peter Norvig,由于某些原因,做一个类似于马丁路德在梵蒂冈宣扬新教的主题演讲,因为他在演讲中大胆地声称Python就是Lisp. 讲完后进入提问环节,出乎我意料的是,Peter点了我过道另一侧,靠上面几排座位的一个老头,他衣着皱褶,在演讲刚开始的时候踱步进来,然后就靠在了那个座位上面.

Lispの創案者、ジョン・マッカーシー逝去(84歳)

- 三十不归 - TechCrunch Japan
Lispの創案者であり、現代人工知能の父ともいうべきジョン・マッカーシー(John McCarthy)が今日(米国時間10/24)逝去した. マッカーシーはプリンストンで〔映画「ビューティフルマインド」のモデルにもなったノーベル賞受賞者〕有名なジョン・ナッシュの下で数学を学び、その後、アメリカと当時のソ連の科学者の間で世界で最初のコンピュータ同士のチェス対局を実現させた.

【外刊IT评论网】为什么我喜欢Lisp语言

- EK - 外刊IT评论
本文是从 Why I love Lisp 这篇文章翻译而来. 这篇文章是我在Simplificator——我工作的地方——的一次座谈内容的摘录,座谈的题目叫做“为什么我喜欢Smalltalk语言和Lisp语言”. 在此之前,我曾发布过一篇叫做“ 为什么我喜欢Smalltalk. 大漠黄沙 by Guilherme Jófili.

巨星殞落!人工智慧之父、LISP 語言發明人 John McCarthy 去世

- chitsaou - T客邦
在 1956 年提出「Artificial Intelligence」一詞而被稱為人工智慧之父的 John McCarthy 於10月23日過世. 2011年10月可說是科技界傷心的時期,10月5日賈伯斯逝世、10月13日 C 語言之父 Dennis Ritchie 逝世,如今又一顆巨星殞落. ▲ Stanford Engineering(史丹佛大學工學院)在官方推特上宣佈大師過世的消息.