dombey(8) BSD System Manager's Manual dombey(8)NAME
dombey — Generic SCGI Application Server Library
SYNOPSIS
#include <dombeyevents.h>
-I/usr/local/include -L/usr/local/lib -ldombeyevents -lcrypto
DESCRIPTION
The Libdombey package provides 3 generic SCGI application servers. The
libraries handle network and concurrrency tasks. You supply code to ser‐
vice connections. Separate libraries provide multi-process, multi-
threaded, and event-driven servers. All 3 libraries service TCP or UNIX-
domain connections. This manual describes the event-driven library. The
multi-process and multi-threaded libraries are described in the "lib‐
dombey" manual.
USAGE
The library provides your server's "main" function. You define 2 func‐
tions to match the following prototypes.
void scgi_init_func();
int scgi_request_handler( void *, int );
Do not define any other global symbol beginning with the five characters
´scgi_' because the library reserves that namespace.
SCGI_INIT_FUNC()
In scgi_init_func(), perform the initialization tasks your server needs
to do once at server start-up before any workers are created.
The library calls scgi_init_func():
· after changing to the directory specified by the -r command line
option.
· before attempting to change the server's user and group to the values
specified by the command line options. If the server starts as root,
scgi_init_func() will execute as root.
· before the server becomes a daemon and starts listening for connec‐
tions. The standard streams are connected to the terminal from which
the server was started. Error and informative messages should be
sent to the terminal.
SCGI_SET_NAME()
To set the server's name, call scgi_set_name() inside scgi_init_func().
void scgi_set_name( char * );
If not set, the server's name defaults to "dombey". The server's name is
used in two ways.
· When a server is running, stderr is connected to /dev/null. Errors
are reported with syslog(3). The library calls openlog() with the
server's name to ensure log entries are identified by the server's
name.
· The server's pidfile is written to /var/run/ if the server is started
as root. The filename is the server's name with ".pid" appended to
it. This file is used by rc.d scripts to stop the server. A sample
script is included in the dombey distribution.
SCGI_SET_PERIODIC()
You can install a function for the library to invoke periodically with:
void scgi_set_periodic( void (*)(), int );
The function pointed to by first argument is called when the number of
seconds specified by the second argument have elapsed and then again
repeatedly when that number of seconds has elapsed since the last call.
SCGI_REQUEST_HANDLER()
The library calls scgi_request_handler() (possibly multiple times) to
service each connection.
int scgi_request_handler( void *, int );
The opaque pointer argument identifies the current connection. You pass
the pointer to other library functions as necessary.
The second argument is set to 0 the first time the function is invoked
for a connection. On successive invocations, the argument is set to the
return value of scgi_request_handler() on its previous invocation.
Servers are blocked while scgi_request_handler() runs.
Queue response data for the client with scgi_write_conn().
· To abort a response, return a value less than 0. Queued data is dis‐
carded, and the connection is closed.
· To indicate that the complete response has been queued for the
client, return 0.
· To indicate that a partial response has been queued for the client,
return 1. scgi_request_handler() is called again when the queued
data has been sent to the client.
· To indicate that you want to be notified when a descriptor becomes
readable, return the descriptor. scgi_request_handler() is called
when the descriptor is readable. The event is a oneshot event. Con‐
tinue to return the descriptor until you are no longer interested in
it.
SCGI_WRITE_CONN()
To queue response data for the client, pass a character pointer to
scgi_write_conn().
int scgi_write_conn( void *conn, char *data );
The function's first argument is the opaque pointer passed to
scgi_request_handler(). The function's second argument is a character
pointer to the data, which must be zero-terminated. The library copies
the data to an internal buffer.
scgi_write_conn() does not write the data but queues it for delivery.
When the socket is writeable, the library will send up to one buffer of
queued data to the client, in discrete writes, until the outgoing queue
is consumed. Writes are multiplexed with events on other connections.
To ensure smooth multiplexing, queue large data in chunks with separate
calls to scgi_write_conn().
scgi_write_conn() returns:
· -1 if the opaque pointer does not reference a connection.
· -2 If the server cannot enlarge the queue.
· 0 on success.
If the function returns -2, the server cannot allocate memory. There is
no point continuing to service this connection. Perform any clean up
operations necessary, and then return -1 from scgi_request_handler() to
drop the connection.
ACCESS TO REQUEST DATA
Dombey recognizes requests that use both GET and POST parameters in the
same request. Inside scgi_request_handler(), use the following library
functions to access the environment, the parameters, and cookies. The
first argument to all of these functions is the opaque pointer passed to
scgi_request_handler().
char *scgi_get_env( void *conn, char * );
char **scgi_get_envs( void *conn );
char *scgi_get_param( void *conn, char * );
char **scgi_get_params( void *conn );
char *scgi_get_cookie( void *conn, char * );
char **scgi_get_cookies( void *conn );
scgi_get_env() retrieves the value of one particular SCGI environment
variable. Pass the name of the variable as argument, and the function
returns that variable's value or NULL if the variable is not defined.
scgi_get_envs() returns an array of character pointers listing all the
SCGI environment variables and their values with each variable name fol‐
lowed by its value. The array is always terminated with a NULL pointer.
scgi_get_param() retrieves the decoded value of one particular SCGI
parameter. Pass the name of the parameter as argument, and the function
returns that parameter's value or NULL if the parameter is not defined.
scgi_get_params() returns an array of character pointers listing all the
SCGI parameters and their values with each parameter name followed by its
value. The array is always terminated by a NULL pointer.
scgi_get_cookie() retrieves the value of one named cookie defined in the
the HTTP_COOKIE environment variable. Pass the name of the desired
cookie as argument, and the function returns that cookie's value or NULL
if the cookie is not set.
scgi_get_cookies() returns an array of character pointers listing all the
cookies defined in HTTP_COOKIE with each cookie name followed by its
value. The array is always terminated by a NULL pointer.
ACCESS TO UPLOADED FILES
Inside scgi_request_handler(), use the following library functions to
access files uploaded by the client.
char **scgi_get_file( void *conn, char * );
char **scgi_get_next_file( void *conn, char **, char * );
char **scgi_get_files( void *conn );
When processing a POSTed multipart/form-data document, elements of that
document with a "filename" parameter are stored in files in the directory
specified by the -r option. Files are created with mkstemp(). All files
are unlink()ed by the library when scgi_request_handler() returns. If
you want the files to persist, hard link new names to them.
scgi_get_file() retrieves the files array entries associated with a par‐
ticular SCGI parameter. Pass the name of the parameter as argument, and
the function returns a pointer to character pointer. Index the returned
pointer with 0 to access the client filename. Index the pointer with 1
to access the local filename. Index the pointer with 2 to access the key
used to encrypt the file. Index the pointer with 3 to access the iv used
to encrypt the file. The last two values are NULL if the file is not
encrypted.
If the user did not select a file to upload for a particular file input,
the entry for that input is placed in the params array, and the parame‐
ter's value is the empty string. If scgi_get_file() returns NULL for an
expected form element, then call scgi_get_param(). If that function
returns the empty string, the user did not select a file to upload. If
that function returns NULL, the named input was not part of the originat‐
ing form.
For file inputs that have the multiple attribute set, dombey creates more
than one entry in the files array with the same name. Calling
scgi_get_file() will only return the data for the first file. To access
the next file, call scgi_get_next_file() with the address returned by
scgi_get_file() and the name of the parameter. To access the remainder
of the files, call scgi_get_next_file() with the address it returned on
its previous invocation and the name of the parameter. When there are no
more entries of the same name, the function returns NULL.
scgi_get_files() returns a NULL-terminated array of character pointers
listing the parameters of all the files uploaded by the current request.
The array consists of groups of 5 ajacent entries for each uploaded file.
The first entry of each group is the "name" parameter (the name of the
input in the form from which the file was posted). The second entry is
the "filename" parameter (the filename on the client machine). The third
entry is the filename on the local filesystem where the file has been
stored. The fourth entry is the key used to encrypt the file or NULL if
the file is not encrypted. The fifth entry is the initialization vector
used to encrypt the file or NULL if the file is not encrypted.
SCGI_ENCRYPT_FILES()
Dombey can encrypt uploaded files with the AES-256 cipher in CBC mode. A
random key and initialization vector are generated for each encrypted
file. Files are encrypted on the fly with no data reaching storage unen‐
crypted. To enable encryption, call the following function with the
argument set to a non-zero value. To disable encryption, set the argu‐
ment to 0.
void scgi_encrypt_files( int on );
SCGI_READ_ENCRYPTED()
Read encrypted files with the following function.
char *scgi_read_encrypted( void *conn, int fd, int *len, char *key, char *iv );
First, call the function with fd set to -2 to establish a cipher context.
The len argument must point to an int to hold status codes. The key and
iv arguments must point to the key and iv values for the file.
Next, open the filename with open(2), and call scgi_read_encrypted() with
fd set to the open file descriptor. The function returns a pointer to a
dynamically allocated array of character data. The length of the data is
placed into len. Free the data when you are finished with it. Upon EOF,
the function returns NULL with len set to 0. Upon failure, the function
returns NULL with len set to -1. An error message is logged with sys‐
log(3). The cipher context is automatically cleaned when an error occurs
or when EOF is read.
The key and iv arguments can be NULL after the cipher context has been
established.
If you do not read a file to EOF, call the function with fd set to -1 to
clean the cipher context. Calling the function with fd set to -2 also
cleans any previously established context.
DO MIX CALLS OF scgi_read_encrypted() TO DIFFERENT OPEN FILES BECAUSE IT
MAINTAINS ONLY ONE CIPHER CONTEXT AT A TIME.
CONVENIENCE FUNCTIONS
Use these convenience functions to encode a string in x-www-form-urlen‐
coding and to escape <, >, and & with their HTML entities.
char *scgi_form_encode( char * );
char *scgi_html_escape( char * );
Both functions return dynamically allocated strings that must be freed by
the caller. These functions will return NULL if memory cannot be allo‐
cated.
ACCESS TO CONFIGURATION VARIABLES
You can examine the following configuration variables from your code, but
you must not modify them. See the CONFIGURATION section for more infor‐
mation.
char *scgi_config_file;
char *scgi_root_dir;
char *scgi_interface;
char *scgi_port;
char *scgi_user;
char *scgi_group;
scgi_config_file points to the value passed to the -f option. Defaults
to NULL.
scgi_root_dir points to the value passed to the -r option. Must be
explicitly set.
scgi_interface points to the value passed to the -i option. Defaults
to "".
scgi_port points to the value passed as argument to the -p
option. Defaults to "4000".
scgi_user points to the value passed as argument to the -u
option. Defaults to "nobody".
scgi_group points to the value passed as argument to the -g
option. Defaults to "nobody".
SIGNALS
Upon receipt of SIGBUS or SIGSEGV, the library restarts the server with a
call to execv(3). If you want to do something else, install your own
handler.
If your server starts as root and changes user and group, the library
will be unable to restart if your server is not executable by the user or
group.
The library will be unable to perform the operations that require root
privileges after restart unless you turn on the setuid bit of the server
(chmod u=+s).
RESOURCE LIMITS
Dombey stores the information for 25 SCGI environment variables, 25 SCGI
parameters and 25 cookies. More items provided in a client request are
ignored.
CONFIGURATION
Dombey writes its pidfile into /var/run/ if it is started as root. Stop
the library with SIGTERM. Dombey does graceful stops. Servers with
established connections exit after all established connections close. If
you want to kill a server outright, send it a SIGKILL. A sample control
script is provided in the dombey distribution. To use the script,
replace all occurrences of "dombey" with the value you pass to
scgi_set_name(). The script must be named as the value you passed to
scgi_set_name() and installed in /usr/local/etc/rc.d.
Two variables must be added to /etc/rc.conf to use the script. Substi‐
tute your server's name for "dombey":
dombey_enable="YES"
dombey_flags="-u www -g www -r /usr/local/dombey"
If the "enable" variable is set to "YES", the server is started at system
start. Use the following rc commands.
/usr/local/etc/rc.d/dombey start
/usr/local/etc/rc.d/dombey stop
/usr/local/etc/rc.d/dombey restart
/usr/local/etc/rc.d/dombey status
If you do not want the server started on system start, then set
dombey_enable="NO"
and use the following commands:
/usr/local/etc/rc.d/dombey forcestart
/usr/local/etc/rc.d/dombey forcestop
/usr/local/etc/rc.d/dombey forcerestart
/usr/local/etc/rc.d/dombey forcestatus
COMMAND-LINE OPTIONS
The following command-line options are recognized by dombey servers. The
-r option is mandatory.
-r Use the -r option to specify the absolute path to the server root
directory. Dombey chdir(2)s here.
-l By default, dombey listens on all TCP interfaces it can find capable
of IPv4 or IPv6. The -l option instructs the library to listen on a
UNIX-domain socket instead. Specify the path to the socket as argu‐
ment. The server creates the socket when it starts, unlinking it
first if it already exists in the filesystem. The owner and group of
the socket are changed to the values of the -u and -g options. The
permisssions of the socket are set to srwxrwx---.
-p The -p option specifies the port to listen on. This defaults to
4000. To bind to a port lower than 1024, the server must be started
as root.
-i By default, dombey accepts connections on all interfaces it can find
capable of IPv4 or IPv6. The -i option limits dombey to accepting
connections from a specified interface. Pass the IP address of the
desired interface as argument.
-q The -q option specifies the backlog of client connections queued by
the OS kernel for the server to subsequently service. This value
defaults to 1024. The kernel actually uses a queue of 1.5 times the
size of the specified value. Connections arriving when the queue is
full are dropped by the kernel. Libdombey does not le you set this
value to less than 1024.
-u
-g The -u and the -g options specify the user and group of the server.
Both values default to "nobody". To change user, the server must be
started as root.
Dombey restarts servers on receipt of SIGSEGV or SIGBUS.
If your server starts as root and changes user and group, the library
will be unable to restart if your server is not executable by the
user or group.
The library will be unable to perform the operations that require
root privileges after restart unless you turn on the setuid bit of
the server (chmod +s).
-e The -e option specifies the maximum acceptable size in bytes of files
uploaded in multipart/form-data POSTS. This value defaults to
2000000. Connections attempting to upload a file larger than this
are dropped without explanation.
-b The -b option sets the maximum size in bytes of request bodies for
application/x-www-form-urlencoded POSTS. This value defaults to
10000. Connections with CONTENT_LENGTH set to a value greater than
the maximum configured request body size are dropped without explana‐
tion.
-x The -x option prevents dombey from becoming a daemon or writing its
pidfile to /var/run/. Stderr is connected to the terminal so that
diagnostic output should be sent to the terminal.
-f The -f option specifies a filename as argument. Dombey assigns it to
the global character pointer named scgi_config_file. This enables
the code in scgi_init_func() and scgi_worker_init_func() to read a
configuration file.
AUTHORS
James Bailie ⟨jimmy@mammothcheese.ca⟩
http://www.mammothcheese.ca
Nov 13, 2015