116 lines
2.2 KiB
Go
116 lines
2.2 KiB
Go
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)
|
|
}
|
|
}
|