Manual Reference Pages - DROOD (8)
- Minimal Event-Driven HTTP/1.1 Server
Drood Does Not Support:
Gzip Content Encoding
Mapping Filename Suffixes To Mime Types
Compound Requests With Pipelined Responses
Scgi And Websockets
-p Ao port Ac -e Ao root resource Ac -d Ao scgi-dir Ac
-m Ao instances Ac
-t Ao read timeout Ac -w Ao write timeout Ac -u Ao user Ac -g Ao group Ac
-l Ao log file Ac -s Ao host|port|suffix Ac -x -c Oc
Drood is a small, fast, and insecure web server.
- IPv4 and IPv6 connections.
- HEAD, GET, and POST request methods.
- HTTP/1.1 persistent connections.
- Name-based virtual hosting.
- SCGI. A companion SCGI server library package is in devel/libdombey.
- WebSockets. A custom WebSocket server library is provided
with drood and humdinger and is described in libdorrit.8.
- A custom pipelining extension described in droodpipe.8
- Gzip content-encoding.
- Request logging.
- Graceful stops and restarts.
DROOD DOES NOT SUPPORT:
- TLS encrypted connections. A companion HTTPS server is included with
drood, called humdinger. Humdinger has its own manual, humdinger(8).
- Plain CGI.
- Access authentication.
- Content negotiation beyond
"Accept-Encoding", "If-Modified-Since", and "If-Unmodified-Since".
The only content encoding supported is gzip.
- Directory listings.
- The ~user notation in URLS.
Drood is a hybrid server. It forks one worker process per processor on the
host system, and then each worker process becomes an event-driven server.
The master process sleeps waiting for signals.
By default, FreeBSD limits each process to a low number of maximum
simultaneously open descriptors. This places a limit on the number of
connections drood may multiplex. The sysctl settings below accommodate a
generous number of connections. Set these values at the command-line with
the "sysctl" utility, or enable them permanently by placing these lines in
/etc/sysctl.conf on the host machine. Your system will complain about
these values if it lacks resources.
To increase performance, drood attempts to set the accf_http accept filter
on the listening socket. For this to succeed, you must load the module
before starting drood.
To load the module automatically at system boot-up, add the following line
Drood writes its pid into /var/run/drood.pid if it can (ie., it is started
as root). You stop drood with a SIGTERM and restart it with a SIGHUP.
A rc.d script is installed in /usr/local/etc/rc.d/. Add the following
lines to /etc/rc.conf to start drood on system boot. Replace the items in
brackets with values appropriate for your system. These are the minimal
set of options you should start with. The available options are described
in full at the end of this manual page.
drood_flags="-r <server-root> -u <user> -g <group>"
Start, stop, or restart drood, or determine if it is running with the
If you do not want drood started on system start, set
and use the following commands.
GZIP CONTENT ENCODING
To enable gzip content-encoding for static resources, manually gzip the
those resources. The original resources must be available in the same
directory for clients which cannot handle the encoding. Gzipped versions
must have the ".gz" filename suffix.
Drood does not compare the modification times of the uncompressed and
compressed resources. Drood sends a compressed resource if it exists, it
is readable, and the client wants it. You can keep Makefiles in your html
directories to keep your compressed resources up to date with gzip -k.
Drood does not provide directory listings to clients, so clients cannot
know about the Makefiles. As long as the Makefiles are not readable by the
user or group drood is running as, client requests for them fail.
MAPPING FILENAME SUFFIXES TO MIME TYPES
The mappings from filename suffixes to MIME types that drood recognizes
out-of-the-box are listed in /usr/local/etc/drood/types.tab. Any file
that cannot be identified by these mappings is identified by the server as
"text/plain; charset=utf-8". To add a mapping, add a line to types.tab.
- Each line contains one filename suffix to be mapped and one MIME type
separated by one or more tab characters.
- The first line must not be blank.
- Blank lines are ignored after the first line.
- Drood refuses to run if it finds empty fields in types.tab.
- If you modify types.tab, you must restart drood for the changes to take
Drood can substitute one request for another. The substitution mappings
are stored in /usr/local/etc/drood/aliases.tab. To create a substitution,
add a line to aliases.tab.
- Each line contains one original request and one substitution separated
by one or more tab characteres.
- The first line must not be blank.
- Blank lines are ignored after the first line.
- Drood refuses to run if it finds empty fields in aliases.tab.
- If you modify aliases.tab, you must restart drood for the changes to take
Request mapping is used to shorten dynamic URLs. All virtual hosts share
the virtual SCGI directory, so request mapping affects all virtual hosts.
For example, if you have configured drood to forward requests for resources
with the .scgi suffix to an SCGI application server (-s option),
but you want to simplify your URLS so that they do not contain the SCGI
path or the .scgi suffix, you could use substitions similar to the
If the original request contains GET parameters, they are appended to the
/foobar?tiddlywinks=10 => /cgi-bin/foobar.scgi?tiddlywinks=10
/tooley?hooply=mugwump => /cgi-bin/tooley.scgi?special&hooply=mugwump
In the resource names of requests, drood will convert every sequence
of bytes consisting of a percent sign followed by two hexadecimal digits
into the byte specified by the hexadecimal value. Whitespace, semicolons,
and percent signs must all be percent-escaped to be recognized in resource
COMPOUND REQUESTS WITH PIPELINED RESPONSES
Drood recognizes compound requests as described the droodpipe.8 manual and
delivers pipelined responses to those requests.
SCGI AND WEBSOCKETS
You can configure drood to forward request to SCGI and WebSocket
servers. See the -s and options in the following section of the manual.
The following options are recognized. Only the -r option is required.
The -m option specifies how many worker processes are run and defaults to
the number of CPUs on the host system.
The -r option is mandatory and specifies the server root directory.
The resources served-up by drood are determined by the "Host" header of
- For every hostname you want to be recognized by the server, create an
identically-named subdirectory of the server root directory.
- Place the files for each virtual host into its identically-named
- Name one directory "default". This directory is used to fulfill static
requests when no "Host" header is supplied by a client (eg., HTTP/1.0
requests). You can make this directory a symbolic link.
- If you want a directory to be used for more than one hostname, create
symbolic links for the extra hostnames.
An example root directory follows. Only the first entry is an actual
virtual host subdirectory. The rest are links to it.
mammothcheese.ca -> actual subdirectory (IPv4)
www.mammothcheese.ca -> link to above (IPv4)
default -> link (IPv4/IPv6 HTTP/1.0)
If you want to accept connections specified by IP address,
include links for valid addresses:
184.108.40.206 -> link (IPv4 Decimal)
127.0.0.1 -> link (IPv4 Loopback)
If you want to accept IPv6 connections, add entries with the hostname
delimited by square brackets per RFC3986:
[mammothcheese.ca] -> link for IPv6 connections
[www.mammothcheese.ca] -> link for IPv6 connections
[::ffff:220.127.116.11] -> link
[::1] -> link (IPv6 Loopback)
If you instruct drood to listen on a port other than port 80 (-p option),
that port number appears in client "Host" headers. Adjust
your entries accordingly:
mammothcheese.ca:8080 -> actual subdirectory (IPv4)
www.mammothcheese.ca:8080 -> link to above
The root resource of all virtual hosts defaults to a static resource named
"index.html", which may be a link. Change the name of the resource with
the -e option. This value specified names the root resource of all virtual
hosts. The value must not begin with a virgule: /.
If a request is received for any directory, that request is interpreted as
a request for the root resource residing in the directory.
You can specify a dynamic resource as the root resource with the -e
option. If you do so, include the -d option to tell the server where
SCGI programs live.
drood -r /usr/local/www/drood -d cgi-bin -e cgi-bin/index.cgi
The -c option causes drood to reject cross-origin HTTP/1.1 requests for
all static resources except those whose filenames end with .html or .tar.gz.
The -d option specifies a virtual directory that is used in URLS to specify
SCGI and WebSocket requests. The value given to this option cannot contain
the directory separator character "/", nor can it be ".." or ".". This
directory is a virtual entity and should not exist in the filesystem.
All virtual hosts share the SCGI virtual directory. If you want to know
what hostname a server has been invoked for, examine the SERVER_NAME
environment variable. If no "Host" header was supplied with a request,
SERVER_NAME is set to the string "default".
- SCGI responses must contain a "Content-Type" or "Location" header and be
separated from response bodies with a blank line. Other headers are
optional and are unaltered by drood.
- DO NOT send Status headers. Drood creates its own status headers.
- If a "Location" header is present, drood creates a "303 See Other" status
- If no "Location" header is present, drood creates a "200 OK" status header.
- Always send response bodies unless your responses contain Location headers.
Report errors to clients in HTML response bodies.
- If an SCGI server does not send a Content-Length header and the client
request is an HTTP/1.1 request, then drood automatically adds the
"Transfer-Encoding: chunked" header and chunks the response body
for the client.
Requests for SCGI resources must include the SCGI path in their URLs
because this is how drood differentiates static requests from dynamic
requests. If -d is "cgi-bin", then the following is a request to run
The following environment variables are set for SCGI programs. Drood
does not propagate cookies to SCGI servers because drood is an insecure
If the client can receive gzipped data, GZIP is set to 1. If the client
cannot receive gzipped data, GZIP is set to 0. If an SCGI server gzips
its output, the program must generate a
header to notify clients of the encoding.
The -s option informs drood what dynamic resources are supplied by SCGI and
Drood uses the suffixes of dynamic resources to determine which resources
are forwarded to which servers. You register each suffix to be forwarded
with a separate -s option.
Each option value has this form: <host>|<port>|<suffix>.
- <host> is the hostname of the SCGI server or its IP address.
- <port> is the port number the SCGI server is listening on.
- <suffix> is the filename suffix to associate with this SCGI server.
The suffix value must not contain a dot.
Requests for items in the SCGI directory whose filenames are terminated
by <suffix> are forwarded to the SCGI server at <host> listening on
For example, to forward all requests whose URLs match this pattern
to a local server running on port 4000, use the following command line.
Note that it is necessary to quote the -s option value to prevent the shell
from interpreting it as a pipeline.
drood -d cgi-bin -s 127.0.0.1|4000|scgi
To specify a UNIX-domain SCGI server, leave the <host> part empty, and put
the absolute path to the listening socket in the <port> part.
drood -d cgi-bin -s |/full/path/to/socket|scgi
To specify a TCP WebSocket server, prepend "ws:<protocols>:" to the hostname or
IP address of the server. The <protocols> field may be empty.
drood -d cgi-bin -s ws::127.0.0.1|8000|echo
To specify a UNIX-domain WebSocket server, leave the hostname out of the
<host> part and put the absolute path to the listening socket into
the <port> part.
drood -d cgi-bin -s ws::|/var/run/echo.socket|echo
If you want to specify the sub-protocols that a WebSocket server
supports, place the list of sub-protocols into the <protocols> part of the
<host> field. Protocol names must be listed in order of priority and must
be separated by commas.
Drood completes the WebSocket handshake and connects to the WebSocket
server. Drood then sends to the server 2 newline-terminated lines.
The first line names the virtual host to which the client submitted its
request. The second line names the sub-protocol selected during the
After sending the protocol line, drood exchanges data between the client
and the WebSocket server for the lifetime of the connection. Drood does
not modify the exchanged data in any way. WebSocket servers are
responsible for implementing the WebSocket protocol to commmunicate with
The -p option specifies the port to listen on. This defaults to 80.
The -i option limits drood to accepting connections only from a specified
interface. Supply the IP address of the desired interface as argument. By
default, drood accepts connections on all interfaces capable of IPv4 or
The -u and the -g options specify the user and group of drood server
processes. If not specified, both values default to "nobody".
The -t option specifies the value of the read timeout in seconds. When
reading a request from a client, drood drops the connection if it cannot
read the complete request header within 20 seconds. To change this value,
provide a number in the range of 1-60 as argument.
The -w option specifies the value of the write timeout in minutes. When
writing a response to a client, drood drops the connection if 60 minutes
have elapsed. To change this value provide a number in range of 0-120
minutes as argument. Setting this value to 0 disables the write timeout.
The -x option prevents drood from becoming a daemon. Drood runs in the
foreground of the terminal where it was started and is stopped with signals
(ie., Control-C). When the -x option is present, drood does not write its
pid to /var/run/drood.pid.
The -l option turns-on request logging. The option specifies the
fully-qualified filename of a file to hold the log. If the file does not
exist, drood attempts to create it. The file or the directory in which
it resides must be writeable drood at startup before it changes to the user
and group specified by the -u and -g options.
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 requests are 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
- The date and time of the request with this strftime(3) format.
%a, %d %b %Y %H:%M:%S %Z
- The client IP address. The IP address is expressed in IPv6
presentation format. IPv4 clients addresses are written as IPv4-mapped
- The request User-Agent header or "no user-agent header".
- The request method
- The request URL
- The request Referer (sic) header or "no referrer header".
Add the following line to /usr/local/etc/newsyslog.conf.d/newsyslog.conf to
instruct newsyslog(8) to turn over the request log every night at midnight.
The five most recent logfiles are renamed and kept on-hand.
/var/log/drood-requests.log 600 5 * @T00 B /var/run/drood.pid
Do use the B option. Do not use the Z option. The B option prevents
newsyslog from inserting a turnover message and timestamp at the end of the
old logfile. The Z option instructs newsyslog to compress the old logfile.
When drood restarts, new processes use the new logfile, but old processes
that use the old logfile may persist until all active connections have been
.An James Bailie Aq firstname.lastname@example.org
Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.