network-minihttp-0.1: A very minimal webserver




This module contains functions for writing webservers. These servers process requests in a state monad pipeline and several useful actions are provided here in. See examples/fileserver.hs for an example of how to use this module.



type Source = IO SourceResultSource

A source is a stream of data, like a lazy data structure, but without some of the dangers that such entail. A source returns a SourceResult each time you evaluate it.

data SourceResult Source



error - please don't read this source again


end of data

SourceData ByteString

some data


bsSource :: ByteString -> IO SourceSource

Construct a source from a ByteString



:: (Int64, Int64)

the first and last byte to include

-> Handle

the handle to read from

-> IO Source 

Construct a source from a Handle

nullSource :: SourceSource

A source with no data (e.g. devnull)

The processing monad

type WebMonad = StateT WebState IOSource

The processing monad

data WebState Source

Processing a request involve running a number of actions in a StateT monad where the state for that monad is this record. This contains both a Source and a Handle element. Often something will fill in the Handle and expect later processing to convert it to a Source. Somehow, you have to end up with a Source, however.

getRequest :: WebMonad RequestSource

Return the request

getReply :: WebMonad ReplySource

Return the current reply

setReply :: Int -> WebMonad ()Source

Set the current reply to be a reply with the given status code, the default message for that status code, an empty body and an empty set of headers.

setHeader :: (Headers -> Headers) -> WebMonad ()Source

Set a header in the current reply. Because of the way records work, you use this function like this:

 setHeader $ \h -> h { httpSomeHeader = Just value }

WebMonad actions

handleConditionalRequest :: WebMonad ()Source

This handles the If-*Matches and If-*Modified conditional headers. It takes its information from the Last-Modified and ETag headers of the current reply. Note that, for the purposes of ETag matching, a reply without an ETag header is considered not to exist from the point of view of, say, If-Matches: *.

handleHandleToSource :: WebMonad ()Source

If the current state includes a Handle, this turns it into a Source

handleRangeRequests :: WebMonad ()Source

This handles Range requests and also translates from Handles to Sources. If the WebMonad has a Handle at this point, then we can construct sources from any subrange of the file. (We also assume that Content-Length is correctly set.)

See RFC 2616, section 14.35

handleDecoration :: WebMonad ()Source

At the moment, this just adds the header Server: Network.MiniHTTP



:: FilePath

the root of the filesystem to serve from

-> WebMonad () 

This is a very simple handler which deals with requests by returning the requested file from the filesystem. It sets a Handle in the state and sets the Content-Type, Content-Length and Last-Modified headers

Running the server



:: Int

the port number to listen on

-> WebMonad ()

the processing action

-> IO ()