package hub import ( "errors" "log" "net/http" "vppn/hub/api" "vppn/hub/errs" "git.crumpington.com/lib/webutil" ) type handlerFunc func(s *api.Session, w http.ResponseWriter, r *http.Request) error func (app *App) handlePub(pattern string, fn handlerFunc) { wrapped := func(w http.ResponseWriter, r *http.Request) { sessionID := app.getCookie(r, sessionIDCookieName) s := app.api.Session_Get(sessionID) if r.Method == http.MethodPost { r.Body = http.MaxBytesReader(w, r.Body, 128*1024) r.ParseMultipartForm(64 * 1024) } else { r.ParseForm() } if err := fn(&s, w, r); err != nil { handleError(w, err) } } app.mux.HandleFunc(pattern, wrapped) } func (app *App) handleNotSignedIn(pattern string, fn handlerFunc) { app.handlePub(pattern, func(s *api.Session, w http.ResponseWriter, r *http.Request) error { if s.SessionID != "" { http.Redirect(w, r, "/", http.StatusSeeOther) return nil } return fn(s, w, r) }) } func (app *App) handleSignedIn(pattern string, fn handlerFunc) { app.handlePub(pattern, func(s *api.Session, w http.ResponseWriter, r *http.Request) error { if s.SessionID == "" { http.Redirect(w, r, "/", http.StatusSeeOther) return nil } return fn(s, w, r) }) } type peerHandlerFunc func(p *api.Peer, w http.ResponseWriter, r *http.Request) error func (app *App) handlePeer(pattern string, fn peerHandlerFunc) { wrapped := func(w http.ResponseWriter, r *http.Request) { _, apiKey, ok := r.BasicAuth() if !ok { http.Error(w, "Not authorized", http.StatusUnauthorized) return } // Not doing constant time compare because index lookup time dominates. peer, err := app.api.Peer_GetByAPIKey(apiKey) if err != nil { http.Error(w, "Not authorized", http.StatusUnauthorized) return } r.ParseForm() if err := fn(peer, w, r); err != nil { handleError(w, err) } } app.mux.HandleFunc(pattern, webutil.WithLogging( wrapped)) } func handleError(w http.ResponseWriter, err error) { var e *errs.Error if errors.As(err, &e) { http.Error(w, e.Msg, e.Code) } else { log.Printf("Unexpected error: %v", err) http.Error(w, "Internal server error.", http.StatusInternalServerError) } }