]> Sergey Matveev's repositories - godlighty.git/commitdiff
Verbose redirects, tiny DRY
authorSergey Matveev <stargrave@stargrave.org>
Sun, 3 Oct 2021 21:13:23 +0000 (00:13 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 3 Oct 2021 21:17:28 +0000 (00:17 +0300)
cfg.go
dirlist.go
doc/index.texi
handler.go
media.go
rc/cryptoanarchy.ru.go
rc/git.go
rc/go.go
rc/if.mirror.cypherpunks.ru.go
rc/redirect.go [new file with mode: 0644]

diff --git a/cfg.go b/cfg.go
index 321941dbbbc521d427a761ab97b78e9b06c4c9b0..1aa243a8c901064442cfcca2f2ba7978d9d79848 100644 (file)
--- a/cfg.go
+++ b/cfg.go
@@ -30,15 +30,15 @@ type TLSCfg struct {
 type Hook func(http.ResponseWriter, *http.Request) bool
 
 type HostCfg struct {
-       Root         string
-       Index        string
-       TLS          *TLSCfg
-       DirList      bool
-       WebDAV       bool
-       Hooks        []Hook
-       MIMEOverride map[string]string
-
-       DirListReadmes []string
+       Root    string
+       TLS     *TLSCfg
+       DirList bool
+       WebDAV  bool
+       Hooks   []Hook
+
+       Indexes []string
+       Readmes []string
+       MIMEs   map[string]string
 }
 
 var Hosts = make(map[string]*HostCfg)
index 86c65f49dc4212fa9e9babdbc7aaa238deefed52..c7c7e6ab3fd320f4063e911347570a3a186934d3 100644 (file)
@@ -81,7 +81,7 @@ func dirList(
                if fi.IsDir() {
                        file.IsDir = true
                } else {
-                       file.Type = mediaType(file.Name, cfg.MIMEOverride)
+                       file.Type = mediaType(file.Name, cfg.MIMEs)
                }
                files = append(files, file)
        }
index abf9c20d949bdd5ceff087df0fd1271758fe6696..bbc53e7be031cf9d6ed92f81b870c754b8823e26 100644 (file)
@@ -27,7 +27,8 @@ ChaCha20-Poly1305, session resumption and GOST cryptography (if built
 with @url{http://www.gostls13.cypherpunks.ru/, gostls13}). SNI supported.
 
 @item HTTP/1.1, @url{https://en.wikipedia.org/wiki/HTTP%2F2, HTTP/2}
-(only when negotiated during ALPN) and keepalives support.
+(only when negotiated during ALPN) and keepalives support. Graceful
+shutdowns.
 
 @item @code{gzip} and @url{https://facebook.github.io/zstd/, Zstandard}
 compression on-the-fly.
index c613d2a6b9a4c61fd39f4e52eac3c0cde47e72f6..3aacc29f6b74d502616308481e159445bdafc95b 100644 (file)
@@ -69,18 +69,21 @@ func (h Handler) Handle(
        w http.ResponseWriter, r *http.Request,
        host string, cfg *HostCfg,
 ) {
-       if cfg == nil {
+       notFound := func() {
                fmt.Printf("%s %s \"%s %s %s\" %d \"%s\"\n",
                        r.RemoteAddr, host, r.Method, r.URL.Path, r.Proto,
                        http.StatusNotFound,
                        r.Header.Get("User-Agent"),
                )
                http.NotFound(w, r)
+       }
+       if cfg == nil {
+               notFound()
                return
        }
 
        for _, hook := range cfg.Hooks {
-               if hook(w, r) {
+               if done := hook(w, r); done {
                        return
                }
        }
@@ -94,12 +97,7 @@ func (h Handler) Handle(
        }
 
        if cfg.Root == "" {
-               fmt.Printf("%s %s \"%s %s %s\" %d \"%s\"\n",
-                       r.RemoteAddr, host, r.Method, r.URL.Path, r.Proto,
-                       http.StatusNotFound,
-                       r.Header.Get("User-Agent"),
-               )
-               http.NotFound(w, r)
+               notFound()
                return
        }
 
@@ -132,16 +130,12 @@ func (h Handler) Handle(
        var fd *os.File
        var contentType string
        var etag string
-       pth := path.Clean(path.Join(cfg.Root, r.URL.Path))
+       pthOrig := path.Clean(path.Join(cfg.Root, r.URL.Path))
+       pth := pthOrig
 IndexLookup:
        fi, err := os.Stat(pth)
        if err != nil {
-               fmt.Printf("%s %s \"%s %s %s\" %d \"%s\"\n",
-                       r.RemoteAddr, host, r.Method, r.URL.Path, r.Proto,
-                       http.StatusNotFound,
-                       r.Header.Get("User-Agent"),
-               )
-               http.NotFound(w, r)
+               notFound()
                return
        }
        if fi.IsDir() {
@@ -166,7 +160,7 @@ IndexLookup:
                                return
                        }
                        var readme []byte
-                       for _, f := range append(cfg.DirListReadmes, Readme) {
+                       for _, f := range append(cfg.Readmes, Readme) {
                                readme, _ = ioutil.ReadFile(path.Join(pth, f))
                                if readme != nil {
                                        break
@@ -180,12 +174,15 @@ IndexLookup:
                        }
                        contentType = "text/html; charset=utf-8"
                } else {
-                       if cfg.Index == "" {
-                               pth = path.Join(pth, Index)
-                       } else {
-                               pth = path.Join(pth, cfg.Index)
+                       for _, index := range append(cfg.Indexes, Index) {
+                               p := path.Join(pth, index)
+                               if _, err := os.Stat(p); err == nil {
+                                       pth = p
+                                       goto IndexLookup
+                               }
                        }
-                       goto IndexLookup
+                       notFound()
+                       return
                }
        }
 
@@ -210,7 +207,7 @@ IndexLookup:
        }
 
        if contentType == "" {
-               contentType = mediaType(path.Base(pth), cfg.MIMEOverride)
+               contentType = mediaType(path.Base(pth), cfg.MIMEs)
        }
        contentTypeBase := strings.SplitN(contentType, ";", 2)[0]
        w.Header().Set("Content-Type", contentType)
index dec08224bcb928ed134b11ee87e9694ce7d5cf12..f36db17c27870b9c6a2f716545c6ffba54977167 100644 (file)
--- a/media.go
+++ b/media.go
@@ -23,18 +23,18 @@ const OctetStream = "application/octet-stream"
 
 var ContentTypes = make(map[string]string)
 
-func mediaType(fn string, override map[string]string) string {
+func mediaType(fn string, overrides map[string]string) string {
        ext := path.Ext(fn)
        if ext == "" {
                ext = fn
        }
-       if ct := override[ext]; ct != "" {
+       if ct := overrides[ext]; ct != "" {
                return ct
        }
        if ct := ContentTypes[ext]; ct != "" {
                return ct
        }
-       if ct := override[""]; ct != "" {
+       if ct := overrides[""]; ct != "" {
                return ct
        }
        return OctetStream
index 94630daec1e3788c2f6bfdf72d02d0c3a691b7be..81c85d5157a793e8ec037f07d20f76b5b6ccfd56 100644 (file)
@@ -7,13 +7,14 @@ import (
 )
 
 func init() {
-       godlighty.Hosts["www.cryptoanarchy.ru"] = &godlighty.HostCfg{
+       host := "www.cryptoanarchy.ru"
+       godlighty.Hosts[host] = &godlighty.HostCfg{
                Hooks: []godlighty.Hook{
                        func(w http.ResponseWriter, r *http.Request) bool {
-                               http.Redirect(
-                                       w, r,
+                               redirect(
+                                       host, w, r,
                                        "//www.cypherpunks.ru/Manifesto-cryptoanarchist.html",
-                                       http.StatusTemporaryRedirect,
+                                       http.StatusMovedPermanently,
                                )
                                return true
                        },
index de153a23a8b007d5311f129760b044f173cfffa0..65498b162810697f7495abfee2e5f966c349f9de 100644 (file)
--- a/rc/git.go
+++ b/rc/git.go
@@ -13,7 +13,7 @@ func addGitRepoCfg(host, root, gitwebCfg string) {
                Hooks: []godlighty.Hook{
                        func(w http.ResponseWriter, r *http.Request) bool {
                                if r.URL.Path == "/" {
-                                       http.Redirect(w, r, "//"+host+"/", http.StatusMovedPermanently)
+                                       redirect(host, w, r, "//"+host+"/", http.StatusMovedPermanently)
                                        return true
                                }
                                return false
index 532e29186d84d987a867fe156cdbf65d03085edb..e4b0d8edfbecc7258bcad568f629b322af603f97 100644 (file)
--- a/rc/go.go
+++ b/rc/go.go
@@ -25,9 +25,9 @@ import (
 
 func addGoRepoCfg(host string) {
        godlighty.Hosts[host] = &godlighty.HostCfg{
-               Root:         path.Join(WWW, host),
-               TLS:          newTLSCfg(host),
-               MIMEOverride: map[string]string{"": "text/html"},
+               Root:  path.Join(WWW, host),
+               TLS:   newTLSCfg(host),
+               MIMEs: map[string]string{"": "text/html"},
        }
 }
 
index 79b8949333deac82f1cf197eeff7eba5dd3717ba..dad2b39bf3b7acbf05d948d5d622034f1f3ada63 100644 (file)
@@ -4,12 +4,10 @@ import "go.stargrave.org/godlighty"
 
 func init() {
        addStaticListedDir("www.if.mirror.cypherpunks.ru", "/storage/if")
-       godlighty.Hosts["www.if.mirror.cypherpunks.ru"].MIMEOverride = map[string]string{
+       godlighty.Hosts["www.if.mirror.cypherpunks.ru"].MIMEs = map[string]string{
                "directory-tree": "text/plain",
                "Index":          "text/plain",
                "Master-Index":   "text/plain",
        }
-       godlighty.Hosts["www.if.mirror.cypherpunks.ru"].DirListReadmes = []string{
-               "Index",
-       }
+       godlighty.Hosts["www.if.mirror.cypherpunks.ru"].Readmes = []string{"Index"}
 }
diff --git a/rc/redirect.go b/rc/redirect.go
new file mode 100644 (file)
index 0000000..86a6210
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+godlighty -- highly-customizable HTTP, HTTP/2, HTTPS server
+Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package rc
+
+import (
+       "fmt"
+       "net/http"
+)
+
+func redirect(
+       host string,
+       w http.ResponseWriter, r *http.Request,
+       to string, status int,
+) {
+       http.Redirect(w, r, to, status)
+       fmt.Printf("%s %s \"%s %s %s\" %d \"%s\"\n",
+               r.RemoteAddr, host, r.Method, r.URL.Path, r.Proto,
+               status, r.Header.Get("User-Agent"),
+       )
+}