This weekend I spent a couple hours seeing if I could get the original CERN httpd web server running. I guess this is tangentially related to some things I’m doing at work–maybe more about that another time.
I wasn’t hopeful. The last released version of httpd was from 1996, so this C code is 26 years old. Also while I know what C is, I wouldn’t call myself an expert C programmer by any means. C has always seemed like the Greek or Latin of programming languages to me: an important thing to know because of how it has influenced other languages, and to understand how things have come to be the way they are. But unlike Latin and (ancient) Greek, C is still actively being used today.
I started by downloading the w3c-httpd-3.0A.tar.gz and unpacking it.
Glancing at the
BUILD.SH it had all kinds of options for
different operating systems that were popular back then: Ultrix, AIX,
Mach, HP-UX, SunOS, Irix, SCO, and of course NeXT, which is the
operating system that Tim Berners-Lee originally used to build the first
web browser and web server. But Linux was in the list too, so I ssh’d to
my Ubuntu VPS at Linode (where I host this blog), downloaded and
unpacked the tarball there, crossed my fingers, and typed
I noticed there were a lot of warnings, which aren’t necessarily bad, but there were also some errors that stopped the compilation in its tracks like:
../../Library/Implementation/HTFTP.c:444:14: error: dereferencing pointer to incomplete type ‘str uct tm’
So I took a look and did some googling and saw some Stack Overflow
comments suggesting that the
time.h header needed to be
included when you see this error. So I added one to
and the build moved on. Then I encountered this error:
../../Library/Implementation/HTTCP.c:120:14: error: conflicting types for ‘sys_errlist’ 120 | extern char *sys_errlist; /* see man perror on cernvax */ | ^~~~~~~~~~~ In file included from /usr/include/stdio.h:781, from ../../Library/Implementation/tcp.h:164, from ../../Library/Implementation/HTTCP.c:19: /usr/include/x86_64-linux-gnu/bits/sys_errlist.h:27:26: note: previous declaration of ‘sys_errlist’ was here 27 | extern const char *const sys_errlist;
Reading this error suggested that the variable declaration in
HTTPCP.c didn’t match the system level definition so I
updated the declaration in
HTTCP.c to match the one found
the build moved on to another missing
time.h which I added.
Then I ran into a linking problem:
cc -o httpd_3.0A HTDaemonDIR.o HTRequest.o HTRetrieve.o HTScript.o HTLoad.o HTCache.o HTCacheInfo.o HTConfig.o HTWild.o HTSInit.o HTSUtils.o HTims.o HTPasswd.o HTAuth.o HTLex.o HTGroup.o HTACL.o HTAAProt.o HTAAServ.o HTAAFile.o HTLog.o HTgc.o HTUserInit.o HTRFC931.o ../../Library/linux/libwww.a /usr/bin/ld: ../../Library/linux/libwww.a(HTTCP.o): in function `HTErrnoString': /home/ed/Projects/cern-httpd-orig/Library/linux/../../Library/Implementation/HTTCP.c:148: warning : `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead /usr/bin/ld: /home/ed/Projects/cern-httpd-orig/Library/linux/../../Library/Implementation/HTTCP.c :148: warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead /usr/bin/ld: HTPasswd.o: in function `HTAA_encryptPasswd': /home/ed/Projects/cern-httpd-orig/Daemon/linux/../../Daemon/Implementation/HTPasswd.c:104: undefined reference to `crypt
A bit more googling around led me to try adding
LFLAGS = -lcrypt to the
All/linux/Makefile.include file, and then the build
httpd, htadm, htimage, cgiparse and cgiutils built successfully and can be found in directory Daemon/linux. Have fun! If you have any problems with this software feel free to contact <email@example.com>. Online documentation is available via the <URL:http://www.w3.org/pub/WWW/Daemon/> BUILD complete! make: Leaving directory '/home/ed/Projects/cern-httpd-orig/All/Implementation' WWW build for linux done. status = 0
I started it up using the provided
changing the port to 9999 and the document root to my static site
website and it worked.
$ Daemon/linux/httpd -r server_root/config/httpd.conf
Interestingly it didn’t work in the browser completely because my
style.css was being served up using a
Content-Type: text/plain and browsers won’t use it unless
it is served up with
text/css. CERN httpd stopped being
developed the year that CSS was initially released.
Of course after all this noodling around I happened to notice that Emanuele Goldoni had already figured this all out and published his updates on GitHub, after simplifying things a bit by cleaning out unused non-Linux build configuration.
Still, getting it working was kind of a fun exercise, and I was really surprised that so little changes were required to get this 26 year old C code to run. I think this says something interesting about how interconnected C, GCC, Linux and the web are as a software ecosystem–and perhaps about the original httpd code itself. But most importantly it speaks to how the W3C has cared for its own history on the web–the fact that this code was even downloadable, and there was still documentation for it.
I guess seeing httpd serve up my recently updated static website, and for it to render in a browser, also illustrates how backwards compatible the web has been at the protocol level. This seems highly unusual for software.
I’m running httpd for a little bit at http://inkdroid.org:9999 … but will turn it off shortly 🖥 🐞 🔥
Update 2022-04-21: It might be nice to create a little Dockerfile for httpd to make it easy to run.