diff options
Diffstat (limited to 'server.go')
| -rw-r--r-- | server.go | 208 |
1 files changed, 0 insertions, 208 deletions
diff --git a/server.go b/server.go deleted file mode 100644 index 6296574..0000000 --- a/server.go +++ /dev/null @@ -1,208 +0,0 @@ -/* -Copyright 2022 Sam Anthony - -This file is part of samanthony.xyz. - -samanthony.xyz 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, either version 3 of the License, or (at your option) any later -version. - -samanthony.xyz 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 -samanthony.xyz. If not, see <https://www.gnu.org/licenses/>. -*/ - -package main - -import ( - "flag" - "fmt" - "golang.org/x/sys/unix" - "html/template" - "io/fs" - "log" - "net" - "net/http" - "os" - "path" - fp "path/filepath" - "strings" -) - -// Flags -var ( - host = "localhost" - port = "80" - chroot = "/var/www/" - user = "www" - group = "www" - root = "/htdocs/samanthony.xyz/" -) - -func init() { - flag.StringVar(&host, "host", host, "") - flag.StringVar(&port, "port", port, "") - flag.StringVar(&chroot, "chroot", chroot, "") - flag.StringVar(&user, "user", user, "") - flag.StringVar(&group, "group", group, "") - flag.StringVar(&root, "root", root, "") - - flag.Parse() -} - -// Must lookup the hostname before entering the chroot. -var addr = "" - -func init() { - // host is an ip address - if ip := net.ParseIP(host); ip != nil { - addr = ip.String() - } else { // host is a domain name - addrs, err := net.LookupHost(host) - if err != nil { - log.Fatal(err) - } - for _, a := range addrs { - if ip := net.ParseIP(a); ip != nil { - if v4 := ip.To4(); v4 != nil { - addr = v4.String() - } - } - } - if addr == "" { - log.Fatalf("No ipv4 address bound to %s", host) - } - } -} - -var ( - uid int - gid int -) - -func init() { - var err error - uid, err = uidOf(user) - if err != nil { - log.Fatal(err) - } - gid, err = gidOf(group) - if err != nil { - log.Fatal(err) - } -} - -// Enter chroot -func init() { - if err := unix.Chroot(chroot); err != nil { - log.Fatalf("chroot: %s: %v", chroot, err) - } -} - -// Build templates -var tmpl = make(map[string]*template.Template) - -func init() { - err := fp.WalkDir(root, func(path string, d fs.DirEntry, err error) error { - if fp.Clean(path) == fp.Clean(root) || - fp.Ext(path) != ".html" || - path == fp.Join(root, "base.html") { - return nil - } - label := path[len(fp.Clean(root)):] - tmpl[label] = template.Must(template.ParseFiles( - fp.Join(root, "base.html"), path)) - return nil - }) - if err != nil { - log.Fatal(err) - } -} - -// Template data -type Page struct { - Nav Nav -} - -type Nav struct { - ThisSection string - Links []NavLink -} - -type NavLink struct { - Href string - Label string -} - -var nav = Nav{ - Links: []NavLink{ - {"/", "samanthony.xyz"}, - {"/software/", "software"}, - }, -} - -func rootHandler(w http.ResponseWriter, r *http.Request) { - if err := dropPerms(uid, gid); err != nil { - log.Println(err) - code := http.StatusInternalServerError - http.Error(w, http.StatusText(code), code) - return - } - - reqPath := r.URL.Path - - // If request directory, serve index.html. - // ie. /software -> /software/index.html - if info, err := os.Stat(fp.Join(root, reqPath)); err == nil { - if info.IsDir() { - reqPath = path.Join(reqPath, "index.html") - } - } else if os.IsNotExist(err) { - http.NotFound(w, r) - return - } else { - log.Println(err) - code := http.StatusInternalServerError - http.Error(w, http.StatusText(code), code) - return - } - - if t, ok := tmpl[reqPath]; ok { - thisSection := "" - for _, link := range nav.Links { - if strings.HasPrefix(reqPath, link.Href) { - thisSection = link.Href - } - } - nav := nav - nav.ThisSection = thisSection - page := Page{nav} - - err := t.Execute(w, page) - if err != nil { - log.Println(err) - code := http.StatusInternalServerError - http.Error(w, http.StatusText(code), code) - return - } - } else { - http.ServeFile(w, r, fp.Join(root, reqPath)) - } -} - -func main() { - http.HandleFunc("/", rootHandler) - http.Handle("/.well-known/acme-challenge/", - http.StripPrefix( - "/.well-known/acme-challenge/", - http.FileServer(http.Dir("/acme/")), - ), - ) - - log.Printf("Listening on %s:%s\n", addr, port) - log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%s", addr, port), nil)) -} |