
HTTP-module HOWTO.

Introduction:

every HTTP trusted dynamic module defines a 'tcapi template', which
defines entry points and module properties. Note that TUX's in-kernel
dynamic API is ment to be small and simple. Complex and slow requests
should be handled in user-space.

-----------------------------------------------------------------------

Currently defined fields in the TUX 1.0 module template are:

struct tcapi_template_s {
        char *vfs_name;
        char *version;
        int (*query) (http_req_t *req);
        int (*send_reply) (http_req_t *req);
        int (*log) (http_req_t *req, char *log_buffer);
        void (*finish) (http_req_t *req);
};

-----------------------------------------------------------------------

HTTP-module vfs_name:

        char *vfs_name;

the VFS name to which the module is mapped. Eg. if vfs_name is "httpapi",
then http://server/httpapi?filename requests will be directed to this
module.

-----------------------------------------------------------------------

HTTP-module version:

        char *version;

the TUX version string of the module. Current TUX version is "TUX 1.0".
Future API changes might result in older, incompatible modules being not
loaded. Future APIs might support older APIs as well.

-----------------------------------------------------------------------

TUX-module query():

        int (*query) (http_req_t *req);

callback which happens after a new request arrives which involves this
module. 'req' is the HTTP request descriptor.

RETURN VALUES:

         0: request parsed, continue with output

        -1: input data incomplete, put socket into idle state

        -2: request finished, flush now

         (all other return values undefined)

-----------------------------------------------------------------------

HTTP-module send_reply():

        int (*send_reply) (http_req_t *req);

if defined then replies are generated by the module. Simpler modules
which have this callback set to NULL will just fill out req->filename
and req->urlc, which file will then be transmitted by TUX.

RETURN VALUES:

         positive values: bytes transmitted
                      -3: redirect request to secondary server
         everything else: 0 bytes transmitted, flush request now

-----------------------------------------------------------------------

HTTP-module log():

        int (*log) (http_req_t *req, char *log_buffer);

if defined then the module can create a custom log entry, and returns
the log entry's size. log_buffer is maximum MAX_LOG_ENTRY long.

RETURN VALUES:

        length of log entry

-----------------------------------------------------------------------

HTTP-module finish():

        void (*finish) (http_req_t *req);

if defined then after closing the connection TUX calls this callback.
Modules can free potential per-request private data structures this way.

RETURN VALUES:

        none

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------

TUX helper functions and object descriptors available to HTTP modules,
all these functions have a http_ prefix, to avoid namespace pollution.

-----------------------------------------------------------------------

http_req_t *;

descriptor of a client connection. Defined fields are:


char * query; // the string part of the URI after the question mark.
urlc_t *urlc; // HTTP object belonging to this connection



-----------------------------------------------------------------------

struct http_file *;

opaque file descriptor similar to user-space 'FILE *'. Fields are
undefined for modules and are not needed to use the pointer.


-----------------------------------------------------------------------

struct http_page *;

opaque page descriptor used for mapping pages. Fields are undefined
for modules and are not needed to use the pointer.

-----------------------------------------------------------------------

struct http_direntry *;

opaque type describing directory entries. Fields are undefined
for modules and are not needed to use the pointer.

-----------------------------------------------------------------------

extern struct http_nameidata docroot;

document root 'lookup context'. It is automatically provided for all
HTTP modules, lookups are always relative to a lookup context.

-----------------------------------------------------------------------

struct http_mutex *;

HTTP_DECLARE_MUTEX(name)

macro to declare a mutex. The mutex can be referred to by 'name'. The
type of the mutex is opaque.

-----------------------------------------------------------------------

urlc_t *;

TUX URL object descriptor. Defined fields are:

int filelen; // length of object
tcapi_t *tcapi; // HTTP module this object belongs to
csumc_t *csumc; // checksum-object
int body_len; // length of the body of the object
threadinfo_t *ti; // HTTP thread descriptor
char *reply_cookie; // max 256 bytes reply cookie buffer
int bytes_sent; // nr of bytes sent to client
int keep_alive; // wether the connection should be kept after the request
char *cookies; // input cookies
int cookies_len; // length of input cookie field
void *private; // opaque pointer free to be used by modules
char *post_data; // input POST data
http_method_t method; // input HTTP method
char *filename; // HTTP object name
int filename_len; // length of HTTP object name string
int http_status; // reply message status towards client
int body_len; // body length of HTTP reply message

-----------------------------------------------------------------------

typedef enum http_methods {
        METHOD_NONE,
        METHOD_GET,
        METHOD_HEAD,
        METHOD_POST,
        METHOD_PUT
} http_method_t;

-----------------------------------------------------------------------

threadinfo_t *;

descriptor for a TUX thread. Defined fields are:

char *output_buffer;

output buffer belonging to this thread.

-----------------------------------------------------------------------

