http_servlet_tmpl
—
HTTP servlet for template files
PDEL Library (libpdel, -lpdel)
#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;
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.
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.
- Takes one argument, and returns the contents of the HTTP header having
that name.
- 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.
- 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.
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.
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.
The PDEL library was developed at Packet Design, LLC.
http://www.packetdesign.com/
Archie Cobbs
⟨archie@freebsd.org⟩