From: Sergey Matveev Date: Sun, 3 Oct 2021 21:13:23 +0000 (+0300) Subject: Verbose redirects, tiny DRY X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=a65ca9f1e9917d3c8193297ce20b59352a009c55;p=godlighty.git Verbose redirects, tiny DRY --- diff --git a/cfg.go b/cfg.go index 321941d..1aa243a 100644 --- 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) diff --git a/dirlist.go b/dirlist.go index 86c65f4..c7c7e6a 100644 --- a/dirlist.go +++ b/dirlist.go @@ -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) } diff --git a/doc/index.texi b/doc/index.texi index abf9c20..bbc53e7 100644 --- a/doc/index.texi +++ b/doc/index.texi @@ -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. diff --git a/handler.go b/handler.go index c613d2a..3aacc29 100644 --- a/handler.go +++ b/handler.go @@ -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) diff --git a/media.go b/media.go index dec0822..f36db17 100644 --- 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 diff --git a/rc/cryptoanarchy.ru.go b/rc/cryptoanarchy.ru.go index 94630da..81c85d5 100644 --- a/rc/cryptoanarchy.ru.go +++ b/rc/cryptoanarchy.ru.go @@ -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 }, diff --git a/rc/git.go b/rc/git.go index de153a2..65498b1 100644 --- 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 diff --git a/rc/go.go b/rc/go.go index 532e291..e4b0d8e 100644 --- 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"}, } } diff --git a/rc/if.mirror.cypherpunks.ru.go b/rc/if.mirror.cypherpunks.ru.go index 79b8949..dad2b39 100644 --- a/rc/if.mirror.cypherpunks.ru.go +++ b/rc/if.mirror.cypherpunks.ru.go @@ -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 index 0000000..86a6210 --- /dev/null +++ b/rc/redirect.go @@ -0,0 +1,35 @@ +/* +godlighty -- highly-customizable HTTP, HTTP/2, HTTPS server +Copyright (C) 2021 Sergey Matveev + +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 . +*/ + +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"), + ) +}