Blob


1 .\" Copyright (c) 2021, 2022 Omar Polo <op@omarpolo.com>
2 .\"
3 .\" Permission to use, copy, modify, and distribute this software for any
4 .\" purpose with or without fee is hereby granted, provided that the above
5 .\" copyright notice and this permission notice appear in all copies.
6 .\"
7 .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 .Dd $Mdocdate: January 02 2022$
15 .Dt GMID 1
16 .Os
17 .Sh NAME
18 .Nm gmid
19 .Nd simple and secure Gemini server
20 .Sh SYNOPSIS
21 .Nm
22 .Bk -words
23 .Op Fl fnv
24 .Op Fl c Ar config
25 .Op Fl D Ar macro Ns = Ns Ar value
26 .Op Fl P Ar pidfile
27 .Ek
28 .Nm
29 .Bk -words
30 .Op Fl 6hVv
31 .Op Fl d Pa certs-dir
32 .Op Fl H Ar hostname
33 .Op Fl p Ar port
34 .Op Fl x Pa cgi
35 .Op Pa dir
36 .Ek
37 .Sh DESCRIPTION
38 .Nm
39 is a simple and minimal gemini server that can serve static files,
40 execute CGI scripts and talk to FastCGI applications.
41 It can run without a configuration file with a limited set of features
42 available.
43 .Pp
44 .Nm
45 rereads the configuration file when it receives
46 .Dv SIGHUP .
47 .Pp
48 The options are as follows:
49 .Bl -tag -width 14m
50 .It Fl c Pa config
51 Specify the configuration file.
52 .It Fl D Ar macro Ns = Ns Ar value
53 Define
54 .Ar macro
55 to be set to
56 .Ar value
57 on the command line.
58 Overrides the definition of
59 .Ar macro
60 in the config file if present.
61 .It Fl f
62 Stays and logs on the foreground.
63 .It Fl n
64 Check that the configuration is valid, but don't start the server.
65 If specified two or more time, dump the configuration in addition to
66 verify it.
67 .It Fl P Pa pidfile
68 Write daemon's pid to the given location.
69 .Ar pidfile
70 will also act as lock: if another process is holding a lock on that
71 file,
72 .Nm
73 will refuse to start.
74 .El
75 .Pp
76 If no configuration file is given,
77 .Nm
78 runs in
79 .Dq config-less mode
80 .Pq i.e. runs in the foreground to serve a directory from the shell
81 and looks for the following options
82 .Bl -tag -width 14m
83 .It Fl 6
84 Enable IPv6.
85 .It Fl d Pa certs-path
86 Directory where certificates for the config-less mode are stored.
87 By default it is
88 .Pa $XDG_DATA_HOME/gmid ,
89 i.e.
90 .Pa ~/.local/share/gmid .
91 .It Fl H Ar hostname
92 The hostname
93 .Po
94 .Ar localhost
95 by default
96 .Pc .
97 Certificates for the given
98 .Ar hostname
99 are searched inside the
100 .Pa certs-dir
101 directory given with the
102 .Fl d
103 option.
104 They have the form
105 .Pa hostname.cert.pem
106 and
107 .Pa hostname.key.pem .
108 If a certificate or a key doesn't exist for a given hostname, they
109 will be generated automatically.
110 .It Fl h , Fl -help
111 Print the usage and exit.
112 .It Fl p Ar port
113 The port to listen on, by default 1965.
114 .It Fl V , Fl -version
115 Print the version and exit.
116 .It Fl v
117 Verbose mode.
118 Multiple
119 .Fl v
120 options increase the verbosity.
121 .It Fl x Pa path
122 Enable execution of
123 .Sx CGI
124 scripts.
125 See the description of the
126 .Ic cgi
127 option in the
128 .Sq Servers
129 section below to learn how
130 .Pa path
131 is processed.
132 Cannot be provided more than once.
133 .It Pa dir
134 The root directory to serve.
135 By default the current working directory is assumed.
136 .El
137 .Sh CONFIGURATION FILE
138 The configuration file is divided into three sections:
139 .Bl -tag -width xxxx
140 .It Sy Macros
141 User-defined variables may be defined and used later, simplifying the
142 configuration file.
143 .It Sy Global Options
144 Global settings for
145 .Nm .
146 .It Sy Servers
147 Virtual hosts definition.
148 .El
149 .Pp
150 Within the sections, empty lines are ignored and comments can be put
151 anywhere in the file using a hash mark
152 .Pq Sq # ,
153 and extend to the end of the current line.
154 A boolean is either the symbol
155 .Sq on
156 or
157 .Sq off .
158 A string is a sequence of characters wrapped in double quotes,
159 .Dq like this .
160 Multiple strings one next to the other are joined into a single
161 string:
162 .Bd -literal -offset indent
163 # equivalent to "temporary-failure"
164 block return 40 "temporary" "-" "failure"
165 .Ed
166 .Pp
167 Furthermore, quoting is necessary only when a string needs to contain
168 special characters
169 .Pq like spaces or punctuation ,
170 something that looks like a number or a reserved keyword.
171 The last example could have been written also as:
172 .Bd -literal -offset indent
173 block return 40 temporary "-" failure
174 .Ed
175 .Pp
176 Strict ordering of the sections is not enforced, so that is possible
177 to mix macros, options and
178 .Ic server
179 blocks.
180 However, defining all the
181 .Ic server
182 blocks after the macros and the global options is recommended.
183 .Pp
184 Newlines are often optional, except around top-level instructions, and
185 semicolons
186 .Dq \&;
187 can also be optionally used to separate options.
188 .Pp
189 Additional configuration files can be included with the
190 .Ic include
191 keyword, for example:
192 .Bd -literal -offset indent
193 include "/etc/gmid.conf.local"
194 .Ed
195 .Ss Macros
196 Macros can be defined that will later be expanded in context.
197 Macro names must start with a letter, digit or underscore and may
198 contain any of those characters.
199 Macros names may not be reserved words.
200 Macros are not expanded inside quotes.
201 .Pp
202 Two kinds of macros are supported: variable-like and proper macros.
203 When a macro is invoked with a
204 .Dq $
205 before its name its expanded as a string, whereas when it's invoked
206 with a
207 .Dq @
208 its expanded in-place.
209 .Pp
210 For example:
211 .Bd -literal -offset indent
212 dir = "/var/gemini"
213 certdir = "/etc/keys"
214 common = "lang it; auto index on"
216 server "foo" {
217 root $dir "/foo" # -> /var/gemini/foo
218 cert $certdir "/foo.crt" # -> /etc/keys/foo.crt
219 key $certdir "/foo.pem" # -> /etc/keys/foo.pem
220 @common
222 .Ed
223 .Ss Global Options
224 .Bl -tag -width 12m
225 .It Ic chroot Pa path
226 .Xr chroot 2
227 the process to the given
228 .Pa path .
229 The daemon has to be run with root privileges and thus the option
230 .Ic user
231 needs to be provided, so privileges can be dropped.
232 Note that
233 .Nm
234 will enter the chroot after loading the TLS keys, but before opening
235 the virtual host root directories.
236 It's recommended to keep the TLS keys outside the chroot.
237 Future version of
238 .Nm
239 may enforce this.
240 .It Ic ipv6 Ar bool
241 Enable or disable IPv6 support, off by default.
242 .It Ic map Ar mime-type Cm to-ext Ar file-extension
243 Map
244 .Ar mime-type
245 to the given
246 .Ar file-extension .
247 Both argument are strings.
248 .It Ic port Ar portno
249 The port to listen on.
250 1965 by default.
251 .It Ic prefork Ar number
252 Run the specified number of server processes.
253 This increases the performance and prevents delays when connecting to
254 a server.
255 When not in config-less mode,
256 .Nm
257 runs 3 server processes by default.
258 The maximum number allowed is 16.
259 .It Ic protocols Ar string
260 Specify the TLS protocols to enable.
261 Refer to
262 .Xr tls_config_parse_protocols 3
263 for the valid protocol string values.
264 By default, both TLSv1.3 and TLSv1.2 are enabled.
265 Use
266 .Dq tlsv1.3
267 to enable only TLSv1.3.
268 .It Ic user Ar string
269 Run the daemon as the given user.
270 .El
271 .Ss Servers
272 Every virtual host is defined by a
273 .Ic server
274 block:
275 .Bl -tag -width Ds
276 .It Ic server Ar hostname Brq ...
277 Match the server name using shell globbing rules.
278 It can be an explicit name,
279 .Ar www.example.com ,
280 or a name including a wildcards,
281 .Ar *.example.com .
282 .El
283 .Pp
284 Followed by a block of options that is enclosed in curly brackets:
285 .Bl -tag -width Ds
286 .It Ic alias Ar name
287 Specify an additional alias
288 .Ar name
289 for this server.
290 .It Ic auto Ic index Ar bool
291 If no index file is found, automatically generate a directory listing.
292 Disabled by default.
293 .It Ic block Op Ic return Ar code Op Ar meta
294 Send a reply and close the connection;
295 by default
296 .Ar code
297 is 40
298 and
299 .Ar meta
300 is
301 .Dq temporary failure .
302 If
303 .Ar code
304 is in the 3x range, then
305 .Ar meta
306 is mandatory.
307 Inside
308 .Ar meta ,
309 the following special sequences are supported:
310 .Bl -tag -width Ds -compact
311 .It \&%\&%
312 is replaced with a single
313 .Sq \&% .
314 .It \&%p
315 is replaced with the request path.
316 .It \&%q
317 is replaced with the query string of the request.
318 .It \&%P
319 is replaced with the server port.
320 .It \&%N
321 is replaced with the server name.
322 .El
323 .It Ic cert Pa file
324 Path to the certificate to use for this server.
325 The
326 .Pa file
327 should contain a PEM encoded certificate.
328 This option is mandatory.
329 .It Ic cgi Pa path
330 Execute
331 .Sx CGI
332 scripts that matches
333 .Pa path
334 using shell globbing rules.
335 .It Ic default type Ar string
336 Set the default media type that is used if the media type for a
337 specified extension is not found.
338 If not specified, the
339 .Ic default type
340 is set to
341 .Dq application/octet-stream .
342 .It Ic entrypoint Pa path
343 Handle all the requests for the current virtual host using the
344 .Sx CGI
345 script at
346 .Pa path ,
347 relative to the current document root.
348 .It Ic env Ar name Cm = Ar value
349 Set the environment variable
350 .Ar name
351 to
352 .Ar value
353 when executing CGI scripts.
354 Can be provided more than once.
355 .\" don't document the "spawn <prog>" form because it probably won't
356 .\" be kept.
357 .It Ic fastcgi Oo Ic tcp Oc Pa socket Oo Cm port Ar port Oc
358 Enable
359 .Sx FastCGI
360 instead of serving files.
361 The
362 .Pa socket
363 can either be a UNIX-domain socket or a TCP socket.
364 If the FastCGI application is listening on a UNIX domain socket,
365 .Pa socket
366 is a local path name within the
367 .Xr chroot 2
368 root directory of
369 .Nm .
370 Otherwise, the
371 .Ic tcp
372 keyword must be provided and
373 .Pa socket
374 is interpreted as a hostname or an IP address.
375 .Ar port
376 can be either a port number or the name of a service enclosed in
377 double quotes.
378 If not specified defaults to 9000.
379 .It Ic index Ar string
380 Set the directory index file.
381 If not specified, it defaults to
382 .Pa index.gmi .
383 .It Ic key Pa file
384 Specify the private key to use for this server.
385 The
386 .Pa file
387 should contain a PEM encoded private key.
388 This option is mandatory.
389 .It Ic lang Ar string
390 Specify the language tag for the text/gemini content served.
391 If not specified, no
392 .Dq lang
393 parameter will be added in the response.
394 .It Ic location Pa path Brq ...
395 Specify server configuration rules for a specific location.
396 The
397 .Pa path
398 argument will be matched against the request path with shell globbing
399 rules.
400 In case of multiple location statements in the same context, the first
401 matching location will be put into effect and the later ones ignored.
402 Therefore is advisable to match for more specific paths first and for
403 generic ones later on.
405 .Ic location
406 section may include most of the server configuration rules
407 except
408 .Ic alias , Ic cert , Ic cgi , Ic entrypoint , Ic env , Ic key ,
409 .Ic location , Ic param No and Ic proxy .
410 .It Ic log Ar bool
411 Enable or disable the logging for the current server or location block.
412 .It Ic param Ar name Cm = Ar value
413 Set the param
414 .Ar name
415 to
416 .Ar value
417 for FastCGI.
418 .It Ic ocsp Ar file
419 Specify an OCSP response to be stapled during TLS handshakes
420 with this server.
421 The
422 .Ar file
423 should contain a DER-format OCSP response retrieved from an
424 OCSP server for the
425 .Ic cert
426 in use.
427 If the OCSP response in
428 .Ar file
429 is empty, OCSP stapling will not be used.
430 The default is to not use OCSP stapling.
431 .It Ic proxy Oo Cm proto Ar name Oc Oo Cm for-host Ar host : Ns Oo Ar port Oc Oc Brq ...
432 Set up a reverse proxy.
433 The optional matching rules
434 .Cm proto
435 and
436 .Cm for-host
437 can be used to enable proxying only for protocols matching
438 .Ar name
439 .Po Dq gemini
440 by default
441 .Pc
442 and/or whose request IRI matches
443 .Ar host
444 and
445 .Ar port
446 .Pq 1965 by default .
447 Matching happens using shell globbing rules.
448 .Pp
449 In case of multiple matching proxy blocks in the same context, the
450 first matching proxy will be put into effect and the later ones
451 ignored.
452 .Pp
453 Valid options are:
454 .Bl -tag -width Ds
455 .It Ic cert Ar file
456 Specify the client certificate to use when making requests.
457 .It Ic key Ar file
458 Specify the client certificate key to use when making requests.
459 .It Ic protocols Ar string
460 Specify the TLS protocols allowed when making remote requests.
461 Refer to the
462 .Xr tls_config_parse_protocols 3
463 function for the valid protocol string values.
464 By default, both TLSv1.2 and TLSv1.3 are enabled.
465 .It Ic relay-to Ar host : Ns Op Ar port
466 Relay the request to the given
467 .Ar host
468 at the given
469 .Ar port ,
470 1965 by default.
471 This is the only mandatory option in a
472 .Ic proxy
473 block.
474 .It Ic require Ic client Ic ca Ar file
475 Allow the proxying only from clients that provide a certificate
476 signed by the CA certificate in
477 .Ar file .
478 .It Ic use-tls Ar bool
479 Specify whether to use TLS when connecting to the proxied host.
480 Enabled by default.
481 .It Ic verifyname Ar bool
482 Enable or disable the TLS server name verification.
483 Enabled by default.
484 .El
485 .It Ic root Pa directory
486 Specify the root directory for this server
487 .Pq alas the current Dq document root .
488 It's relative to the chroot if enabled.
489 .It Ic require Ic client Ic ca Pa path
490 Allow requests only from clients that provide a certificate signed by
491 the CA certificate in
492 .Pa path .
493 It needs to be a PEM-encoded certificate and it's not relative to the
494 chroot.
495 .It Ic strip Ar number
496 Strip
497 .Ar number
498 components from the beginning of the path before doing a lookup in the
499 root directory.
500 It's also considered for the
501 .Ar meta
502 parameter in the scope of a
503 .Ic block return .
504 .El
505 .Sh CGI
506 When a request for an executable file matches the
507 .Ic cgi
508 rule, that file will be executed and its output fed to the client.
509 .Pp
510 The CGI scripts are executed in the directory they reside and inherit
511 the environment from
512 .Nm
513 with these additional variables set:
514 .Bl -tag -width 24m
515 .It Ev GATEWAY_INTERFACE
516 .Dq CGI/1.1
517 .It Ev GEMINI_DOCUMENT_ROOT
518 The root directory of the virtual host.
519 .It Ev GEMINI_SCRIPT_FILENAME
520 Full path to the CGI script being executed.
521 .It Ev GEMINI_URL
522 The full IRI of the request.
523 .It Ev GEMINI_URL_PATH
524 The path of the request.
525 .It Ev PATH_INFO
526 The portion of the requested path that is derived from the the IRI
527 path hierarchy following the part that identifies the script itself.
528 Can be unset.
529 .It Ev PATH_TRANSLATED
530 Present if and only if
531 .Ev PATH_INFO
532 is set.
533 It represent the translation of the
534 .Ev PATH_INFO .
535 .Nm
536 builds this by appending the
537 .Ev PATH_INFO
538 to the virtual host directory root.
539 .It Ev QUERY_STRING
540 The decoded query string.
541 .It Ev REMOTE_ADDR , Ev REMOTE_HOST
542 Textual representation of the client IP.
543 .It Ev REQUEST_METHOD
544 This is present only for RFC3875 (CGI) compliance.
545 It's always set to the empty string.
546 .It Ev SCRIPT_NAME
547 The part of the
548 .Ev GEMINI_URL_PATH
549 that identifies the current CGI script.
550 .It Ev SERVER_NAME
551 The name of the server
552 .It Ev SERVER_PORT
553 The port the server is listening on.
554 .It Ev SERVER_PROTOCOL
555 .Dq GEMINI
556 .It Ev SERVER_SOFTWARE
557 The name and version of the server, i.e.
558 .Dq gmid/1.7.3
559 .It Ev AUTH_TYPE
560 The string "Certificate" if the client used a certificate, otherwise
561 unset.
562 .It Ev REMOTE_USER
563 The subject of the client certificate if provided, otherwise unset.
564 .It Ev TLS_CLIENT_ISSUER
565 The is the issuer of the client certificate if provided, otherwise
566 unset.
567 .It Ev TLS_CLIENT_HASH
568 The hash of the client certificate if provided, otherwise unset.
569 The format is
570 .Dq ALGO:HASH .
571 .It Ev TLS_VERSION
572 The TLS version negotiated with the peer.
573 .It Ev TLS_CIPHER
574 The cipher suite negotiated with the peer.
575 .It Ev TLS_CIPHER_STRENGTH
576 The strength in bits for the symmetric cipher that is being used with
577 the peer.
578 .It Ev TLS_CLIENT_NOT_AFTER
579 The time corresponding to the end of the validity period of the peer
580 certificate in the ISO 8601 format
581 .Pq e.g. Dq 2021-02-07T20:17:41Z .
582 .It Ev TLS_CLIENT_NOT_BEFORE
583 The time corresponding to the start of the validity period of the peer
584 certificate in the ISO 8601 format.
585 .El
586 .Sh FastCGI
587 .Nm
588 optionally supports FastCGI.
590 .Ic fastcgi
591 rule must be present in a server or location block.
592 Then, all requests matching that server or location will be handled
593 via the specified FastCGI backend.
594 .Pp
595 By default the following variables
596 .Pq parameters
597 are sent, and carry the same semantics as with CGI.
598 More parameters can be added with the
599 .Ic param
600 option.
601 .Pp
602 .Bl -bullet -compact
603 .It
604 GATEWAY_INTERFACE
605 .It
606 GEMINI_URL_PATH
607 .It
608 QUERY_STRING
609 .It
610 REMOTE_ADDR
611 .It
612 REMOTE_HOST
613 .It
614 REQUEST_METHOD
615 .It
616 SERVER_NAME
617 .It
618 SERVER_PROTOCOL
619 .It
620 SERVER_SOFTWARE
621 .It
622 AUTH_TYPE
623 .It
624 REMOTE_USER
625 .It
626 TLS_CLIENT_ISSUER
627 .It
628 TLS_CLIENT_HASH
629 .It
630 TLS_VERSION
631 .It
632 TLS_CIPHER
633 .It
634 TLS_CIPHER_STRENGTH
635 .It
636 TLS_CLIENT_NOT_BEFORE
637 .It
638 TLS_CLIENT_NOT_AFTER
639 .El
640 .Sh MIME
641 To auto-detect the MIME type of the response
642 .Nm
643 looks at the file extension and consults its internal table.
644 By default the following mappings are loaded, but they can be
645 overridden or extended using the
646 .Ic map
647 configuration option.
648 If no MIME is found, the value of
649 .Ic default type
650 matching the file
651 .Ic location
652 will be used, which is
653 .Dq application/octet-stream
654 by default.
655 .Pp
656 .Bl -tag -offset indent -width 14m -compact
657 .It diff
658 text/x-patch
659 .It gemini, gmi
660 text/gemini
661 .It gif
662 image/gif
663 .It jpeg
664 image/jpeg
665 .It jpg
666 image/jpeg
667 .It markdown, md
668 text/markdown
669 .It patch
670 text/x-patch
671 .It pdf
672 application/pdf
673 .It png
674 image/png
675 .It svg
676 image/svg+xml
677 .It txt
678 text/plain
679 .It xml
680 text/xml
681 .El
682 .Sh LOGGING
683 Messages and requests are logged by
684 .Xr syslog 3
685 using the
686 .Dv DAEMON
687 facility or printed on
688 .Em stderr .
689 .Pp
690 Requests are logged with the
691 .Dv NOTICE
692 severity.
693 Each request log entry has the following fields, separated by
694 whitespace:
695 .Pp
696 .Bl -bullet -compact
697 .It
698 Client IP address and the source port number, separated by a colon
699 .It
700 .Sy GET
701 keyword
702 .It
703 Request URL
704 .It
705 Response status
706 .It
707 Response meta
708 .El
709 .Sh EXAMPLES
710 Serve the current directory
711 .Bd -literal -offset indent
712 $ gmid .
713 .Ed
714 .Pp
715 To serve the directory
716 .Pa docs
717 and enable CGI scripts inside
718 .Pa docs/cgi
719 .Bd -literal -offset indent
720 $ mkdir docs/cgi
721 $ cat <<EOF > docs/cgi/hello
722 #!/bin/sh
723 printf "20 text/plain\er\en"
724 echo "hello world"
725 EOF
726 $ chmod +x docs/cgi/hello
727 $ gmid -x '/cgi/*' docs
728 .Ed
729 .Pp
730 An X.509 certificate must be provided to run
731 .Nm
732 using a configuration file.
733 First, the RSA certificate is created using a wildcard common name:
734 .Bd -literal -offset indent
735 # openssl genrsa \-out /etc/ssl/private/example.com.key 4096
736 # openssl req \-new \-x509 \e
737 \-key /etc/ssl/private/example.com.key \e
738 \-out /etc/ssl/example.com.crt \e
739 \-days 36500 \-nodes \e
740 \-subj "/CN=example.com"
741 # chmod 600 /etc/ssl/example.com.crt
742 # chmod 600 /etc/ssl/private/example.com.key
743 .Ed
744 .Pp
745 In the example above, a certificate is valid for one hundred years from
746 the date it was created, which is normal for TOFU.
747 .Pp
748 The following is an example of a possible configuration for a site
749 that enables only TLSv1.3, adds a mime type for the file extension
750 .Qq rtf
751 and defines two virtual host:
752 .Bd -literal -offset indent
753 ipv6 on # enable ipv6
755 protocols "tlsv1.3"
757 map "application/rtf" to-ext "rtf"
759 server "example.com" {
760 cert "/etc/ssl/example.com.crt"
761 key "/etc/ssl/private/example.com.key"
762 root "/var/gemini/example.com"
765 server "it.example.com" {
766 cert "/etc/ssl/example.com.crt"
767 key "/etc/ssl/private/example.com.key"
768 root "/var/gemini/it.example.com"
770 # enable cgi scripts inside "cgi-bin"
771 cgi "/cgi-bin/*"
773 # set the language for text/gemini files
774 lang "it"
776 .Ed
777 .Pp
778 Yet another example, showing how to enable a
779 .Ic chroot
780 and use
781 .Ic location
782 rule
783 .Bd -literal -offset indent
784 chroot "/var/gemini"
785 user "_gmid"
787 server "example.com" {
788 cert "/path/to/cert.pem" # absolute path
789 key "/path/to/key.pem" # also absolute
790 root "/example.com" # relative to the chroot
792 location "/static/*" {
793 # load the following rules only for
794 # requests that matches "/static/*"
796 auto index on
797 index "index.gemini"
800 .Ed
801 .Sh ACKNOWLEDGEMENTS
802 .Nm
803 uses the
804 .Dq Flexible and Economical
805 UTF-8 decoder written by
806 .An Bjoern Hoehrmann .
807 .Sh AUTHORS
808 .An -nosplit
809 The
810 .Nm
811 program was written by
812 .An Omar Polo Aq Mt op@omarpolo.com .
813 .Sh CAVEATS
814 .Bl -bullet
815 .It
816 All the root directories are opened during the daemon startup; if a
817 root directory is deleted and then re-created,
818 .Nm
819 won't be able to serve files inside that directory until a restart.
820 This restriction only applies to the root directories and not their
821 content.
822 .It
823 a %2F sequence is indistinguishable from a literal slash: this is not
824 RFC3986-compliant.
825 .It
826 a %00 sequence is treated as invalid character and thus rejected.
827 .El