Boost logo

Boost :

From: Steven Siloti (ssiloti_at_[hidden])
Date: 2007-04-06 21:15:49


Darren Garvey wrote:

> This is an initial probe for ideas about an API for [any] upcoming CGI
> library submission.

I've been working on a library for writing web applications (via any
sort of gateway: cgi, fcgi, scgi, mod_proxy_http, etc.) that might be of
interest here. This is all very preliminary as it's something I hack on
in my spare time more-or-less as an exercise (I don't even have much of
a use for such a library!).

It's design is inspired by Python's WSGI in that you build up a context
based on a stack of middleware classes which act as mixins to provide
abstractions and services on top of a base request/response provided by
the gateway.

The mixin system I've created allows mixins to make arbitrary
additions/changes to the context structure. At the core is a stack class
which handles combining multiple mixins into a single (potential)
context. Here what it looks like right now:

http://magila.googlepages.com/context.hpp

It's actual method of operation is somewhat involved. Basically each
mixin consists of three types: a constructor object, a context
definition structure, and context instance structure. The constructor
object is the mixin class itself, it's responsible for carrying any
initialization parameters to the final instance.

Inside the mixin class a context definition structure (ctx_type) and a
context instance structure (type) are defined. The idea is to first
build up a type which defines the final structure of the context then
pass that as a template parameter to the instance type which actually
instantiates the various structures contained therein. The two step
process is necessary because otherwise you get a loop were a derived
class's type depends on it's base who's type depends on the derived
class's type.

Here's an example of a basic http context and a simple mixin which
parses the Content-Length header out as an int and provides an int in
the response which is assigned to the response's Content-Length header.

http://magila.googlepages.com/http_context.hpp
http://magila.googlepages.com/http_mixins.hpp

These can be combined using the stack class as such:

stack<http::context, http::content_length>

The result is a type which is itself a valid mixin. This allows a lot of
flexibility in how you build up a context. Once you've built up you
context with all the middleware you want you pass it as a template
parameter to a gateway class which is responsible for adding it's own
base request/response part of the context then calling process_request()
to kick off the upper layers in the stack.

To hide all this complexity from the end user we use a resource mixin
which takes a class as a template parameter and calls an appropriate
member function based on the http method in the request and passes it a
reference to itself. See:

http://magila.googlepages.com/http_resource.hpp

And finally a trivial example of how it all looks to the end user:

http://magila.googlepages.com/swgl_test.cpp

You'll note I've left out the gateway class. What I'm using now is just
a trivial standalone server using asio that I wrote just for debugging
that's not in any shape that I'd want to show :).

As an example, to create an instance of the final context you would do
something like this:

stack<base_context, upper_context>::type<> ctx(base_context(req, res),
upper_context(foo, bar, bas));

And thus each mixin's ::type's constructor would be passed an object
inheriting from it's containing class and which has been constructed
from the instance of that class passed to the stack's constructor.

Needless to say the code here is all very much a WIP and only provided
for reference. Sorry if this has all been a waste of (your) time, just
thought I'd throw it out there.

Steven Siloti


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk