HTTP_SERVLET_TMPL(3)

NAME
http_servlet_tmpl - HTTP servlet for template files

LIBRARY
PDEL Library (libpdel, -lpdel)

SYNOPSIS
#include <sys/types.h>
#include <stdio.h>
#include <netinet/in.h>
#include <openssl/ssl.h>
#include <pdel/tmpl/tmpl.h>
#include <pdel/http/http_defs.h>
#include <pdel/http/http_server.h>
#include <pdel/http/servlet/tmpl.h>
struct http_servlet *
http_servlet_tmpl_create(struct http_servlet_tmpl_info *info);
extern tmpl_handler_t http_servlet_tmpl_func_query;
extern tmpl_handler_t http_servlet_tmpl_func_query_exists;
extern tmpl_handler_t http_servlet_tmpl_func_query_string;
extern tmpl_handler_t http_servlet_tmpl_func_get_header;
extern tmpl_handler_t http_servlet_tmpl_func_set_header;
extern tmpl_handler_t http_servlet_tmpl_func_remove_header;
extern tmpl_handler_t http_servlet_tmpl_func_redirect;
extern tmpl_handler_t http_servlet_tmpl_func_unbuffer;

DESCRIPTION
http_servlet_tmpl_create() creates a new servlet that serves HTTP requests by executing a tmpl(3) template file. The output of the template is sent as the body of the HTTP response. By default, the template output is buffered in memory and after template execution has finished the HTTP response is sent.

info is a pointer to a struct http_servlet_tmpl_info, which contains a struct http_servlet_tmpl_tinfo:

    /* Function to free user 'arg' */
    typedef void	http_servlet_tmpl_free_t(void *arg);
    /* Information required by tmpl(3) library */
    struct http_servlet_tmpl_tinfo {
        int                      flags;          /* tmpl_execute() flags */
        const char               *mtype;         /* tmpl string mem type */
        tmpl_handler_t           *handler;       /* tmpl function handler */
        tmpl_errfmtr_t           *errfmtr;       /* tmpl error formatter */
        void                     *arg;           /* opaque argument */
        http_servlet_tmpl_free_t *freer;         /* destructor for 'arg' */
    };
    /* Information required for the tmpl servlet */
    struct http_servlet_tmpl_info {
        const char               *path;          /* template file */
        const char               *mime_type;     /* default mime type */
        const char               *mime_encoding; /* default mime encoding */
        http_logger_t            *logger;        /* http error logger */
        struct http_servlet_tmpl_tinfo   tinfo;  /* info for tmpl(3) */
    };

path is the pathname of the template file. The file is parsed when the servlet is first executed, and the parsed template is cached for use by subsequent servlet invocations. If the file modification timestamp changes, the file is parsed again.

mime_type and mime_encoding specify the default MIME type and encoding for the template output. The template itself may change the MIME type however. If mime_type is NULL, "text/html; charset=iso-8859-1" is used.

The logger is a logging function whose type is defined in http_server(3).

The tinfo structure provides information required by the tmpl(3) library in order to create and execute the template. The mtype, handler, and errfmtr fields are passed to tmpl_ctx_create(); The flags field is passed to tmpl_execute().

The arg field is copied into a struct http_servlet_tmpl_arg, and a pointer to this structure is used as the user cookie field arg passed to tmpl_ctx_create():

    struct http_servlet_tmpl_arg {
        void                     *arg;   /* arg from 'tinfo' */
        struct http_request      *req;   /* http request */
        struct http_response     *resp;  /* http response */
    };

Therefore, by casting the pointer returned from tmpl_ctx_get_arg() to a struct http_servlet_tmpl_arg *, handler() can access both the original arg as well as the HTTP request and response objects.

For an HTTP POST with MIME type “application/x-www-form-urlencoded” the servlet will automatically read in the URL-encoded name, value pairs, making them accessible via http_request_get_value(3) (see also http_servlet_tmpl_func_query() below).

When the servlet is destroyed, if the freer field is not NULL, it is invoked to release resources associated with arg.

  Built-in template functions
The http_servlet_tmpl servlet includes the following built-in tmpl(3) user functions. These functions all assume the tmpl(3) user cookie is a struct http_servlet_tmpl_arg *.

http_servlet_tmpl_func_query()
    This function takes exactly one argument, which is the name of a field in an HTML form, and returns the value of that field as submitted by the remote client. This function works for both GET and POST form submissions. If no such field was submitted, the empty string is returned.

http_servlet_tmpl_func_query_exists()
    This function takes exactly one argument, which is the name of a field in an HTML form, and returns "1" or "0" depending on whether a field having that name was submitted by the client.

http_servlet_tmpl_func_query_string()
    Takes zero arguments. Returns the HTTP query string.

http_servlet_tmpl_func_get_header()
    Takes one argument, and returns the contents of the HTTP header having that name.

http_servlet_tmpl_func_set_header()
    Takes two arguments, the name of an HTTP header and its value, and sets the corresponding HTTP response header. This function has no effect if the headers have already been sent.

http_servlet_tmpl_func_remove_header()
    Takes one argument, the name of an HTTP header, and removes the corresponding HTTP response header. This function has no effect if the headers have already been sent.

http_servlet_tmpl_func_redirect()
    Takes one argument, which must be a valid URL. Forces an HTTP redirect response to the URL. This function only works if the servlet has not created any output yet.

http_servlet_tmpl_func_unbuffer()
    Takes zero arguments. Unbuffers the servlet output, so that the output is written directly to the network instead of first into a memory buffer. This is done by calling http_response_send_headers(3) with a non-zero unbuffer argument. This function should be called in servlets that produce a high volume of output. You can't modify the HTTP response headers once this has been called.

The http_servlet_tmpl servlet by default buffers the entire template output to facilitate HTTP keep-alive. For templates that generate voluminous output, this could consume excessive memory. The solution is to implement a template function using http_servlet_tmpl_func_unbuffer() and invoke this function within those templates.

IMPLEMENTATION NOTES
Multiple instances of the same http_servlet_tmpl servlet may be executing at the same time. Therefore, any user-supplied template functions called must be thread-safe.

Since it's running as a servlet, the thread executing handler() and errfmtr() may be canceled at any cancellation point. Therefore, these functions should be written so as to not leak resources if this happens.

RETURN VALUES
On failure, http_servlet_tmpl_create() returns NULL and sets errno to an appropriate value.

The built-in tmpl(3) user functions return NULL with errno set to EINVAL if the wrong number of arguments is passed. They may also return NULL with errno set as a result of other system errors.

SEE ALSO
http_request(3), http_response(3), http_server(3), http_servlet(3), libpdel(3), tmpl(3)

HISTORY
The PDEL library was developed at Packet Design, LLC. http://www.packetdesign.com/

AUTHORS
Archie Cobbs <archie@freebsd.org>