package pkg import ( "net/http" "path" "strings" ) type ApplicationHandler struct { db *Db fileHandler http.Handler loginHandler *LoginHandler } func NewApplication(db *Db) http.Handler { var handler http.Handler = &ApplicationHandler{ db: db, fileHandler: http.FileServer(http.Dir("web/static")), loginHandler: &LoginHandler{}, } handler = LocaleSetter(db, handler) handler = LoginChecker(db, handler) handler = Recoverer(handler) handler = Logger(handler) return handler } func (h *ApplicationHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { var head string head, r.URL.Path = shiftPath(r.URL.Path) switch head { case "static": h.fileHandler.ServeHTTP(w, r) case "login": h.loginHandler.ServeHTTP(w, r) case "edit": switch r.Method { case http.MethodGet: mustRenderTemplate(w, r, "editor.gohtml", "web.gohtml", nil) default: methodNotAllowed(w, r, http.MethodGet) } case "": switch r.Method { case http.MethodGet: h.serveHomePage(w, r) default: methodNotAllowed(w, r, http.MethodGet) } default: http.NotFound(w, r) } } func (h *ApplicationHandler) serveHomePage(w http.ResponseWriter, r *http.Request) { mustRenderWebTemplate(w, r, "home.gohtml", nil) } func shiftPath(p string) (head, tail string) { p = path.Clean("/" + p) if i := strings.IndexByte(p[1:], '/') + 1; i <= 0 { return p[1:], "/" } else { return p[1:i], p[i:] } } func methodNotAllowed(w http.ResponseWriter, _ *http.Request, allowed ...string) { w.Header().Set("Allow", strings.Join(allowed, ", ")) http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) }