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 small and fast, minimal web server.  It is configured with
     command-line options.

   WHAT DROOD DOES
     o   Drood supports 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.

     o   Drood supports requests for single byte ranges.

     o   Drood performs request logging instead of transaction logging.

     o   Drood stops and restarts gracefully.  Already established connections
         are allowed to terminate naturally before server processes stop.

   WHAT DROOD DOES NOT DO
     o   Drood does not support TLS/SSL.

     o   Drood does not perform access authentication.

     o   Drood Does not perform content negotiation beyond recognizing the
         "Accept-Encoding", "If-Modified-Since", "If-Unmodified-Since", and
         "Range" 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.

     drood_enable="YES"
     drood_flags="-r <server-root> -u <user> -g <group>"

     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.

     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 and the client wants 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.

     Note that when sending responses to requests with Range headers, Drood
     will always send the requested byte ranges from the uncompressed
     resource.  Gzip content encoding is only used for responses containing
     entire static resources.

   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
         svg     image/svg+xml
         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.

     -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.  For every hostname you wish to be recognized by the
         server, an identically-named subdirectory of the server root direc-
         tory must be created.  The static files served up by each virtual
         host are placed into the identically-named subdirectory.  Any or all
         of the subdirectories may be hard or symbolic links.  One subdirec-
         tory 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 link.  If you would like a directory to be used for more
         than one hostname, you must create links for the extra hostnames.

         An example root directory specifying entries for one hostname is
         below.  Only the first entry is an actual virtual host subdirectory.

         mammothcheese.ca          -> actual subdirectory (IPv4)
         www.mammothcheese.ca      -> link to above (IPv4)
         default                   -> link (IPv4/IPv6 HTTP/1.0)

         If you wish to accept connections specified by IP address, you must
         include links for valid addresses:

         64.15.138.206             -> link (IPv4 Decimal)
         127.0.0.1                 -> link (IPv4 Loopback)

         The following three entries specify valid, but rarely used forms of
         IPv4 addresses, which could be included for completeness sake:

         0100.017.0212.0316        -> link (IPv4 Octal)
         0x40.0x0f.0x8a.0xce       -> link (IPv4 Hexadecimal)
         1074760398                -> link (IPv4 IP Number)

         If you wish to accept IPv6 connections, you will need to add entries
         where the hostname is delimited with square brackets per RFC3986:

         [mammothcheese.ca]        -> link for IPv6 connections
         [www.mammothcheese.ca]    -> link for IPv6 connections
         [::1]                     -> link (IPv6 Loopback)

         If you cause drood to listen on a port other than port 80, that port
         number will appear in client "Host" headers.  You must adjust your
         entries accordingly:

         mammothcheese.ca:8080     -> actual subdirectory (IPv4)
         www.mammothcheese.ca:8080 -> link to above
         (etc)

         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 files in the (S)CGI directory hierar-
         chy.

     -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 "/".

         If a request is received for a directory, that request is interpreted
         as a request for the root resource residing in that directory.

         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

     -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".

         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 a request to run
         foobar.cgi would look like this:

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

         Note that if you have a (S)CGI directory and you subsequently decide
         to run drood without the -d option, that directory will be treated as
         a virtual host subdirectory.  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 ignores Status header
         lines from (S)CGI programs.  If a "Location" header is provided by
         the (S)CGI program, then drood will create a "302 Found" status line
         to send to the client.  Otherwise, drood will compose a "200 OK" sta-
         tus line.  This means errors must be reported to the client using
         HTML responses.

         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,
         SERVER_PORT, GATEWAY_INTERFACE, CONTENT_TYPE, SCGI, GZIP, and CON-
         TENT_LENGTH.

         SCGI is set to 1 for SCGI resources, and to 0 for plain CGI.  If the
         client request included an Accept-Encoding header indicating the
         client can receive gzipped data, GZIP is set to 1.  Otherwise it is
         set to 0.

         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.  The filesystem entries must exist, but they
         may be empty files.

         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 whose filenames are terminated by
         this sequence of characters, will be forwarded 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 generic multi-process SCGI server is included in the drood distri-
         bution.  The server has its own rc script and manual page
         (plunger.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 argument to the -p option specifies the port to listen on.  This
         defaults to 80 if the -p option is not present on the command-line.

     -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.

     -u

     -g  The -u and the -g options may be used to specify the user and group
         of drood server processes.  If not specified, both values default to
         "nobody".

     -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.  The value must be in the range 1-60 seconds.

     -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.

     -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.

     -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 the number of CPUs on the host system.  On a four-
         core machine, four instances of drood would be run automatically.

     -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

                                 Jul 30, 2011