package libmkwebpage import ( "fmt" "net/http" "net/http/cgi" "os" ) type Webpage struct { muxStatic *http.ServeMux muxDynamic *http.ServeMux muxInternal *http.ServeMux templates templates staticFilePrefix string } type handler struct { w *Webpage } func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if _, pattern := h.w.muxInternal.Handler(r); pattern != "" { h.w.muxInternal.ServeHTTP(w, r) return } h.w.getHandler().ServeHTTP(w, r) } func New() *Webpage { webpage := Webpage{muxStatic: http.NewServeMux(), muxDynamic: http.NewServeMux(), muxInternal: http.NewServeMux()} webpage.muxInternal.HandleFunc("/.libmkpage/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "/.libmkpage/") }) return &webpage } // See http.HandleFunc func (w *Webpage) Handle(pattern string, handler func(http.ResponseWriter, *http.Request)) *Webpage { return w.HandleDynamic(pattern, handler).HandleStatic(pattern, handler) } // See http.HandleFunc, only executed in dynamic requests (i.e. in a dev setup) func (w *Webpage) HandleDynamic(pattern string, handler func(http.ResponseWriter, *http.Request)) *Webpage { w.muxDynamic.HandleFunc(pattern, handler) return w } // See http.HandleFunc, only executed in static requests (i.e. in a prod setup) func (w *Webpage) HandleStatic(pattern string, handler func(http.ResponseWriter, *http.Request)) *Webpage { w.muxStatic.HandleFunc(pattern, handler) return w } // See http.Handle func (w *Webpage) Handler(pattern string, handler http.Handler) *Webpage { return w.HandlerDynamic(pattern, handler).HandlerStatic(pattern, handler) } // See http.Handle, only executed in dynamic requests (i.e. in a dev setup) func (w *Webpage) HandlerDynamic(pattern string, handler http.Handler) *Webpage { w.muxDynamic.Handle(pattern, handler) return w } // See http.Handle, only executed in static requests (i.e. in a prod setup) func (w *Webpage) HandlerStatic(pattern string, handler http.Handler) *Webpage { w.muxStatic.Handle(pattern, handler) return w } // Returns the proper Mux for the current Request based on the request type without the magic internal mux func (w *Webpage) getHandler() http.Handler { if w.isDynamic() { return w.muxDynamic } else { return w.muxStatic } } // Returns a http.Handler capable of hosting the application. Useful for combining more than one webpage in one binary func (w *Webpage) GetHandler() http.Handler { return handler{w} } func (w *Webpage) isDynamic() bool { return os.Getenv("PATH_INFO") == "" } func (w *Webpage) isStatic() bool { return !w.isDynamic() } func (w *Webpage) Serve() { if w.isDynamic() { fmt.Println("Listening on [::]:8080") panic(http.ListenAndServe(":8080", w.GetHandler())) } err := cgi.Serve(w.GetHandler()) if err != nil { panic(err) } os.Exit(0) }