package servlet import ( "html/template" "io/ioutil" "log" "net/http" "os" "regexp" "vinegar/vinegarUtil" ) const ( defaultLruSize = int64(1024 * 1024 * 50) ContentTypeHeaderKey = "Content-Type" ContentEncodingHeaderKey = "Content-Encoding" AcceptEncodingHeaderKey = "Accept-Encoding" ) type ErrorResponse struct { Code int Message string } type ( VinegarServlet struct { Port string Routes []*VinegarRoute } VinegarRoute struct { Pattern *regexp.Regexp Handler VinegarHandlerFunction Cache vinegarUtil.Cache } VinegarHandlerFunction func(w http.ResponseWriter, req *http.Request) ) func NewServlet(port string) *VinegarServlet { srv := VinegarServlet{Port: port} return &srv } func NewServletRoute(routePattern string, handleFunc VinegarHandlerFunction) *VinegarRoute { pattern := regexp.MustCompile(routePattern) route := VinegarRoute{Pattern: pattern, Handler: handleFunc, Cache: vinegarUtil.NewLRU(defaultLruSize)} return &route } func (s *VinegarServlet) AddRoute(route *VinegarRoute) { route.Announce() s.Routes = append(s.Routes, route) } func (s *VinegarServlet) ServeHTTP(w http.ResponseWriter, req *http.Request) { path := req.URL.Path for _, route := range s.Routes { if route.Pattern.MatchString(path) { route.Handler(w, req) return } } } func (s *VinegarServlet) Start() { if len(s.Routes) < 1 { log.Fatal("No routes found for server. Nothing to listen and serve.") os.Exit(1) } log.Printf("Listening on [%s]\n", s.Port) err := http.ListenAndServe(s.Port, s) if err != nil { panic(err) } } func (r *VinegarRoute) Announce() { log.Printf("Added route for [%s]\n", r.Pattern.String()) } func SendError(w http.ResponseWriter, code int, msg string) { errorFile := "templates/error.html" errorResp := ErrorResponse{code, msg} tmplManager := template.New("error") f, err := os.OpenFile(errorFile, os.O_RDONLY, 0777) if err != nil { panic(err) } defer f.Close() content, err := ioutil.ReadAll(f) if err != nil { panic(err) } tmpl, err := tmplManager.Parse(string(content)) if err != nil { panic(err) } w.WriteHeader(code) err = tmpl.Execute(w, errorResp) if err != nil { panic(err) } }