Anki/http.go

70 lines
1.4 KiB
Go

package main
import (
"context"
_ "embed"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
)
type Context struct {
User string
}
func HTTP(port int, db DB) error {
foo := func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/":
httpRoot(w, r)
default:
http.NotFound(w, r)
}
}
foo = withAuth(foo)
return http.ListenAndServe(fmt.Sprintf(":%d", port), http.HandlerFunc(foo))
}
func extract(ctx context.Context) Context {
v := ctx.Value("__context")
v2, _ := v.(Context)
return v2
}
func inject(ctx context.Context, v Context) context.Context {
return context.WithValue(ctx, "__context", v)
}
func withAuth(foo http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
u, _, ok := r.BasicAuth()
if !ok || u == "" {
w.Header().Set("WWW-Authenticate", "Basic")
w.WriteHeader(401)
return
}
c := extract(r.Context())
c.User = u
r = r.WithContext(inject(r.Context(), c))
foo(w, r)
}
}
//go:embed public/root.html
var httpRootHTML string
func httpRoot(w http.ResponseWriter, r *http.Request) {
body := httpRootHTML
if os.Getenv("DEBUG") != "" {
b, _ := os.ReadFile("public/root.html")
body = string(b)
}
ctx := extract(r.Context())
body = strings.ReplaceAll(body, "{{USER}}", ctx.User)
assignments, _ := json.Marshal(nil)
body = strings.ReplaceAll(body, "{{ASSIGNMENTS_JSON}}", string(assignments))
w.Write([]byte(body))
}