homepage/main.go

93 lines
2.0 KiB
Go
Raw Permalink Normal View History

package main
import (
"embed"
2024-04-02 23:32:51 +02:00
"fmt"
"io/fs"
"log"
"net/http"
2024-04-02 23:32:51 +02:00
"os"
"path"
2023-07-19 22:35:42 +02:00
"time"
)
var version = "development"
//go:embed public/*
var embeddedPublic embed.FS
2024-04-02 23:32:51 +02:00
// bytes of the 404.html page.
var b404 []byte
// usrIP is a good way to read the src IP this way because we trust our proxy.
// largely from: https://stackoverflow.com/a/55738279
func usrIP(r *http.Request) string {
ip := r.Header.Get("x-forwarded-for")
if ip == "" {
ip = r.Header.Get("x-real-ip")
}
if ip == "" {
ip = r.RemoteAddr
}
return ip
}
// notFound writes back 404 and the 404 page.
func notFound(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
w.Write(b404)
}
// handleNotFound allows us to override the response on e.g. 404.
// inspired by https://stackoverflow.com/a/62747667
func handleNotFound(fs http.FileSystem) http.Handler {
fileServer := http.FileServer(fs)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
p := r.URL.Path
// so as not to allow path traversals.
cleanedPath := path.Clean(p)
_, err := fs.Open(cleanedPath)
if os.IsNotExist(err) {
log.Printf("Error 404 Not Found when serving path: %s, cleaned path: %s, IP: %s",
p, cleanedPath, usrIP(r))
notFound(w, r)
return
}
fileServer.ServeHTTP(w, r)
})
}
func main() {
2023-08-13 16:00:27 +02:00
// TODO: ENV WHATPORT
2024-04-02 23:32:51 +02:00
// TODO: add /ip endpoint that returns the src IP.
f404, err := embeddedPublic.ReadFile("public/404.html")
if err != nil {
2024-04-02 23:32:51 +02:00
log.Fatalf("no 404.html in the folder, weird: %s", fmt.Errorf("err: %w", err))
}
2024-04-02 23:32:51 +02:00
b404 = f404
2024-04-02 23:32:51 +02:00
root, err := fs.Sub(embeddedPublic, "public")
if err != nil {
log.Fatal(err)
}
2024-04-02 23:32:51 +02:00
log.Printf("Starting app built from revision '%s'\n", version)
log.Print("Listening on :1314...")
2023-07-19 22:35:42 +02:00
// https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
srv := http.Server{
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
Addr: ":1314",
2024-04-02 23:32:51 +02:00
Handler: handleNotFound(http.FS(root)),
2023-07-19 22:35:42 +02:00
}
err = srv.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}