libdombey(8)            FreeBSD System Manager's Manual           libdombey(8)

NAME
     libdombey -- SCGI Application Server Library

SYNOPSIS
     #include<dombey.h>
     -I/usr/local/include -L/usr/local/lib -ldombey

DESCRIPTION
     libdombey implements an SCGI application server which is incapable of
     generating responses on its own.  The programmer links custom code
     against the library to create a complete multi-process server.

     The library supplies the server's "main" function, and performs all the
     network and process management functions of the server.  One master
     process forks and kills child processes, as needed, according to demand,
     once per second.  The child processes accept and service client connec-
     tions.  The master process does not.

     libdombey may be made to listen for connections on TCP or UNIX-domain
     sockets.

USAGE
     The programmer must define in his or her code three functions which are
     prototyped in dombey.h:

     void scgi_init_func();
     void scgi_child_init_func();
     void scgi_request_handler();

     In scgi_init_func(), or in functions which it calls, the programmer must
     perform the initialization tasks his or her server needs to do, once at
     server start-up, before any child processes are forked.  scgi_init_func()
     is called precisely once by libdombey before the server attempts to
     change user and group to "nobody" or to the values specified by the -u
     and/or -g command-line options.  Therefore, if the server starts as root,
     scgi_init_func() will execute as root.  scgi_init_func() is executed
     before the server becomes a daemon, which means the standard streams will
     still be connected to the terminal it was started from, and error and
     informative messages may be sent there.  scgi_init_func() is called
     before any of the command-line options are processed, except for the -f
     option.  Therefore, if the server has been started with the -r option,
     the server will not yet have set the current working directory when
     scgi_init_func() is executed.

     In scgi_child_init_func(), or in functions which it calls, the programmer
     may perform any other initialization tasks each child process needs to
     perform independently of its parent before it can begin servicing connec-
     tions.  For example, one may open unique database connections for each
     server child in scgi_child_init_func().  scgi_child_init_func() is called
     every time a new server child process is forked().
     scgi_child_init_func() is executed after the server has changed user and
     group to "nobody" or to the values specified by the -u and/or -g command-
     line options.  When scgi_child_init_func() is executed the standard
     streams will be connected to /dev/null.  Therefore errors must be
     reported using syslog(3).  When scgi_child_init_func() is executed, the
     -r command-line option will have been processed to change the current
     working directory.

     Libdombey recognizes several command-line options to configure itself,
     described at the end of this manual, but does not allow user code access
     to the command line arguments.  Instead, it recognizes an -f option, and
     assigns the value of this option to the global character pointer
     scgi_config_file.  The code in scgi_init_func() and/or
     scgi_child_init_func() may then access the specified configuration file.
     Libdombey does nothing with the value of scgi_config_file.  If the -f
     option was not present on the command line, this variable will be NULL.

     If the programmer has shut-down tasks to perform when the master or child
     processes exit, he or she can register functions via atexit(3) in either
     scgi_init_func() or scgi_child_init_func().  Functions registered in
     scgi_init_func() will be called by the master and all child processes
     when they exit.  Functions registered in scgi_child_init_func() will only
     be called by the registering process when it exits.  If the programmer
     needs to perform a shut-down task only in the master process, then he or
     she is advised to use a global int to indicate whether a process is the
     master or a child.

     In scgi_init_func(), the programmer may install a function to be called
     periodically by the master process to perform maintenance tasks with:

     void scgi_periodic( void (*)(), int );

     The function pointed to by first argument will be called periodically by
     the master process, the period being specified in seconds by the second
     argument.  This function may only be called from scgi_init_func() because
     only that function is invoked in the master process.  Calling it from any
     other location in your code will have no effect.  Setting the interval to
     a value <= 0, or setting the function to NULL, disables the periodic
     function.  Note that the server will be running as the user and group
     defined by the -u and -g options when the periodic function is invoked.

     The third programmer-supplied function, scgi_request_handler() is called
     once for every request received by the server.  The programmer must use
     the buffered IO functions to output a complete CGI response to stdout
     before scgi_request_handler() returns.

     NEVER read from stdin.  Your server may block forever, if you do.

     The programmer must not define any global symbol beginning with the five
     characters "scgi_", other than the names of the three programmer supplied
     functions, because the library reserves that namespace for its own use.

     There is one libdombey library function which should be called from
     inside scgi_init_func():

     void scgi_set_name( char * );

     If not set, or set to NULL, the server's name defaults to "LibDombey".
     The server's name is used in two ways:

     o   When the server is running, stderr is connected to /dev/null.
         Errors, therefore, must be reported using syslog(3).  The library
         calls openlog() with the server's name as argument, to ensure log
         entries are identified by the server's name.

     o   The server's pidfile will be written to /var/run/, if the server is
         started as root.  The filename will be the server's name with ".pid"
         appended to it.  This file can be used by /usr/local/etc/rc.d/
         scripts to stop the server.  A sample script is included in the lib-
         dombey distribution.

     Inside scgi_request_handler(), eight library functions may be employed to
     access the SCGI environment, the decoded SCGI parameters, uploaded files,
     and any cookies defined in HTTP_COOKIE:

     char *scgi_get_env( char * );
     char **scgi_get_envs();

     char *scgi_get_param( char * );
     char **scgi_get_params();

     char *scgi_get_cookie( char * );
     char **scgi_get_cookies();

     char **scgi_get_file( char * );
     char **scgi_get_files();

     scgi_get_env() may be used to retrieve the value of one particular SCGI
     environment variable.  The name of the variable is passed as argument,
     and the function returns the variable's value, or NULL if the variable is
     not defined.  Note that some variables may be defined with their values
     being empty strings.  scgi_get_envs() returns an array of character
     pointers, listing all the SCGI environment variables and their values,
     each variable name followed by its value, with the array terminated with
     a NULL pointer.

     scgi_get_param() may be used to retrieve the decoded value of one partic-
     ular SCGI parameter.  The uncoded name of the parameter is passed as
     argument, and the function returns the decoded value, or NULL if the
     parameter is not defined.  Note that some parameters may have values of
     empty strings, if a value was not explicitly set by the client.
     scgi_get_params() returns an array of character pointers, listing all the
     SCGI parameters and their values, each decoded parameter name followed by
     its decoded value, with the array terminated by a NULL pointer.

     scgi_get_cookie() may be used to retrieve the value of one named cookie
     defined in the value of the HTTP_COOKIE environment variable.  The name
     of the desired cookie is passed as argument, and the function returns the
     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, each cookie name followed by its value, with the array ter-
     minated by a NULL pointer.

     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.  Other non-file elements of the same document
     may be accessed with scgi_get_param() and scgi_get_params(), but the file
     elements must be accessed with scgi_get_files() and scgi_get_file().

     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 three ajacent entries for each uploaded file.  The
     first entry of each group of three 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 success-
     fully uploaded file has been stored.  All files are created with
     mkstemp() and reside in the directory specified by the -r option.  These
     filenames will all be unlink()ed by the library when scgi_request_han-
     dler() returns.  If the programmer wants to the files to persist, he or
     she is responsible for hard linking another name to them.

     scgi_get_file() may be used to access the files array entries associated
     with a particular name.  The function accepts the name parameter as argu-
     ment and returns a pointer to a character pointer.  Indexing the returned
     pointer with 0, will give you a character pointer to the "filename"
     parameter, and indexing the returned pointer with 1 will give you a char-
     acter pointer to the local filename of the uploaded file.

     libdombey stores only the first 25 SCGI environment variable/value pairs,
     the first 25 SCGI parameter/value pairs, the first 25 uploaded files, and
     the first 25 cookie/value pairs.  More items provided in a client request
     will be ignored.  These limits are defined with four macros in the source
     code, MAX_ENV, MAX_PARAMS, MAX_FILE, and MAX_COOKIE, respectively.  You
     may change them and recompile libdombey, if you need more items.

     The pointers and strings returned by these functions MUST NOT be modi-
     fied.  The values returned by scgi_get_env(), scgi_get_param(),
     scgi_get_file(), and scgi_get_cookie() do not persist between invocations
     of scgi_request_handler(), so do not store them.  The locations of the
     arrays returned by scgi_get_envs(), scgi_get_params(), scgi_get_files(),
     and scgi_get_cookies() never change, so these functions may be called
     once and the returned values stored and used thereafter.  One may call
     these two functions in scgi_init_func() to get their values, but the con-
     tent of the arrays will be indeterminate at that time, and should not be
     accessed.

     There is one last library convenience function available to the program-
     mer:

     char *scgi_form_encode( char * );

     This function encodes a string using x-www-form-urlencoding.  The
     returned string is dynamically allocated, and must be free(3)d when no
     longer needed.

     An example server is included in the libdombey distribution, named
     test.scgi.  Please examine the test.c source for the example server.  It
     demonstrates the use of libdombey concisely.

