]> Sergey Matveev's repositories - godlighty.git/blob - doc/index.texi
4be54c80cd9b52126b205102ed5e9651aaa026d2
[godlighty.git] / doc / index.texi
1 \input texinfo
2 @documentencoding UTF-8
3 @settitle godlighty
4
5 @copying
6 Copyright @copyright{} 2021 @email{stargrave@@stargrave.org, Sergey Matveev}
7 @end copying
8
9 @node Top
10 @top godlighty
11
12 @command{godlighty} is highly-customizable HTTP, HTTP/2, HTTPS server
13 written on pure Go.
14
15 Why yet another web-server? Because all others suck even for my simple
16 ordinary needs: they use hateful OpenSSL, lacks documentation, has
17 complex configuration format, lack some features, hard to extend with.
18
19 @itemize
20
21 @item Rather minimalistic pure-Go web-server with few number of
22 dependencies, producing single statically linked executable. Maximal
23 reuse of native libraries capabilities.
24
25 @item Modern, reliable, secure and fast TLS 1.3 implementation with
26 ChaCha20-Poly1305, session resumption and SNI.
27
28 @item If built with @url{http://www.gostls13.cypherpunks.ru/, gostls13},
29 then @url{http://www.gost.cypherpunks.ru/, GOST} TLS 1.3 cryptography
30 will be fully supported, with ability to use GOST-based X.509
31 certificates if client announces its knowledge of GOST algorithms (with
32 the fallback to ordinary ECDSA ones).
33
34 @item HTTP/1.1, @url{https://en.wikipedia.org/wiki/HTTP%2F2, HTTP/2}
35 (only when negotiated during ALPN) and keepalives support. Graceful
36 shutdowns.
37
38 @item @code{gzip} and @url{https://facebook.github.io/zstd/, Zstandard}
39 compression on-the-fly.
40
41 @item @code{Range}, @code{ETag} (based on file/directory's
42 @code{ctime}), @code{Last-Modified} and corresponding precondition
43 handlers are fully used.
44
45 @item Auto-generated directory listings and
46 read-only @url{https://en.wikipedia.org/wiki/WebDAV, WebDAV} support.
47
48 @item Per-domain HTTP basic authorization and TLS client authentication.
49
50 @item If corresponding @file{.meta4} files are found, then @code{Link}
51 header is generated automatically to that
52 @url{http://www.metalinker.org/, Metalink}.
53
54 @item Very friendly to @url{http://cr.yp.to/daemontools.html, daemontools}.
55 Can drop (UID, GID, groups) privileges.
56
57 @end itemize
58
59 Basically all configuration is done directly inside source code. You
60 have to recompile it every time configuration changes. Is it a problem?
61 I doubt, because Go is very fast. But it produces huge statically linked
62 executables, you say! Use @command{bsdiff}/@command{bspatch}!
63
64 Send @code{SIGINFO} (@code{SIGUSR1} on Linux) signal to get current
65 daemon's configuration.
66
67 Initially @command{godlighty} has basic static files handlers (with
68 compression, HTTP preconditions are enabled of course). In the example
69 below there are nearly all default functions.
70
71 @verbatim
72 Hosts["example.com"] = &godlighty.HostCfg{
73     Root: "/www/example.com",
74     TLS: &godlighty.TLSCfg{
75         Cert: "/path/to/example.com.pem",
76         Key: "/path/to/example.com.key.pem",
77         CACert: "/path/to/ca.pem",
78     },
79     DirList: true,
80     WebDAV: true,
81     MIMEs: map[string]string{
82         ".special": "text/x-special-type",
83     },
84 }
85 @end verbatim
86
87 If your keys and certificates are in single file and you use common CA
88 certificate, then it is trivial to DRY:
89
90 @verbatim
91 var (
92     Etc = "/whatever"
93     CACert = path.Join(Etc, "ca.pem")
94 )
95
96 func newTLSCfg(host string) *godlighty.TLSCfg {
97     return &godlighty.TLSCfg{
98         Cert:   path.Join(Etc, host+".pem"),
99         Key:    path.Join(Etc, host+".pem"),
100         CACert: CACert,
101     }
102 }
103 @end verbatim
104
105 But there are hooks that can do anything more. For example if you want
106 to run CGI script or make a redirection (FastCGI handler example is in
107 @file{rc/fcgi}):
108
109 @verbatim
110 HostCfg{
111     ...,
112     Hooks: []godlighty.Hook{
113         func(w http.ResponseWriter, r *http.Request) bool {
114             if r.URL.Path == "/" {
115                 http.Redirect(w, r, "//here.we.go/", http.StatusMovedPermanently)
116                 return true
117             }
118             return false
119         },
120         func(w http.ResponseWriter, r *http.Request) bool {
121             cgi.Handler{
122                 Path: "/usr/local/libexec/git-core/git-http-backend",
123                 Dir:  "/var/empty",
124                 Env: []string{
125                     "GIT_PROJECT_ROOT=" + root,
126                     "GIT_HTTP_EXPORT_ALL=",
127                 },
128             }.ServeHTTP(w, r)
129             return true
130         },
131     },
132 @end verbatim
133
134 You can separate your configuration files and add them through
135 @code{init()} call:
136
137 @verbatim
138 $ ls rc
139 blog.stargrave.org.go
140 ca.cypherpunks.ru.go
141 cgi.go
142 cryptoanarchy.ru.go
143 git.go
144 go.go
145 if.mirror.cypherpunks.ru.go
146 lists.cypherpunks.ru.go
147 mime.go
148 static.go
149 tls.go
150 [...]
151
152 $ cat rc/static
153 package rc
154
155 import "path"
156
157 func addStaticCfg(host, root string) {
158     if !path.IsAbs(root) {
159         root = path.Join(WWW, root)
160     }
161     godlighty.Hosts[host] = &godlighty.HostCfg{
162         Root: root,
163         TLS:  newTLSCfg(host),
164     }
165 }
166
167 func addStaticListedDir(host, root string) {
168     addStaticCfg(host, root)
169     godlighty.Hosts[host].DirList = true
170     godlighty.Hosts[host].WebDAV = true
171 }
172
173 func init() {
174     [...]
175     addStaticCfg("paster.stargrave.org", "/storage/paster/pastes")
176     addStaticCfg("www.godlighty.stargrave.org", "godlighty.stargrave.org")
177     addStaticCfg("www.nncpgo.org", "nncpgo.org")
178     addStaticListedDir("www.mds.cypherpunks.ru", "/storage/audiobook/mds")
179     [...]
180 }
181 @end verbatim
182
183 It is created exclusively to drive my own websites, but if you are
184 interested, then @code{git clone git://git.stargrave.org/godlighty.git} it.
185
186 @bye