重现WWW的起源(下):编译运行WWW 0.15源码

作者:蓬岸 Dr.Quest
知乎文章编号:698328259
创建于:2024-05-18 3:36:21
修改于:2024-05-18 3:36:21


在这个系列的上集我们已经得到了一台可用的NeXTSTEP 3.3机器,接下来的主要任务就是配置开发环境了。在继续之前,建议在下面的链接下载

fsck.technology/softwar

NS33CISCUserPatch3是NeXTSTEP 3.3的最后一版更新包,包含了著名的“千年虫”修复,而后者是开发工具的补丁包,可以在安装完开发环境之后安装。

安装NeXTSTEP开发环境

安装开发环境的过程相对简单,NeXTSTEP 3.3系统附带了一张开发光盘,一般名为developer.iso。将光盘装入NeXTSTEP电脑的光驱就会自动挂载到系统。利用上一集介绍的“芝麻开门”方式Services→Open Sesame→Open As Root方式安装光盘中NextCD\Package目录下的几个安装包。一般而言,四个安装包里只需要安装DeveloperLibs.pkg和DeveloperTools.pkg就可以正常工作,剩下的两个包分别是开发文档和GNU代码。

试用NeXTSTEP开发环境

安装好开发环境后点“计算机”图标,就会看到多出来的NextDeveloper目录,所有开发工具都其中的Apps目录,有OSX或者iOS开发经验的朋友们应该一眼就能认出那两个熟悉的名字,ProjectBuilder和InterfaceBuilder,大部分的开发工作都是围绕着它们进行的。这两个工具在Mac OS X 10.3的时候被整合成XCode,直到今天仍然是macOS的主要开发工具。

在Demos目录中能找到许多已经编译好的程序,其中就有OSX用户都非常熟悉的国际象棋

在Example里有许多代码示例,但需要注意的一点是,如果你需要编译某个程序,需要将它的文件夹复制到“me”目录下才能正常编译,不然会因为没有写入权限而失败。

NeXTSTEP 3.3的使用方式与之后的OSX开发工具大致相同,通过鼠标连线(按住Ctrl并拖拽)将界面上的控件和插座(Outlet)和动作(Action)连接。在网上可以找到开发手册:https://www.nextcomputers.org/files/manuals/nd/

但对于今天的开发者来说,即使有一些macOS、iOS,从头编写自己的程序还是需要一点降级适应的过程,一方面是编辑器没有代码高亮,另一方面则是一些编码习惯和库与今天不太一致。

比如今天几乎总会用到的foundation库,在当时就很少被用上,也没法通过#import <foundation/foundation.h>一次性引用整个foundation库,实例代码里也几乎找不到使用foundation的代码。今天开发者会频繁使用的NSString在当时也很少被使用,几乎所有字符串操作都是围绕char *类型完成的。

但整体而言,Objective-C的语法变化并不大,对于有使用Objective-C开发macOS/iOS app经验的开发者来说,阅读和修改当时的程序几乎是零成本的。

编译WorldWideWeb 0.15源码

http://evolt.org的浏览器存档中,仍然能找到一系列早期的WorldWideWeb软件包:WorldWideWeb (Nexus)

而其中唯一完整的源代码,是0.15版,更早些的0.12版有部分源代码,但并非是完整的,这一点在2019年CERN搭建Web版WWW模拟器(仅外观模拟,技术上并不相同)所做的研究中得到确认:

Inside the Code — WorldWideWeb NeXT Application

NeXTSTEP的tar命令很旧,并不支持当代Linux上常见的tar -zxvf用法,因此下载下来的WWWNextStep_0.15.tar.gz要先用gzip -d解压为tar,再在文件浏览器里解包。之后会得到一个WWW文件夹。

打开NextStep/Implementation文件夹就会发现WorldWideWeb 0.15是一个标准的ProjectBuilder工程,打开PB.project就可以Build了。

但注意Build的时候不要clean,不然会把WorldWideWeb运行时需要的主模板文件、主页等内建的HTML页面删掉,导致功能不完整。然后点Run,浏览器就会运行了。

这份1992年的浏览器代码终于运行起来!我们离互联网的历史如此之近!不过此时的WWW代码仍然有些小bug,其中之一是每次运行都会提示找不到节点cernvax.cern.ch,因为这是一个CERN已经停用的二级域名。另外当我们点击页面中的任何链接时都会卡住。

第一个问题容易解决,在代码中搜索cernvax.cern.ch,唯一一处起作用的地方在NewsAccess.m中,修改成127.0.0.1就不会再有错误提示。

而第二个问题完全没有任何线索,我本来以为要卡在这里的时候,读到了这篇帖子:koko: reviving timbl’s WorldWideWeb browser

其中最后提到

万维网连接超时是一个字节顺序问题。
在 timbl 的私有 tcp.h 中,他有 #define htons(x) (x)
NS 486 有各种字节顺序宏,因此注释掉一个 #define 确实是所需要的,尽管我花了很多失误才弄清楚这一点。我想知道他是否真的需要为68K版本的NS添加#define。

因此在tcp.h中注释掉#define htons一行就可以

这样NeXTSTEP上的WWW 0.15的bug修复就完成了!如果你愿意的话,可以在Build完成之后在ProjectBuilder的Build选项中选择install进行build,这样相当于Linux的make install,就会吧WorldWideWeb安装到me/Apps目录中。

在现代PC上搭建HTTP/0.9网站并浏览

但值得注意的,WorldWideWide 0.15已经打不开大部分的现代网站了,因为它仍然使用老式的HTTP/0.9协议,关于HTTP协议的进化,可以查阅:Evolution of HTTP - HTTP | MDN

其中一个在现代PC上提供HTTP/0.9服务的方法,是使用old-servers,这也是CERN 2019年复原项目使用的代码:CERN day 2

GitHub - remy/old-servers: Replicate old HTTP server functionality

我们可以用运行一般node.js软件的方法运行它,克隆到本地,安装npm依赖,然后运行0-9服务器,该服务器代码默认监听8124端口。

git clone https://github.com/remy/old-servers.git
cd old-servers
npm install
node 0-9

由于最初版本的WorldWideWeb没有地址栏,因此我们需要手动编写一个起始页面,比如

<title>Connect to my server</title>
<p><a href="http://192.168.1.73:8124/index.html">Click to connect</a></p>

然后就可以点击链接连接到服务器了。

如果需要替换默认的主页,则组要从文件浏览器中File→Open as folder以文件夹形式打开WorldWideWeb.app,并修改或替换其中的Default.html文件。

尾声

至此,我们在NeXTSTEP 3.3上复原WorldWideWeb 0.15的工作就完成了,我们可以完整的体验它的各项功能,WorldWideWeb 0.15不仅是一款浏览器,也是一款编辑器,使用Links菜单可以添加超级链接,但只支持本地文件,而Style可以设置文本格式,它还提供打印所需要的页面设置功能。从许多角度看,初期的WorldWideWeb 0.15都更像一款排版工具而非现代意义的“浏览器”。这也体现了诞生于CERN的WorldWideWeb其最初的目标:为科研工作者提供一款便利的在线内容发表工具。