Scheme Web Server Source Code
Using the link below, download a tarball containing the source code for a web server written in Scheme and C.
A bit of history. The server project was originally started in 2008 to create a web site for an arts organization. Choosing Scheme to implement the server was the direct result of realizing Scheme's template forms were so naturally expressive of HTML's hierarchical structure. I reasoned that it would be straightforward to show "web designers" (already familiar with HTML) how easy it is to write web pages in Scheme to be served up by the server.
Ultimately the organization decided not to proceed with the project. However, a merit of Scheme is that the original version was created in less than two months and already quite usable. It seemed a shame to discard the project, and since I had other ways to use it, development continued.
Over the subsequent three years, the code has been overhauled a number of times. The most recent and substantial rewrite took place during Jan to May 2012. The structure of the server has changed dramatically.
The server is now implemented as a multiplexed, multitasking, compiled embedded Scheme-in-C application, using Chicken Scheme and its embedding API. This approach provides advantages in stability, low-memory use, and performance, leveraging the capabilities of the Scheme and C implementations, and avoiding potential pitfalls of both. Currently in preparation, a detailed description, a tour through the code, will be provided on this site.
Development sources are available. As interest in the server grows, setting up a VCS distribution will better. In the interim, comments, feedback, bug-reports are welcome! Write to 'sourcecode at bmedctr dot com'.
Features of the server:
-
It's intended to make the server portable across implementations of R5RS (and the future R7RS) scheme. The goal is partly achieved, but there are significant limitations to portability. Interfacing with C-language code was necessary to achieve good integration with SSL and database APIs. Chicken scheme arguably has the best C-FFI among Scheme implementations, as well as one of the most portable across platforms. It may be possible to modify the code for other schemes but that's is its own project not yet attempted.
-
The server is a multitasking application, allowing full use of multi-core hardware. Initially, the server forks a configurable number of "workers" which listen for connections on ports 80 and 443. Client requests are handled by forked processes, which can handle multiple requests per connection. The inital process stays alive, monitoring the status of the workers. If a worker process terminates, it is replaced to maintain traffic-handling capacity.
-
Mail creation and MIME-parsing are built in, which can be used, for example, to build web mail clients in combination with an MTA, database server.
-
Database access procedures for postgresql are included. With portability in mind, the server implements the pgsql "front end/back end" TCP protocol, rather than a wrapper to pgsql's C library interface. While this works well, it has its own complexity, and required a bit of C coding, possibly impeding Scheme portability. In any case, using it is quite straightforward and convenient.
-
A unique feature is that web pages must be loaded as compiled .so files, which provides advantages in performance, memory usage, and security. Notably, there are no .html files at all, every page is generated from Scheme/C code. It allows the whole range of scheme progamming techniques to be used; modular style is required throughout.
-
HTTP virtual hosts are supported, and at least one is required. Virtual sites are easily set up. The number of virtual hosts is limited only by computer memory, which has become plentiful in current-day equipment. Web page files can contain more than one virtual page, along with necessary support procedures and other definitions. The full range of web application techniques is available.
-
Among the Scheme modules in the server several may be applicable in other contexts. common contains various utilities, such as a match/search wrapper simplifying irregex use. Module mime-parse and mail-create allow accessing MIME and mail data. Module iochannel is a bidirectional input/output abstraction that operates on binary and text data. A goal of iochannel was having uniform I/O API for files, net, SSL, byte channels. Also, iochannel objects can be converted to Scheme input/output ports, which can access the extended functionality iochannel provides.
Requirements:
-
C compiler: gcc, clang
-
Gnu make: gmake on BSD, etc.
-
Chicken Scheme, v. 4.7.0 or above
-
Chicken eggs: base64, srfi-99
-
OpenSSL v.1.0.0i or above (for ssl/tls library)
-
For database access:
Postgresql-9.1.3 or above (recommended)
Of course, Chicken scheme must be installed in order to compile the server. Once the server tarball is expanded, change to the "embed" directory, and at a shell prompt, enter "make" (or "gmake" on BSDs), and then "make install". The default installation prefix is '/usr/local', but of course this can be changed by editing the Makefile.
Example Web Site:
As an example, this web site is included in the source tarball.
Command Line Options:
-
-c config-file
The default configuration file is ".multiplexrc" in the directory from which the server is run. The config parameters are quite straightforward--please see the file contents.
-
Options beginning with "-:" are Chicken compiled program options. See the Chicken manual for details.
-
Otherwise command-line arguments are considered startup files that will be loaded by the embedded scheme program. These should be compiled shared objects. The default is "startup.so", compiled from "startup.scm", which contains virtual host website files to load and initialize the specified hosts. Looking at "startup.scm" will help clarify how startup is organized.
After it's compiled, "make install" will put the multiplex binary in a run path directory (by default /usr/local/bin). The sample web site can be accessed by running the server in the source directory, or optionally, "make deploy" will copy the site files to /usr/local/www, and the server can be started from that directory. The supplied "servcmd" script is a simple tool to run the server.
Edit "servcmd" to make sure user and group ids are set properly. Similarly, check the .multiplexrc configuration file, particularly the uid/gid settings. Setting "workers" to 2 is usually optimum, but it can be set higher, e.g., to the number of cpu cores if more than 2 are present.
You should then be able to start the server with "./servcmd", at a shell prompt, e.g., in an X terminal. Note that under X, "servcmd" calls the "termx" wrapper for xterm. If xterm is not installed you need to install it or modify "termx" to use the terminal emulator present on your system. Problems starting the server are usually due to incorrect directory or file permissions.
For the browser to connect to the server running on the same host, it's necessary to set a line in /etc/hosts:
127.0.0.1 webserv.here
ONce everything is set, this page should appear in your browser when pointed at your locally running virtual host. If you're having trouble, check uid/gid, directory and file permissions, local DNS setup, as these are the most frequent sources of difficulty.
License:
BSD (See LICENSE file in source directory.)
Thanks for your interest in our web server project.
© 2009-2012 BMedCTR