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

NAME
     Drood -- Minimal KQueue-Based HTTP/1.1 Server

SYNOPSIS
     drood -r <server-root> [-m <instances> -i <interface> -p <port> -e
           <root-resource> -d <cgi-dir> -t <read-timeout> -w <write-timeout>
           -u <user> -g <group> -l <logfile> -q <backlog> -s
           <host|port|suffix> -x]

DESCRIPTION
     Drood is a lightweight, partially-compliant HTTP/1.1 server, intended as
     an alternative to heavyweight web servers for websites where the server
     requirements are simple.

     The drood distribution includes a generic SCGI application server, named
     scgid(8), which is documented in its own manual.

   WHAT DROOD DOES
     o   Drood services both IPv4 and IPv6 connections.

     o   Drood understands the HEAD, GET, and POST request methods, only.

     o   Drood supports HTTP/1.1 persistent connections.

     o   Drood supports name-based virtual hosting.

     o   Drood supports both CGI and SCGI.

     o   Drood supports gzip content-encoding.

   WHAT DROOD DOES NOT DO
     o   Drood does not accept HTTPS connections.

     o   Drood does not perform access authentication.

     o   Drood does request logging instead of transaction logging.

     o   Drood does not restart "gracefully".  Established connections will be
         dropped without allowing transactions in progress to complete.

     o   Drood Does not perform content negotiation beyond recognizing the
         "Accept-Encoding", "If-Modified-Since", and "If-Unmodified-Since"
         request headers.  The only accept-encoding supported is gzip.

     o   Drood does not provide any response headers useful for caching server
         responses beyond the "Date" and "Last-Modified" headers.

     o   Drood will not generate directory listings for clients.

     o   drood does not support the ~user notation to provide access to
         resources in user directories, but this may be simulated with sym-
         bolic links.

   SYSTEM CONFIGURATION
     Drood is a kqueue(2)-based multiplexer.  By default, FreeBSD limits each
     process to having a maximum of 64 simultaneously open descriptors.  This
     places a limit on the number of connections drood may multiplex.  The
     sysctl settings below, allow for a generous number of connections.  These
     values can be set at the command-line with the "sysctl" utility.  It is
     recommended that they be enabled permanently by placing these lines in
     /etc/sysctl.conf on the host machine.

     kern.maxfiles=16384
     kern.maxfilesperproc=16384
     kern.kq_calloutmax=65536
     kern.ipc.nmbclusters=25600
     kern.ipc.maxsockets=25600

     Drood will attempt to set the accf_http accept filter on the listening
     socket, to increase performance.  For this to succeed, you will need to
     load the module before starting drood with:

     kldload accf_http

     To load the module automatically at system boot-up, add the following
     line to /boot/loader.conf:

     accf_http_load="YES"

   DROOD CONFIGURATION
     Drood writes its pid into /var/run/drood.pid, if it can (ie., it is
     started as root), and may be stopped with a SIGTERM.  A rc.d script is
     provided and installed in /usr/local/etc/rc.d/.  Add the following lines
     to /etc/rc.conf to start drood on system boot-up.  Replace the items in
     brackets with values appropriate for your system.  These are the minimal
     set of options one should start with.  These and all of the other avail-
     able options are described in full at the end of this manual page.

     scgid_enable="NO"
     drood_enable="YES"
     drood_flags="-r <server-root> -u <user> -g <group> -m <instances>"

     Once your system is configured you may start, stop, or restart drood, or
     determine if it is running with the following commands:

     /usr/local/etc/rc.d/drood start
     /usr/local/etc/rc.d/drood stop
     /usr/local/etc/rc.d/drood restart
     /usr/local/etc/rc.d/drood status

     If you do not want drood started on system start, then set

     drood_enable="NO"

     and use the following commands:

     /usr/local/etc/rc.d/drood forcestart
     /usr/local/etc/rc.d/drood forcestop
     /usr/local/etc/rc.d/drood forcerestart
     /usr/local/etc/rc.d/drood forcestatus

   GZIP CONTENT ENCODING
     To enable gzip content-encoding for static resources, the webmaster must
     manually gzip the resources he or she would like to make available in
     that encoding.  The original resource should not be replaced by the
     gzipped version, but should also be available in the same directory for
     clients which cannot handle the encoding.  The gzipped version must have
     the ".gz" filename suffix.  If a client indicates it is acceptable for a
     requested resource to be gzipped, then drood will attempt to send the
     gzipped version of the resource.  If this attempt fails, drood will
     attempt to send the non-compressed version of the requested resource.

     Do not confuse gzip content-encoding with naturally gzipped resources,
     such as tar.gz files.  An explicit request for a gzipped resource will be
     cause the resource to be transferred to the client, as expected.  With
     gzip content-encoding, the client requests a resource, such as an *.html
     file, indicating it can accept that resource gzipped, to save bandwidth
     and decrease transfer time.  Drood will look for a gzipped version of the
     requested resource and send it instead, if it exists.  All major browsers
     support gzip content-encoding, so creating gzipped versions of your
     static resources is a useful thing to do, to both speed up transfers and
     lower the server's bandwidth consumption.

     Note that drood does not compare the modification times of the uncom-
     pressed and compressed resources.  It will always send the compressed
     resource if it exists, is acceptable to the client, and drood has permis-
     sion to read it.  One can keep Makefiles in one's html directories to
     compress all the resources whose compressed versions are out of date,
     with gzip -k.  As long as the Makefiles are not readable by the user or
     group drood is running as, client requests for them will fail.

   MAPPING FILENAME SUFFIXES TO MIME TYPES
     These are the mappings from filename suffixes to MIME types which drood
     recognizes out-of-the-box.  They are listed in types.tab in
     /usr/local/etc/drood/.  Any file which cannot be identified by these map-
     pings is identified by the server as "text/plain; charset=utf-8".  To add
     a mapping, simply add a line to types.tab.  Each line must consist of the
     filename suffix to be mapped, followed by one or more tab characters,
     followed by the MIME type, followed by a newline.  Blank lines are
     ignored, after the first line.  The first line must not be blank.  If
     drood finds empty fields in types.tab it will refuse to run.  If you mod-
     ify types.tab, you must restart drood for the changes to take effect.

         Suffix  MIME Type
         html    text/html; charset=utf-8
         htm     text/html; charset=utf-8
         xml     text/xml; charset-utf-8
         txt     text/plain; charset=utf-8
         css     text/css
         ico     image/vnd.microsoft.icon
         png     image/png
         jpg     image/jpeg
         jpeg    image/jpeg
         tiff    image/tiff
         tif     image/tiff
         gif     image/gif
         tgz     application/x-compressed
         zip     application/zip
         ps      application/postscript
         eps     application/postscript
         gz      application/x-gzip
         tgz     application/x-compressed
         pdf     application/pdf
         swf     application/x-shockwave-flash
         js      application/x-javascript
         mov     video/quicktime
         qt      video/quicktime
         mpg     video/mpeg
         mp2     video/mpeg
         mpa     video/mpeg
         mpe     video/mpeg
         avi     video/x-msvideo
         asf     video/x-ms-asf
         asx     video/x-ms-asf
         asr     video/x-ms-asf
         flv     video/x-flv
         ra      audio/x-pn-realaudio
         ram     audio/x-pn-realaudio
         wav     audio/x-wav
         mp3     audio/mpeg

   COMMAND-LINE OPTIONS
     The following options are recognized.  Only the -r option is required,
     but you will probably want to include at least the -u, and -g options
     when you are starting the server for production use.  For optimal perfor-
     mance, employ the -m option, and use the -q and -t options to match your
     load levels.  If you wish to service CGI and/or SCGI requests, add the -d
     option.  If you wish to service SCGI requests, you must add one or more
     -s options.

     -r  The -r option is mandatory and specifies the server root directory,
         which drood will make its current working directory.

         The resources served-up by drood are determined by the "Host" header
         of requests, thus implementing name-based virtual hosting.  For every
         hostname you wish to be recognized by the server, an identically-
         named subdirectory of the server root directory must be created.  The
         static files served up by each virtual host are placed into the iden-
         tically-named subdirectory.  Any or all of the subdirectories may be
         symbolic links.  One subdirectory must be named "default".  This is
         the directory which will be used to fulfill static requests when no
         "Host" header is supplied by a client (eg., HTTP/1.0 requests).  The
         "default" directory can and should be a symbolic link.  If you would
         like a directory to be used for more than one hostname, you must cre-
         ate links for the extra hostnames.

         For example, I could have, in my server root directory, the following
         subdirectories.  Note the symlink for the loopback addresses.  With-
         out it, drood will not be able to find resources for requests from
         loopback connections, if clients use the address in URIs, instead of
         the local hostname.  Note the link for the IP address of the server,
         to allow clients to connect using URIs containing the server's IP
         address instead of its hostname.  Note that if you are using IPv6,
         you will need to create links which include the surrounding square
         brackets which are used to identify IPv6 addresses in URIs (rfc3986).

         mammothcheese.ca     -> actual subdirectory
         www.mammothcheese.ca -> symlink to mammothcheese.ca
         default              -> symlink to mammothcheese.ca
         127.0.0.1            -> symlink to mammothcheese.ca
         [::1]                -> symlink to mammothcheese.ca (IPv6 Loopback)
         99.250.61.49         -> symlink to mammothcheese.ca

         Drood will reject any request whose host header contains a virgule
         "/", or starts with "." in order to prevent clients from accessing
         resources outside of the virtual host subdirectories.  Note this does
         not prevent you from symlinking a directory outside of the server
         root directory hierarchy into the server root directory.

         Symbolic links can be used to provide access to user websites.  For
         example, if I wished to expose the personal website of user "ella" on
         mammothcheese.ca to drood, I could create a symbolic link inside the
         mammothcheese.ca directory named "ella" pointing to her ~/public_html
         directory.  This would allow access via URIs such as http://www.mam-
         mothcheese.ca/ella/.  Note that drood will recognize a request ending
         in a virgule "/" as a request for the root resource in the directory
         specified by the request.  Note also, if the root resource has been
         set to a dynamic resource, this won't work.  In that case, the full
         path to ella's root resource will have to be specified by clients.
         Eg., http:www.mammothcheese.ca/ella/index.html.  See the entry for
         the -e option for information on the root resource.

         Remember to set the ownership and permissions of the directories and
         their contents according to the values you give for the -u and -g
         options.  Static resources must be set readable by the user or group
         drood will be running as.  Directories must similarly be searchable.

         If the -d option is present, requests whose "Host" headers reference
         the directory specified by that option, will be rejected.  This pre-
         vents clients from requesting data files in the (S)CGI directory.
         Drood will refuse to send files to clients, if they are executable by
         drood, regardless of where they reside.

     -e  The root resource of all virtual hosts defaults to a static resource
         named "index.html", which itself may be a symbolic link.  This may be
         changed with the -e option.  Note this changes the name of the root
         resource of all virtual hosts served-up by drood.  The value speci-
         fied must not begin with a virgule "/".

         You may, with the -e option, specify a dynamic resource as the root
         resource.  If you do, you must be sure to include the -d option to
         tell the server where (S)CGI programs live.  Eg.,

         drood -r /usr/local/www/drood -d cgi-bin -e cgi-bin/index.cgi

         To summarize, every virtual host has its own static root resource in
         its own subdirectory, but all virtual hosts' static root resources
         must have the same name, either the default "index.html" or another
         name specified by the -e option.  If a dynamic resource is specified
         as the root resource, then it is shared by all virtual hosts, and
         resides in the (S)CGI subdirectory, as defined by the -d option.  If
         a dynamic root resource needs to know the virtual host for which it
         is being executed, it must examine the SERVER_NAME environment vari-
         able.

         If a request is received ending with a virgule "/", that request is
         interpreted as a request for the root resource residing in the direc-
         tory specified by the request.  If the root resource is a dynamic
         resource, such a request will not make sense, and fail, unless the
         request is for the toplevel root resource of a host.

         If the root resource is a symbolic link and you wish to make use of
         gzip content-encoding for that resource when requested via the sym-
         bolic link, make a symbolic link to the compressed version of the
         root resource as well.  For example, if you have index.html linked to
         another_file.html, create a compressed version of another_file.html
         if one does not already exist, with "gzip -k another_file.html".
         Then create a link for it with "ln -s another_file.html.gz
         index.html.gz"  Remember to set the file permissions accordingly for
         the values you have used for the -u and -g options.

     -d  The -d option, if present, specifies the subdirectory of the server
         root directory which contains CGI and/or SCGI resources.  The value
         given to this option cannot contain the directory separator character
         "/" anywhere in it, nor can it be ".." or "." by itself.  The direc-
         tory specified must be one level below the server root directory.
         The directory must be readable and searchable for the user or group
         specified with the -u and -g options.  The directory may contain any
         subdirectory structure the user wishes to create in it.  Only exe-
         cutables in the (S)CGI directory, or its subdirectories, can be run.
         Drood refuses to execute symbolic links.

         All virtual hosts share the (S)CGI directory.  If (S)CGI programs
         wish to know what hostname they have been invoked for, they must
         examine the SERVER_NAME environment variable.  If no "Host" header
         was supplied with the request, then SERVER_NAME will be set to the
         string "default".  If the -d option is not present, executables can-
         not be run.  Requests for dynamic resources must include the dynamic
         path in their URIs, because this is how drood differentiates static
         requests from dynamic requests.  Eg., if -d is "cgi-bin", then

         http://host.domain/cgi-bin/foobar.cgi

         is a request to run foobar.cgi from the cgi-bin subdirectory of the
         server root directory.  If the -d option was not set, then this would
         be interpreted as a request for a static resource named foobar.cgi
         located in the cgi-bin subdirectory of the host.domain subdirectory
         of the server root directory.

         Note that if you have a (S)CGI directory and you subsequently decide
         to run drood without the -d option, that directory will be considered
         a valid directory containing static resources for a virtual host, and
         clients may request the non-executable resources in the directory, if
         the client knows their names, by providing a "Host" header set to the
         name of the directory.  Drood will always refuse to send files to
         which it has executable permission to clients, no matter where they
         reside, but if you have data files in your (S)CGI directory, it's a
         good idea to remove the (S)CGI directory if you are not running drood
         with the -d option anymore.  You should at least change the (S)CGI
         directory's ownership and/or permissions to make it inaccessible by
         drood.

         (S)CGI programs need only precede their response bodies with a "Con-
         tent-Type" header and a blank line.  Drood will chunk response data
         for (S)CGI programs invoked over persistent connections.  The (S)CGI
         program's response header will be supplemented with a response status
         line, a "Date" header if one is missing, a "Server" header, and if
         the (S)CGI response header does not include a "Content-Length" header
         and the connection is persistent, a "Transfer-Encoding: chunked"
         header.  If a "Location" header is provided by the (S)CGI program,
         then drood with create a "302 Found" response to send to the client,
         which will cause the client to redirect itself to the URI specified
         in the "Location" header.  Otherwise, drood will compose a "200 OK"
         response status line.

         It is crucial that CGI programs invoked with the POST method read
         from stdin exactly the number of characters specified by the CONTENT-
         LENGTH environment variable.  Reading too much or too little will
         prevent drood from reading the next request over a persistent connec-
         tion, and it will then drop the connection.  For GET requests, the
         stdin of CGI programs will be connected to /dev/null.

         The stderr of CGI programs is connected to /dev/null. For testing
         purposes run drood with -x option and the CGI stderr will be con-
         nected to the terminal from which drood is running.  For production
         use, CGI programs must send diagnostic output to files, or use sys-
         log(3).

         The following environment variables are set for (S)CGI programs:

         REMOTE_ADDR, REQUEST_METHOD, SCRIPT_NAME, QUERY_STRING,
         HTTP_USER_AGENT, HTTP_COOKIE, SERVER_SOFTWARE, SERVER_NAME, GATE-
         WAY_INTERFACE, CONTENT_TYPE, and CONTENT_LENGTH.

         Additionally, SCGI is set for SCGI resources, only.

         Drood cannot recognize virtual paths for (S)CGI programs, so
         PATH_TRANSLATED and PATH_INFO are not set.

     -s  Including this option on the command line, if and only if the -d
         option has also been included, causes drood to forward requests for
         items in the (S)CGI directory, with a specified filename suffix, to a
         specified SCGI Server.  Starting-up and shutting-down processes for
         traditional CGI programs becomes a performance bottleneck on busy
         servers.  The SCGI protocol specifies a simple means by which a web
         server can forward a request to a persistent application to generate
         the response.  Process start-up and shut-down, and application ini-
         tialization costs are eliminated for each request, resulting in sig-
         nificantly better performance over traditional CGI.

         Multiple instances of this option may be present on the command line.
         Each option value must have form:  <host>|<port>|<suffix>, where
         <host> is the name of the host the SCGI server is running on, or its
         IP address expressed in either IPv4 or IPv6 presentation format,
         <port> is the port number the SCGI server is listening on, and suffix
         is the filename suffix to associate with this SCGI server.  Requests
         for items in the (S)CGI directory (specified by the -d option) whose
         filenames are terminated by this sequence of characters, will be for-
         warded to the SCGI server at <host> listening on <port>.  The suffix
         value must not contain a dot.

         For example, to forward requests for files matching *.foo to a local
         server listening on port 4000, and forward requests for files match-
         ing *.bar to a local server listening on port 5000, one would include

         -s '127.0.0.1|4000|foo' -s '127.0.0.1|5000|bar'

         on the drood command line.  Note that it is necessary to quote the
         option values to prevent the shell from interpreting them as pipe-
         lines.

         A stub multi-process SCGI server is included in the drood distribu-
         tion.  The server has its own rc script and manual page (scgid.8),
         and is used by the author to test drood's SCGI support.  It allows
         filter programs to be used as SCGI servers.

     -p  The -p option specifies the port to listen on.  This defaults to 80
         if not specified.

     -i  By default, drood accepts connections on all interfaces it can find
         capable of IPv4 or IPv6.  The -i option, when present, overrides this
         behavior, by limiting drood 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 pre-
         sentation format for either IPv4 or IPv6.

         The intent of this option is to allow the administrator to prevent
         the outside world from accessing a server during testing by making
         drood bind only to one interface (eg., the loopback address).

     -u

     -g  Drood must be started as root in order to bind to port 80.  The -u
         and the -g options may be used to specify the user and group for
         (S)CGI programs.  If not specified, both values default to "nobody".
         If you employ the -m option to run one instance of drood for each
         processor core, as it is recommended you do, the child drood pro-
         cesses will also be launched as this user and group.  The main drood
         process does not change its user or group so that it may restart upon
         receipt of SIGHUP with the same privileges it had when it began run-
         ning.

     -t  When reading a request header from a client, drood drops the connec-
         tion if it cannot read the complete request header within twenty sec-
         onds.  The -t option, if present, specifies a different read timeout
         value, in seconds.  Clients typically keep a connection to a server
         open to aid responsiveness if the user subsequently requests more
         resources from the same server, and rely on the server to timeout
         idle connections.  The value must be in the range 1-60 seconds.  It
         is important this value take into consideration the latency of drood
         on your system under load, and the latency of your network inter-
         faces, and the possible latency of clients behind firewalls on busy
         networks.  If the server starts dropping connections under load, and
         you haven't run out of resources, you may have the read timeout set
         too low.

     -w  When drood is in the process of writing a requested resource to a
         client, the connection will be dropped if 60 minutes has elapsed
         since it started writing the resource.  This value may be changed
         with the -w option, and must be in range of 0-120 minutes.  Setting
         this value to 0, disables the write timeout.  In this case, the
         client may take as long as it likes to read a requested resource.
         Note that persistent connections may exist for longer periods than
         this value specifies, but each individual resource requested over
         such a connection must be read by the client within this number of
         minutes, or the connection will be dropped.

     -q  The -q option, if present, specifies the backlog of client connec-
         tions queued by the OS kernel for the server to subsequently service.
         This value defaults to 1000.  Note that the OS 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.  This
         value should be set to a generous value.  If the system starts
         rejecting connections under load, and you're sure you haven't run out
         of resources, try increasing the size of the backlog queue.

     -x  The -x option, if present, prevents drood 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).  The server also
         will not write its pid to /var/run/drood.pid when the -x option is
         used.

     -m  The -m option specifies how many instances of drood should be run,
         and defaults to 1.  This option is intended for use on multiple-core
         or multiple-processor machines, where running a separate instance of
         drood for each core/processor will drastically increase the number of
         requests per second drood can process.

     -l  The -l option turns-on request logging.  If present it must specify
         the fully-qualified filename of a file to hold the request log.  The
         file must be writeable by the user that drood starts as.  If the file
         does not exist, drood will attempt to create it, so the directory in
         which the file resides should be writeable by the initial user, as
         well.

         Logging is turned-off by default.  Request logging differs from
         transaction logging in that requests are logged as they arrive,
         instead of after they have been processed.  In particular, this means
         the response code and the number of bytes transferred are not
         recorded in log records, because they are not known at the time the
         request is logged.  Drood does not use the common log file format.
         It uses its own, simpler-to-parse format.

         Each line of the logfile is a complete request record.  The fields of
         request records are ordered as follows, with all fields separated by
         single | characters:  The date and time of the request, the client IP
         address, the request User-Agent header, the request method, the
         request URL, and finally, the request Referer (sic) header.  If no
         User-Agent or Referer header is present in a request, these items
         will be the strings, "no user-agent header", or "no referrer header",
         respectively.

         Note that the IP address will be expressed in IPv6 presentation for-
         mat by default.  Clients making IPv4 connections will have their IP
         addresses written as IPv4-mapped IPv6 addresses, unless the -i option
         has been specified with an IPv4 address.  In that case the address
         with appear in the presentation format for IPv4.

         Read the manual for newsyslog.conf(5) to learn how have your logfile
         automatically rotated.  An example is shown below.  Adding this line
         to /etc/newsyslog.conf will cause the file /var/drood-requests.log to
         be turned-over every night at midnight, with the five most recent
         logfiles kept on-hand, renamed and compressed with gzip.

         /var/log/drood-requests.log 600 5 * T00 Z /var/run/drood.pid

         newsyslog(8) can be scheduled to run with crontab(1,5).  Here is a
         sample crontab for root.  Copying these lines to a file and invoking

         /usr/bin/crontab <filename>

         will cause crontab to run newsyslog at midnight every night:

         SHELL=/bin/sh
         PATH=/usr/sbin
         HOME=/var/log
         # insert your email address below to be notified by mail when newsyslog
         # emits output on its stderr.
         MAILTO=user@host.domain

         0 0 * * *       /usr/sbin/newsyslog.

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

                                 Sep 10, 2009