126 lines
2.2 KiB
Go
126 lines
2.2 KiB
Go
package vinegar
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
)
|
|
|
|
const (
|
|
defaultLruSize = int64(1024 * 1024 * 50)
|
|
)
|
|
|
|
type ErrorResponse struct {
|
|
Code int
|
|
Message string
|
|
}
|
|
|
|
type (
|
|
Servlet struct {
|
|
Port string
|
|
Routes []*ServletRoute
|
|
Cache *Lru
|
|
}
|
|
|
|
ServletRoute struct {
|
|
Pattern *regexp.Regexp
|
|
Handler ServletHandleFunction
|
|
}
|
|
|
|
ServletHandleFunction func(w http.ResponseWriter, req *http.Request)
|
|
)
|
|
|
|
func NewServlet(port string) *Servlet {
|
|
lru := NewLRU(defaultLruSize)
|
|
srv := Servlet{Port: port, Cache: lru}
|
|
|
|
return &srv
|
|
}
|
|
|
|
func NewServletRoute(routePattern string, handleFunc ServletHandleFunction) *ServletRoute {
|
|
route := ServletRoute{}
|
|
|
|
pattern := regexp.MustCompile(routePattern)
|
|
|
|
route.Pattern = pattern
|
|
route.Handler = handleFunc
|
|
|
|
return &route
|
|
}
|
|
|
|
func (s *Servlet) AddRoute(route *ServletRoute) {
|
|
s.Routes = append(s.Routes, route)
|
|
}
|
|
|
|
func (s *Servlet) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|
path := req.URL.Path
|
|
fmt.Println("Attempting to match request for " + path)
|
|
for _, route := range s.Routes {
|
|
if route.Pattern.MatchString(path) {
|
|
route.Handler(w, req)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func StartServerGood(s *Servlet) {
|
|
err := http.ListenAndServe(s.Port, s)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
func renderTemplate(w http.ResponseWriter, pathlike string, data any) {
|
|
templateHelper := template.New(pathlike)
|
|
f, err := os.OpenFile(pathlike, os.O_RDONLY, 0777)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer f.Close()
|
|
|
|
content, err := ioutil.ReadAll(f)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
templ, err := templateHelper.Parse(string(content))
|
|
err = templ.Execute(w, data)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
}
|