By default, the built-in HTTP server will be used. However, other back-ends
like CGI/FastCGI can be used if so desired.

So the general nature of simpleHTTP is just what you'd expect
from a web application container. First you figure out which function is
going to process your request, process the request to generate a response,
then return that response to the client. The web application container is
started with simpleHTTP, which takes a configuration and a
response-building structure (ServerPartT which I'll return to in a
moment), picks the first handler that is willing to accept the request, and
passes the request in to the handler. A simple hello world style Happstack
simpleHTTP server looks like:

main = simpleHTTP nullConf $ return "Hello World!"

simpleHTTP nullConf creates a HTTP server on port 8000.
return "Hello World!" creates a ServerPartT that just returns that text.

ServerPartT is the basic response builder. As you might expect, it's a
container for a function that takes a Request and converts it to a response
suitable for sending back to the server. Most of the time though you don't
even need to worry about that as ServerPartT hides almost all the machinery
for building your response by exposing a few type classes.

ServerPartT is a pretty rich monad. You can interact with your request,
your response, do IO, etc. Here is a do block that validates basic
authentication. It takes a realm name as a string, a Map of username to
password and a server part to run if authentication fails.

basicAuth acts like a guard, and only produces a response when
authentication fails. So put it before any ServerPartT for which you want to demand
authentication, in any collection of ServerPartTs.

Documentation

SimpleHTTP

Use the built-in web-server to serve requests according to a
ServerPartT. Use msum to pick the first handler from a list of
handlers that doesn't call mzero. This function always binds o
IPv4 ports until Network module is fixed to support IPv6 in a
portable way. Use simpleHTTPWithSocket with custom socket if you
want different behaviour.

A combination of simpleHTTP'' and mapServerPartT. See
mapServerPartT for a discussion of the first argument of this
function. This function always binds to IPv4 ports until Network
module is fixed to support IPv6 in a portable way. Use
simpleHTTPWithSocket with custom socket if you want different
behaviour.

Used to manipulate the containing monad. Very useful when embedding a
monad into a ServerPartT, since simpleHTTP requires a ServerPartT IO a.
Refer to WebT for an explanation of the structure of the monad.

Finally, the first element of the pair is either Left Response or Right a.

Another way of looking at all these pieces is from the behaviors
they control. The Maybe controls the mzero behavior. Set
(Endo f) comes from the setFilter behavior. Likewise, Append
(Endo f) is from composeFilter. Left Response is what you
get when you call finishWith and Right a is the normal exit.

An example case statement looks like:

ex1 webt = do
val <- ununWebT webt
case val of
Nothing -> Nothing -- this is the interior value when mzero was used
Just (Left r, f) -> Just (Left r, f) -- r is the value that was passed into "finishWith"
-- f is our filter function
Just (Right a, f) -> Just (Right a, f) -- a is our normal monadic value
-- f is still our filter function

Type Classes

This class is used by path to parse a path component into a value.
At present, the instances for number types (Int, Float, etc) just
call readM. The instance for String however, just passes the
path component straight through. This is so that you can read a
path component which looks like this as a String:

Yes, this is exactly like ReaderT with new names.
Why you ask? Because ServerT can lift up a ReaderT.
If you did that, it would shadow ServerT's behavior
as a ReaderT, thus meaning if you lifted the ReaderT
you could no longer modify the Request. This way
you can add a ReaderT to your monad stack without
any trouble.

Manipulating responses

A set of functions for manipulating filters. A ServerPartT implements
FilterMonadResponse so these methods are the fundamental ways of
manipulating the response object, especially before you've converted your
monadic value to a Response.

A control structure.
It ends the computation and returns the Response you passed into it
immediately. This provides an alternate escape route. In particular
it has a monadic value of any type. And unless you call setFilter id
first your response filters will be applied normally.

Extremely useful when you're deep inside a monad and decide that you
want to return a completely different content type, since it doesn't
force you to convert all your return types to Response early just to
accomodate this.

Honor an if-modified-since header in a Request.
If the Request includes the if-modified-since header and the
Response has not been modified, then return 304 (Not Modified),
otherwise return the Response.

proxying

proxyServe is for creating ServerPartTs that proxy.
The sole argument [String] is a list of allowed domains for
proxying. This matches the domain part of the request
and the wildcard * can be used. E.g.

"*" to match anything.

"*.example.com" to match anything under example.com

"example.com" to match just example.com

TODO: annoyingly enough, this method eventually calls escape, so
any headers you set won't be used, and the computation immediatly ends.

This is a for use with 'mapServerPartT\'' It it unwraps the
interior monad for use with simpleHTTP. If you have a
ServerPartT (ErrorT e m) a, this will convert that monad into a
ServerPartT m a. Used with 'mapServerPartT\'' to allow
throwError and catchError inside your monad. Eg.

If the external application returns 0, the original response is
returned unmodified. If the external application returns non-zero, a Response
containing the error messages and original response body is
returned instead.

This function also takes a predicate filter which is applied to the
content-type of the response. The filter will only be applied if
the predicate returns true.

NOTE: This function requirse the use of -threaded to avoid blocking.
However, you probably need that for Happstack anyway.