Haskell Server Pages
Table of contents:
Haskell Server Pages (HSP) is an extension of vanilla Haskell, targetted at the task of writing
dynamic server-side web pages. Features include:
- Embedded XML syntax
- A (low-to-mid-level) programming model for writing dynamic web pages
- A runtime system, in the guise of a server utility, with support for:
- session (through cookies) and application (through the server) state
- interfacing to the HTTP request-response model
- on-request compilation of pages (using hs-plugins)
- A cgi-handler utility for use where the server can't be used (i.e. if you have no control over
the resident web server). Supports everything the server does except application state and setting
outgoing headers (plus it is atm considerably slower to respond).
For more in-depth information and examples of usage, please see my thesis [ps,
pdf].
The first version of HSP was presented by Eric Meijer and Danny van Velzen at the
Haskell Workshop 2000. Their
work was never fully implemented however. This system is at the same time an
implementation, improvement and extension of their original system.
HSP is available as a darcs repository:
> darcs get http://www.cs.chalmers.se/~d00nibro/hsp
The package consists of two subparts:
- the package hsp, containing the programming model behind HSP. Works like a normal
(set of) ghc package(s). Requires haskell-src-exts.
- hspr, the runtime utilities. Consists of (the source for) a server utility hspr and
a cgi-handler hspr-cgi. Requires haskell-src-exts,
hs-plugins, HaskellDB and of course the hsp package
to install and run. You must have a version of hs-plugins that supports haskell-src-exts,
which means any version later than 050413.
The packages are cabalized. The hsp package can be configured, built and installed in the
standard way, but the hspr utilities need some extra work:
- Start by configuring the installation using
runhaskell Setup.hs configure.
Add the --prefix flag here if you want to control where the installed files
end up.
- Use ./configure with a lot of flags. There is a bug in the 6.4 version of Cabal that
means we cannot give these flags in the previous step, so we need to do it manually. If
you have a cvs version of Cabal with this bug fixed, you can add the flags in the previous
step as intended. Don't forget the
--prefix flag here as well:
- --with-server-root=<path to your hsp server root, e.g. $HOME/htdocs>
- --with-sessiondb-driver=<PostgreSQL or MySQL, case sensitive>
- --with-sessiondb-host=<probably localhost which is the default anyway>
- --with-sessiondb-name=<name of the particular database>
- --with-sessiondb-uid=<user id>
- --with-sessiondb-pwd=<password>
runhaskell Setup.hs build and runhaskell Setup.hs install.
mkdir $PREFIX/etc/hspr/compiled
touch $PREFIX/etc/hspr/.filemap
cp -r stubs $PREFIX/etc/hspr
ghc --make DbSpec.hs -o dbspec
./dbspec -c
All of this should go in a makefile or something, but that's just one of those things that
I "absolutely must do before I can release"...
To start the server utility in stand-alone mode, use the command
hspr -p <portnumber>
Currently the only existing documentation is my thesis [ps,
pdf], but unfortunately many things discussed therein
beyond the basics are not included in the current release.
I have also written a paper that will appear in the Haskell Workshop 2005 [ps,
pdf]. This paper details the implementation of HSP and the thoughts
behind it.
Things that need polishing, and things that are altogether missing, in no particular
order of significance.
- The server only handles .hsp-pages (i.e. no images or the like), as it is intended
to work as a plugin to general-purpose servers like Apache or HWS that should handle
any other file types. To properly plug the HSP server in, I (or someone else so inclined)
need to write bindings to such servers, currently the server utility only works in
stand-alone mode.
- No support for POST data yet.
- Session handling needs improvement, currently session ids are generated from 1 up
(I thought the hashUnique function had a more spread-out distribution...).
- Write libraries, libraries, libraries and more libraries.
- Write documentation.
- Implement a "nice" model for continuations.
- Probably a lot more things that I cannot remember right now.