package main import ( "crypto/subtle" "log" "net/http" "net/http/httputil" "net/url" "os" ) func main() { target := mustEnv("PZ8_RELAY_TARGET_URL") username := mustEnv("PZ8_RELAY_USERNAME") password := mustEnv("PZ8_RELAY_PASSWORD") addr := os.Getenv("PZ8_RELAY_LISTEN_ADDR") if addr == "" { addr = ":8080" } targetURL, err := url.Parse(target) if err != nil { log.Fatalf("invalid PZ8_RELAY_TARGET_URL: %v", err) } proxy := &httputil.ReverseProxy{ Rewrite: func(preq *httputil.ProxyRequest) { preq.SetURL(targetURL) }, } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { u, p, ok := r.BasicAuth() if !ok || subtle.ConstantTimeCompare([]byte(u), []byte(username)) != 1 || subtle.ConstantTimeCompare([]byte(p), []byte(password)) != 1 { log.Printf("unauthorized request from %s", r.RemoteAddr) w.Header().Set("WWW-Authenticate", `Basic realm="pz8-relay"`) http.Error(w, "unauthorized", http.StatusUnauthorized) return } proxy.ServeHTTP(w, r) }) log.Printf("pz8-relay listening on %s, proxying to %s", addr, targetURL.Redacted()) log.Fatal(http.ListenAndServe(addr, nil)) } func mustEnv(key string) string { v := os.Getenv(key) if v == "" { log.Fatalf("missing required env var: %s", key) } return v }