--- /dev/null
+@node Configuration
+@unnumbered Configuration
+
+Initially @command{godlighty} has basic static files handlers (with
+compression, HTTP preconditions are enabled of course). In the example
+below there are nearly all default functions.
+Also look for @file{rc/example.cfg}.
+
+@verbatim
+Hosts["example.com"] = &godlighty.HostCfg{
+ Root: "/www/example.com",
+ TLS: &godlighty.TLSCfg{
+ Cert: "/path/to/example.com.pem",
+ Key: "/path/to/example.com.key.pem",
+ CACert: "/path/to/ca.pem",
+ },
+ DirList: true,
+ WebDAV: true,
+ MIMEs: map[string]string{
+ ".special": "text/x-special-type",
+ },
+}
+@end verbatim
+
+If your keys and certificates are in single file and you use common CA
+certificate, then it is trivial to DRY:
+
+@verbatim
+var (
+ Etc = "/whatever"
+ CACert = path.Join(Etc, "ca.pem")
+)
+
+func newTLSCfg(host string) *godlighty.TLSCfg {
+ return &godlighty.TLSCfg{
+ Cert: path.Join(Etc, host+".pem"),
+ Key: path.Join(Etc, host+".pem"),
+ CACert: CACert,
+ }
+}
+@end verbatim
+
+But there are hooks that can do anything more. For example if you want
+to run CGI script or make a redirection (FastCGI handler example is in
+@file{rc/fcgi.example.cfg}):
+
+@verbatim
+HostCfg{
+ ...,
+ Hooks: []godlighty.Hook{
+ func(w http.ResponseWriter, r *http.Request) bool {
+ if r.URL.Path == "/" {
+ http.Redirect(w, r, "//here.we.go/", http.StatusMovedPermanently)
+ return true
+ }
+ return false
+ },
+ func(w http.ResponseWriter, r *http.Request) bool {
+ cgi.Handler{
+ Path: "/usr/local/libexec/git-core/git-http-backend",
+ Dir: "/var/empty",
+ Env: []string{
+ "GIT_PROJECT_ROOT=" + root,
+ "GIT_HTTP_EXPORT_ALL=",
+ },
+ }.ServeHTTP(w, r)
+ return true
+ },
+ },
+@end verbatim
+
+You can separate your configuration files and add them through
+@code{init()} call:
+
+@verbatim
+$ ls rc/stargrave.org.cfg
+blog.stargrave.org.go
+ca.cypherpunks.ru.go
+cgi.go
+cryptoanarchy.ru.go
+git.go
+go.go
+if.mirror.cypherpunks.ru.go
+lists.cypherpunks.ru.go
+static.go
+tls.go
+[...]
+
+$ cat rc/stargrave.org.cfg/static.go
+package rc
+
+import "path"
+
+func addStaticCfg(host, root string) {
+ if !path.IsAbs(root) {
+ root = path.Join(WWW, root)
+ }
+ godlighty.Hosts[host] = &godlighty.HostCfg{
+ Root: root,
+ TLS: newTLSCfg(host),
+ }
+}
+
+func addStaticListedDir(host, root string) {
+ addStaticCfg(host, root)
+ godlighty.Hosts[host].DirList = true
+ godlighty.Hosts[host].WebDAV = true
+}
+
+func init() {
+ [...]
+ addStaticCfg("paster.stargrave.org", "/storage/paster/pastes")
+ addStaticCfg("www.godlighty.stargrave.org", "godlighty.stargrave.org")
+ addStaticCfg("www.nncpgo.org", "nncpgo.org")
+ addStaticListedDir("www.mds.cypherpunks.ru", "/storage/audiobook/mds")
+ [...]
+}
+@end verbatim
+
+There are some preexisting helpers to deal with:
+
+@table @file
+
+@item rc/cgi.go
+CGI scripts.
+
+@item rc/redirect.go
+Loggable redirects.
+
+@item rc/mime.go, rc/mime/*
+Predefined @code{Content-Type} entries. Each file in @file{rc/mime/*}
+has tab-separated format: file's extension, media type and optional
+@code{c} mark, meaning that these type can be transparently compressed
+on-the-fly.
+
+@end table
@node Top
@top godlighty
-@command{godlighty} is highly-customizable HTTP, HTTP/2, HTTPS server
-written on pure Go.
+@command{godlighty} is
+@url{https://www.gnu.org/philosophy/free-sw.html, free software}
+highly-customizable HTTP, HTTP/2, HTTPS server written on pure Go.
Why yet another web-server? Because all others suck even for my simple
ordinary needs: they use hateful OpenSSL, lacks documentation, has
I doubt, because Go is very fast. But it produces huge statically linked
executables, you say! Use @command{bsdiff}/@command{bspatch}!
-Send @code{SIGINFO} (@code{SIGUSR1} on Linux) signal to get current
-daemon's configuration.
-
-Initially @command{godlighty} has basic static files handlers (with
-compression, HTTP preconditions are enabled of course). In the example
-below there are nearly all default functions.
-
-@verbatim
-Hosts["example.com"] = &godlighty.HostCfg{
- Root: "/www/example.com",
- TLS: &godlighty.TLSCfg{
- Cert: "/path/to/example.com.pem",
- Key: "/path/to/example.com.key.pem",
- CACert: "/path/to/ca.pem",
- },
- DirList: true,
- WebDAV: true,
- MIMEs: map[string]string{
- ".special": "text/x-special-type",
- },
-}
-@end verbatim
-
-If your keys and certificates are in single file and you use common CA
-certificate, then it is trivial to DRY:
-
-@verbatim
-var (
- Etc = "/whatever"
- CACert = path.Join(Etc, "ca.pem")
-)
-
-func newTLSCfg(host string) *godlighty.TLSCfg {
- return &godlighty.TLSCfg{
- Cert: path.Join(Etc, host+".pem"),
- Key: path.Join(Etc, host+".pem"),
- CACert: CACert,
- }
-}
-@end verbatim
-
-But there are hooks that can do anything more. For example if you want
-to run CGI script or make a redirection (FastCGI handler example is in
-@file{rc/fcgi}):
-
-@verbatim
-HostCfg{
- ...,
- Hooks: []godlighty.Hook{
- func(w http.ResponseWriter, r *http.Request) bool {
- if r.URL.Path == "/" {
- http.Redirect(w, r, "//here.we.go/", http.StatusMovedPermanently)
- return true
- }
- return false
- },
- func(w http.ResponseWriter, r *http.Request) bool {
- cgi.Handler{
- Path: "/usr/local/libexec/git-core/git-http-backend",
- Dir: "/var/empty",
- Env: []string{
- "GIT_PROJECT_ROOT=" + root,
- "GIT_HTTP_EXPORT_ALL=",
- },
- }.ServeHTTP(w, r)
- return true
- },
- },
-@end verbatim
-
-You can separate your configuration files and add them through
-@code{init()} call:
-
-@verbatim
-$ ls rc
-blog.stargrave.org.go
-ca.cypherpunks.ru.go
-cgi.go
-cryptoanarchy.ru.go
-git.go
-go.go
-if.mirror.cypherpunks.ru.go
-lists.cypherpunks.ru.go
-mime.go
-static.go
-tls.go
-[...]
-
-$ cat rc/static
-package rc
-
-import "path"
-
-func addStaticCfg(host, root string) {
- if !path.IsAbs(root) {
- root = path.Join(WWW, root)
- }
- godlighty.Hosts[host] = &godlighty.HostCfg{
- Root: root,
- TLS: newTLSCfg(host),
- }
-}
-
-func addStaticListedDir(host, root string) {
- addStaticCfg(host, root)
- godlighty.Hosts[host].DirList = true
- godlighty.Hosts[host].WebDAV = true
-}
-
-func init() {
- [...]
- addStaticCfg("paster.stargrave.org", "/storage/paster/pastes")
- addStaticCfg("www.godlighty.stargrave.org", "godlighty.stargrave.org")
- addStaticCfg("www.nncpgo.org", "nncpgo.org")
- addStaticListedDir("www.mds.cypherpunks.ru", "/storage/audiobook/mds")
- [...]
-}
-@end verbatim
-
It is created exclusively to drive my own websites, but if you are
interested, then @code{git clone git://git.stargrave.org/godlighty.git} it.
+@include cfg.texi
+@include usage.texi
+
@bye
--- /dev/null
+@node Usage
+@unnumbered Usage
+
+All @ref{Configuration, configuration} is assumed to be placed in
+@file{rc/cfg}. Probably you want to deal with multiple server
+configurations simultaneously. You place them in corresponding
+@file{rc/NAME.cfg} directories and use @url{http://cr.yp.to/redo.html,
+redo} default target to create necessary symbolic link of
+@file{rc/NAME.cfg} to @file{rc/cfg} and build executable itself.
+
+@example
+$ redo example
+# will produce example executable with rc/example.cfg configuration
+
+$ redo fcgi.example
+# will produce fcgi.example executable with rc/fcgi.example.cfg configuration
+@end example
+
+But because you will mostly like to create binary patches to quickly
+update already existing binaries, then you can use @file{make-update.sh}
+script, that will store newly created binaries in @file{updates/}
+directory and make shell-script with the built-in binary patch and
+SHA512 checksum checker:
+
+@example
+# First run
+$ ./make-update example
+$ scp updates/example.old web-server:/path/to/www-server
+
+$ ./make-update example
+$ scp updates/example-update.sh web-server:/tmp
+web-server $ /tmp/example-update.sh /path/to/www-server
+web-server $ svc -t /var/service/www-server
+@end example
+
+@file{contrib/service} contains @command{daemontools} example run scripts.
+
+Send @code{SIGINFO} (@code{SIGUSR1} on Linux) signal to get current
+daemon's configuration.
+// CGI example
+
package cfg
import (
+// WWW and git:// CGIs
+
package cfg
import (
func addGoRepoCfg(host string) {
godlighty.Hosts[host] = &godlighty.HostCfg{
- Root: path.Join(WWW, host),
- TLS: newTLSCfg(host),
- MIMEs: map[string]string{"": "text/html"},
+ Root: path.Join(WWW, host),
+ TLS: newTLSCfg(host),
+ MIMEs: map[string]string{"": "text/html"},
+ Indexes: []string{"v1"},
}
}
+// Some MIMEs overrides example
+
package cfg
import "go.stargrave.org/godlighty"
+// mlmmj archive browser
package cfg
import (
+// Reverse proxy
+
package cfg
import (
+// Various static directories
+
package cfg
import (
--- /dev/null
+package cfg
+
+import (
+ "net/http"
+ "strings"
+ "time"
+
+ "go.stargrave.org/godlighty"
+ _ "go.stargrave.org/godlighty/rc"
+)
+
+func init() {
+ docRoot := "/usr/local/www/wordpress"
+ host := "some.wordpress.com"
+ godlighty.Hosts[host] = &godlighty.HostCfg{
+ Root: docRoot,
+ Hooks: []godlighty.Hook{
+ func(w http.ResponseWriter, r *http.Request) bool {
+ if r.URL.Path == "/.htaccess" || r.URL.Path == "/xmlrpc.php" {
+ http.NotFound(w, r)
+ return true
+ }
+ return false
+ },
+ func(w http.ResponseWriter, r *http.Request) bool {
+ if strings.TrimSuffix(r.URL.Path, "/") == "" {
+ r.URL.Path = "index.php"
+ }
+ if strings.HasSuffix(r.URL.Path, ".php") {
+ ServeFCGI(
+ w, r, host, docRoot, r.URL.Path,
+ "unix", "/var/run/php-fpm.sock",
+ time.Minute,
+ )
+ return true
+ }
+ return false
+ },
+ },
+ }
+}