commit b9220ca4de556f24be9cdc0d478109b75cd476ae from: Omar Polo date: Mon Jan 11 12:51:25 2021 UTC new README + wording in manpage commit - 85dff1f9c3b18256f0f2cceb802c3c7f2961bc58 commit + b9220ca4de556f24be9cdc0d478109b75cd476ae blob - 13cfae04d8424a84283849e46e75d981bb271bf1 blob + 76f05bd5b384c8a23073a5d6f29ba5a0312c16a1 --- Makefile +++ Makefile @@ -12,9 +12,6 @@ gmid: gmid.o uri.o utf8.o TAGS: gmid.c uri.c utf8.c -etags gmid.c uri.c utf8.c || true -README.md: gmid.1 - mandoc -Tmarkdown gmid.1 | sed -e '1d' -e '$$d' > README.md - clean: rm -f *.o gmid blob - 51404f0154370f3b3d14825214890a69d5a62e2d blob + 46976242229fcc2afb4513eab4d8256befb95e2d --- README.md +++ README.md @@ -1,235 +1,55 @@ +# gmid -# NAME +> dead simple, zero configuration Gemini server -**gmid** - dead simple zero configuration gemini server +gmid is a simple and minimal Gemini server. It requires no +configuration whatsoever so it's well suited for local development +machines. -# SYNOPSIS +Care has been taken to assure that gmid doesn't serve files outside +the given directory, and it won't follow symlinks. Furthermore, on +OpenBSD, gmid is also `pledge(2)`ed and `unveil(2)`ed: the set of +pledges are `stdio rpath inet`, with the addition of `proc exec` if +CGI scripts are enabled, while the given directory is unveiled with +`rx`. -**gmid** -\[**-6fh**] -\[**-c** *cert.pem*] -\[**-d** *docs*] -\[**-k** *key.pem*] -\[**-p** *port*] -\[**-x** *cgi-bin*] -# DESCRIPTION +## Features -**gmid** -is a very simple and minimal gemini server that can serve static files -and execute CGI scripts. + - IRI support (RFC RFC3987) + - dual stack: can serve over both IPv4 and IPv6 + - CGI scripts + - (very) low memory footprint + - small codebase, easily hackable -**gmid** -won't serve files outside the given directory and won't follow -symlinks. -Furthermore, on -OpenBSD, -pledge(2) -and -unveil(2) -are used to ensure that -**gmid** -dosen't do anything else than read files from the given directory, -accept network connections and, optionally, execute CGI scripts. -**gmid** -fully supports IRIs (Internationalized Resource Identifiers, see -RFC3987). +## Planned features -It should be noted that -**gmid** -is very simple in its implementation, and so it may not be appropriate -for serving sites with lots of users. -After all, the code is single threaded and use a single process, -although it can handle multiple clients at the same time. + - virtual hosts -If a user request path is a directory, -**gmid** -will try to serve a -*index.gmi* -file inside that directory. -The options are as follows: +## Drawbacks -**-6** + - not suited for very busy hosts. If you receive an high number of + connection per-second you'd probably want to run multiple gmid + instances behind relayd/haproxy or a different server. -> Enable IPv6. -**-c** *cert.pem* +## Building -> The certificate to use, by default is -> *cert.pem*. +gmid depends a POSIX libc and libtls. It can probably be linked +against libretls, but I've never tried. -**-d** *docs* +See [INSTALL.gmi](INSTALL.gmi) for more info, but the build is as +simple as -> The root directory to serve. -> **gmid** -> won't serve any file that is outside that directory. -> By default is -> *docs*. + make -**-f** +The Makefile isn't able to produce a statically linked executable +(yet), so for that you have to execute by hand -> stays and log in the foreground, do not daemonize the process. + make + cc -static *.o /usr/lib/lib{crypto,tls,ssl}.a -o gmid + strip gmid -**-h** - -> Print the usage and exit. - -**-k** *key.pem* - -> The key for the certificate, by default is -> *key.pem*. - -**-p** *port* - -> The port to bind to, by default 1965. - -**-x** *dir* - -> Enable execution of CGI scripts inside the given directory (relative -> to the document root.) Cannot be provided more than once. - -# CGI - -When CGI scripts are enabled for a directory, a request for an -executable file will execute it and fed its output to the client. - -The CGI scripts will inherit the environment from -**gmid** -with these additional variables set: - -`SERVER_SOFTWARE` - -> "gmid" - -`SERVER_PORT` - -> "1965" - -`SCRIPT_NAME` - -> The (public) path to the script. - -`SCRIPT_EXECUTABLE` - -> The full path to the executable. - -`REQUEST_URI` - -> The user request (without the query parameters.) - -`REQUEST_RELATIVE` - -> The request relative to the script. - -`QUERY_STRING` - -> The query parameters. - -`REMOTE_HOST` - -> The remote IP address. - -`REMOTE_ADDR` - -> The remote IP address. - -`DOCUMENT_ROOT` - -> The root directory being served, the one provided with the -> *d* -> parameter to -> **gmid** - -`AUTH_TYPE` - -> The string "Certificate" if the client used a certificate, otherwise unset. - -`REMOTE_USER` - -> The subject of the client certificate if provided, otherwise unset. - -`TLS_CLIENT_ISSUER` - -> The is the issuer of the client certificate if provided, otherwise unset. - -`TLS_CLIENT_HASH` - -> The hash of the client certificate if provided, otherwise unset. -> The format is "ALGO:HASH". - -Let's say you have a script in -*/cgi-bin/script* -and the user request is -*/cgi-bin/script/foo/bar?quux*. -Then -`SCRIPT_NAME` -will be -*/cgi-bin/script*, -`SCRIPT_EXECUTABLE` -will be -*$DOCUMENT\_ROOT/cgi-bin/script*, -`REQUEST_URI` -will be -*/cgi-bin/script/foo/bar*, -`REQUEST_RELATIVE` -will be -*foo/bar and* -`QUERY_STRING` -will be -*quux*. - -# EXAMPLES - -To quickly getting started - - $ # generate a cert and a key - $ openssl req -x509 -newkey rsa:4096 -keyout key.pem \ - -out cert.pem -days 365 -nodes - $ mkdir docs - $ cat < docs/index.gmi - # Hello world - test paragraph... - EOF - $ gmid -c cert.pem -k key.pem -d docs - -Now you can visit gemini://localhost/ with your preferred gemini -client. - -To add some CGI scripts, assuming a setup similar to the previous -example, you can - - $ mkdir docs/cgi-bin - $ cat < docs/cgi-bin/hello-world - #!/bin/sh - printf "20 text/plain\r\n" - echo "hello world!" - EOF - $ gmid -x cgi-bin - -Note that the argument to the -**-x** -option is -*cgi-bin* -and not -*docs/cgi-bin*, -since it's relative to the document root. - -# ACKNOWLEDGEMENTS - -**gmid** -uses the "Flexible and Economical" UTF-8 decoder written by -Bjoern Hoehrmann. - -# CAVEATS - -* it doesn't support virtual hosts: the host part of the request URL is - completely ignored. - -* a %2F sequence in the path part is indistinguishable from a literal - slash: this is not RFC3986-compliant. - -* a %00 sequence either in the path or in the query part is treated as - invalid character and thus rejected. - +to enjoy your ~2.3M statically-linked gmid. blob - f14d0aaff13a268a3261ec1e593e9ada3143277b blob + 46d2407e61b9dfeccfa9e8aa1523a1d735f3ec20 --- gmid.1 +++ gmid.1 @@ -29,8 +29,8 @@ .Ek .Sh DESCRIPTION .Nm -is a very simple and minimal gemini server that can serve static files -and execute CGI scripts. +is a simple and minimal gemini server that can serve static files and +execute CGI scripts. .Pp .Nm won't serve files outside the given directory and won't follow @@ -137,16 +137,17 @@ and the user request is Then .Ev SCRIPT_NAME will be -.Pa /cgi-bin/script , +.Pa cgi-bin/script , .Ev SCRIPT_EXECUTABLE will be .Pa $DOCUMENT_ROOT/cgi-bin/script , .Ev REQUEST_URI will be -.Pa /cgi-bin/script/foo/bar , +.Pa cgi-bin/script/foo/bar , .Ev REQUEST_RELATIVE will be -.Pa foo/bar and +.Pa foo/bar +and .Ev QUERY_STRING will be .Ar quux .