csumc_t *;

HTTP checksum-object descriptor.

-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------

extern void * http_malloc (int size, int id);

mallocs a new buffer of size 'size', with an allocation ID 'id'. Ids can
be used to debug memory leaks - the allocation and freeing ID must be
the same, and must be under MAX_ALLOC_ID, no other restrictions. TUX 
provides runtime statistics about various ID allocation patterns and
allocation balance. This function can potentially block, so make careful
use of it.

RETURN VALUES:

         the allocated buffer

-----------------------------------------------------------------------

extern void http_free (void *ptr, int id);

free a http_malloc()-ed temporary buffer.


RETURN VALUES:

        none

-----------------------------------------------------------------------

int http_exec_process (char *command, char **argv, char **envp, int *unused1, exec_param_t *unused2, int wait);

starts and exec()s a new user-space process, pointed to by 'command', with
argument array of 'argv', environment array 'envp'. If 'wait' is 1 then TUX
waits for the process to exit, otherwise it's running asynchronously.

RETURN VALUES:

        0 on success
        non-zero on failure

-----------------------------------------------------------------------

http_open_file():

struct http_file * http_open_file (char *filename, int mode);

opens a file descriptor pointed to by 'filename', with file mode 'mode'.

RETURN VALUES:

        the opened file descriptor or NULL on failure

-----------------------------------------------------------------------

int http_read (urlc_t *urlc, char *buf)

read a full HTTP object into a sufficiently sized temporary buffer.

RETURN VALUES:

        0 on success
        non-zero on failure

-----------------------------------------------------------------------

int http_send_client (http_req_t *req, char *buf, int len, int push)

sends a given buffer's contents to the client as-is. If 'push' is 1
then the content is 'pushed' to the client.

RETURN VALUES:

        >=0 bytes sent
        <0 on error

-----------------------------------------------------------------------

int http_send_file (http_req_t *req, int include_header, int push)

sends a given HTTP object to the client as a reply. include_headers
specifies wether TUX should construct a header. The 'push' argument
specifies wether the TCP data should be pushed to the client.

RETURN VALUES:

        0: success
       -1: failure

-----------------------------------------------------------------------

struct http_direntry * http_lookup_direntry (char *pathname,
                struct http_nameidata *docroot, int flags)

looks up a given file identified by pathname, starting at docroot, and
returns a direntry pointer to it. This pointer can later on be used to
do file operations.

RETURN VALUES:

        the looked up directory entry on success
        non-zero http_direntry_error() on failure

-----------------------------------------------------------------------

int http_direntry_error (struct http_direntry * dentry)

converts the error code embedded in the dentry pointer to an integer
error code.

RETURN VALUES:

        0: the dentry is valid
        nonzero: the dentry lookup had an error

-----------------------------------------------------------------------

int http_file_size (struct http_file *file)

returns the length of the file.

-----------------------------------------------------------------------

unsigned int http_mtime (struct http_file *file)

returns the last modification time of the file, in Unix time.

-----------------------------------------------------------------------

int http_write_file (struct http_file *file, char *buf, int len)

writes a given buffer's contents into the file, and updates the file
position.

RETURN VALUES:

        >0 bytes written
        <=0 on error

-----------------------------------------------------------------------

int http_read_file (struct http_file *file, char *buf, int len)

reads a file (from the current position) into a given buffer and
updates the file position.

RETURN VALUES:

        >0 bytes read
        <=0 on error

-----------------------------------------------------------------------

void http_close_file (struct http_file *file)

closes a file descriptor. (usage of the file pointer after closing the
file may result in undefined behavior.)

-----------------------------------------------------------------------

struct http_page * http_mmap_page (struct http_file *file, char *buf,
                                unsigned int offset)

mmaps a given page at a given offset from a given file into the
process's address space.

RETURN VALUES:

        NULL: error
        non-NULL: pointer to the page structure

-----------------------------------------------------------------------

int http_miss_req (struct http_req_t *req)

the module signals towards TUX that the object described via
req->filename should be constructed by TUX.

RETURN VALUES:

         0: request parsed, continue with output

        -1: input data incomplete, put socket into idle state

        -2: request finished, flush now

        (ie. can be used as a ->query() return value.)

-----------------------------------------------------------------------

void http_sleep (int seconds)

suspends execution for a given number of seconds.

-----------------------------------------------------------------------

void http_down (struct http_mutex *mutex)

'down' operation on the mutex (enters critical section). Suspends
execution if the critical section is already entered.

-----------------------------------------------------------------------

void http_up (struct http_mutex *mutex)

'up' operation on the mutex. (release critical section)

-----------------------------------------------------------------------

unsigned int http_client_addr (http_req_t *req)

retrieve the IP address of the client connection 'req'.

RETURN VALUES:

        the client IP address in host-endian format

-----------------------------------------------------------------------