CONFIGURATION
     A server linked against libdombey writes its pidfile into /var/run/, if
     it can (ie., it is started as root), and may be stopped with a SIGTERM.
     A sample rc.d script is provided in the libdombey distribution.  To use
     the script, all occurrences of "dombey" must be replaced with the value
     you passed to scgi_set_name(), and the script installed in
     /usr/local/etc/rc.d, renamed as the value you passsed to scgi_set_name().

     Two variables must be added to /etc/rc.conf.  For example (substituting
     "dombey" for your server's name):

     dombey_enable="YES"
     dombey_flags="-u www -g www -r /usr/local/dombey"

     If the "enable" variable is set to "YES", the server will be started at
     system start.  The following rc commands will be available:

     /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 libdombey servers.
     The -r option is mandatory.  All the rest are optional.

     -r  The mandatory -r option specifies the server root directory, which
         libdombey will make its current working directory.  When multi-
         part/form-data POST request entities contain "filename" parameters,
         files will be created in this directory to hold the data for those
         entities.

     -l  By default, libdombey listens on all TCP interfaces it can find capa-
         ble of IPv4 or IPv6.  The -l option instructs the library to listen
         on a UNIX-domain socket instead.  The path to the socket must be
         specified as this option's argument.  The server will create the
         socket when it starts, unlinking it first, if it already exists in
         the filesystem.  The owner and group of the socket will be changed to
         the values of the -u and -g options, or their defaults.  The permiss-
         sions of the socket will be set to srwxrwx---.  If this option is
         present on the command-line, then the -p and -i options may not be
         present.  The server will refuse to run if they are.

     -p  The -p option specifies the port to listen on.  This defaults to 4000
         if not specified.  Note that to bind to a port lower than 1024, the
         server must be started as root.

     -i  By default, libdombey accepts connections on all interfaces it can
         find capable of IPv4 or IPv6.  The -i option, when present, overrides
         this behavior, by limiting libdombey to accepting connections from a
         specified interface only.  The option accepts the IP address of the
         desired interface as an argument.  The address must be expressed in
         the presentation format for either IPv4 or IPv6.

     -m

     -n  libdombey uses a multi-process model, with one master process forking
         or killing slave processes in response to client activity.  Only the
         slave processes service client requests.  The -n options specifies
         the number of idle slaves the master will attempt to keep ready at
         all times.  The -m option specifies the maximum number of slaves
         which may be running at any time.  The value specified must be equal
         to or greater than the value specified for -n.  The default value for
         -n is 3 and the default value for -m is 25.

     -b  The -b option, if present, describes a maximum acceptable data size,
         in bytes, which is used differently when processing different types
         of requests.  Its purpose is to prevent malicious clients from caus-
         ing the server to consume arbitrary amounts of memory.  If not speci-
         fied this value defaults to 10000.

         For GET requests this value is ignored.

         For POST requests which are encoded with x-www-form-urlencoding, this
         size is the maximum size of request bodies.  Connections will be
         dropped without explanantion when CONTENT_LENGTH exceeds this value.

         For POST requests submitted as multipart/form-data documents, this
         value specifies the maximum size of each non-file entity in the docu-
         ment.  The -e option specifies the maximum length of file entities.

     -e  The -e option specifies the maximum size, in bytes, of files uploaded
         in multipart/form-data POSTS.  If not specified, it defaults to
         2000000.  Connections attempting to upload a file greater than this
         size will be dropped without explanation.

     -u

     -g  The -u and the -g options may be used to specify the user and group
         for the server to change to after it has bound to the listening
         socket.  If not specified, both values default to "nobody".  Note
         that in order for a libdombey server to change user the server must
         be started as root.  If not started as root, two error messages will
         be syslog()ed at start-up, complaining about the inability of the
         server to change user and group.  You can suppress them by providing
         values to -u and -g to override the default "nobody" with the actual
         user and group under which the server runs.

     -x  The -x option, if present, prevents libdombey from becoming a daemon.
         It will then run in the foreground of the terminal where it was
         started, and may be stopped with signals (ie., Control-C).  Stderr
         will be connected to the terminal, so diagnostic output may be sent
         there when this option is present on the command-line.  The server
         also will not write its pidfile to /var/run/ when the -x option is
         used.

     -f  The -f option requires a filename as argument.  Libdombey does noth-
         ing with this value, but assigns it to the global character pointer
         named scgi_config_file.  This allows the code in scgi_init_func()
         and/or scgi_child_init_func() to read a configuration file, specified
         by the user, upon process start-up.

AUTHORS
     James Bailie <jimmy@mammothcheese.ca>
     http://www.mammothcheese.ca

                                 Jan 05, 2012