okay, everything seems to work. somewhat.

This commit is contained in:
dtookey 2022-07-18 17:00:22 -04:00
parent 1fdb507dbb
commit 26fbb2908c
4 changed files with 47 additions and 42 deletions

View File

@ -1,4 +1,4 @@
package vinegar package cacheutil
import ( import (
"bytes" "bytes"
@ -12,8 +12,6 @@ import (
const ( const (
DefaultCacheTimeInMinutes = 15 DefaultCacheTimeInMinutes = 15
ContentTypeHeaderKey = "Content-Type"
ContentEncodingHeaderKey = "Content-Encoding"
) )
type ( type (
@ -108,7 +106,7 @@ func (l *Lru) Get(key string) (*LruEntry, bool) {
if exists { if exists {
entry.mostRecentAccess = time.Now() entry.mostRecentAccess = time.Now()
} else { } else {
fmt.Printf("cache miss for '%s'\n", key) fmt.Printf("cacheutil miss for '%s'\n", key)
} }
return entry, exists return entry, exists
} }

View File

@ -1,4 +1,4 @@
package vinegar package servlet
import ( import (
"fmt" "fmt"
@ -7,8 +7,8 @@ import (
type ( type (
ApiRoute struct { ApiRoute struct {
ServletRoute *ServletRoute VinegarRoute *VinegarRoute
HttpMethodRoutes *map[HttpMethod]ServletHandleFunction HttpMethodRoutes *map[HttpMethod]VinegarHandlerFunction
} }
) )
@ -26,7 +26,7 @@ const (
) )
func NewApiRoute(pattern string) *ApiRoute { func NewApiRoute(pattern string) *ApiRoute {
functionMap := make(map[HttpMethod]ServletHandleFunction) functionMap := make(map[HttpMethod]VinegarHandlerFunction)
ancestorRoute := NewServletRoute(pattern, createMethodHandler(&functionMap)) ancestorRoute := NewServletRoute(pattern, createMethodHandler(&functionMap))
route := ApiRoute{ route := ApiRoute{
ancestorRoute, ancestorRoute,
@ -35,7 +35,7 @@ func NewApiRoute(pattern string) *ApiRoute {
return &route return &route
} }
func createMethodHandler(m *map[HttpMethod]ServletHandleFunction) ServletHandleFunction { func createMethodHandler(m *map[HttpMethod]VinegarHandlerFunction) VinegarHandlerFunction {
return func(w http.ResponseWriter, req *http.Request) { return func(w http.ResponseWriter, req *http.Request) {
method := getHttpMethod(req) method := getHttpMethod(req)
fn, exists := (*m)[method] fn, exists := (*m)[method]
@ -52,7 +52,7 @@ func createMethodHandler(m *map[HttpMethod]ServletHandleFunction) ServletHandleF
} }
} }
func (api *ApiRoute) RegisterHttpMethodHandler(method HttpMethod, handler ServletHandleFunction) { func (api *ApiRoute) RegisterHttpMethodHandler(method HttpMethod, handler VinegarHandlerFunction) {
(*api.HttpMethodRoutes)[method] = handler (*api.HttpMethodRoutes)[method] = handler
} }

View File

@ -1,4 +1,4 @@
package vinegar package servlet
import ( import (
"fmt" "fmt"
@ -7,10 +7,13 @@ import (
"net/http" "net/http"
"os" "os"
"regexp" "regexp"
"vinegar/cacheutil"
) )
const ( const (
defaultLruSize = int64(1024 * 1024 * 50) defaultLruSize = int64(1024 * 1024 * 50)
ContentTypeHeaderKey = "Content-Type"
ContentEncodingHeaderKey = "Content-Encoding"
) )
type ErrorResponse struct { type ErrorResponse struct {
@ -19,29 +22,29 @@ type ErrorResponse struct {
} }
type ( type (
Servlet struct { VinegarServlet struct {
Port string Port string
Routes []*ServletRoute Routes []*VinegarRoute
Cache *Lru Cache *cacheutil.Lru
} }
ServletRoute struct { VinegarRoute struct {
Pattern *regexp.Regexp Pattern *regexp.Regexp
Handler ServletHandleFunction Handler VinegarHandlerFunction
} }
ServletHandleFunction func(w http.ResponseWriter, req *http.Request) VinegarHandlerFunction func(w http.ResponseWriter, req *http.Request)
) )
func NewServlet(port string) *Servlet { func NewServlet(port string) *VinegarServlet {
lru := NewLRU(defaultLruSize) lru := cacheutil.NewLRU(defaultLruSize)
srv := Servlet{Port: port, Cache: lru} srv := VinegarServlet{Port: port, Cache: lru}
return &srv return &srv
} }
func NewServletRoute(routePattern string, handleFunc ServletHandleFunction) *ServletRoute { func NewServletRoute(routePattern string, handleFunc VinegarHandlerFunction) *VinegarRoute {
route := ServletRoute{} route := VinegarRoute{}
pattern := regexp.MustCompile(routePattern) pattern := regexp.MustCompile(routePattern)
@ -51,11 +54,11 @@ func NewServletRoute(routePattern string, handleFunc ServletHandleFunction) *Ser
return &route return &route
} }
func (s *Servlet) AddRoute(route *ServletRoute) { func (s *VinegarServlet) AddRoute(route *VinegarRoute) {
s.Routes = append(s.Routes, route) s.Routes = append(s.Routes, route)
} }
func (s *Servlet) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (s *VinegarServlet) ServeHTTP(w http.ResponseWriter, req *http.Request) {
path := req.URL.Path path := req.URL.Path
fmt.Println("Attempting to match request for " + path) fmt.Println("Attempting to match request for " + path)
for _, route := range s.Routes { for _, route := range s.Routes {
@ -66,7 +69,7 @@ func (s *Servlet) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
} }
func StartServerGood(s *Servlet) { func StartServerGood(s *VinegarServlet) {
err := http.ListenAndServe(s.Port, s) err := http.ListenAndServe(s.Port, s)
if err != nil { if err != nil {

View File

@ -1,60 +1,64 @@
package vinegar package servlet
import ( import (
"net/http" "net/http"
"path" "path"
"strings" "strings"
"vinegar/cacheutil"
) )
type ( type (
FileRoute struct { FileRoute struct {
*ServletRoute *VinegarRoute
fileRoot string fileRoot string
} }
) )
func NewImageRoute(urlPattern string, pathlike string, servlet *Servlet) *FileRoute { func NewImageRoute(urlPattern string, pathlike string, servlet *VinegarServlet) *FileRoute {
defaultPrune := strings.Replace(urlPattern, ".*", "", -1) defaultPrune := strings.Replace(urlPattern, ".*", "", -1)
rootRoute := NewServletRoute(urlPattern, createUncompressedFileServletFunction(defaultPrune, pathlike, servlet.Cache)) rootRoute := NewServletRoute(urlPattern, createUncompressedFileServletFunction(defaultPrune, pathlike, servlet.Cache))
imgRoute := FileRoute{rootRoute, pathlike} imgRoute := FileRoute{rootRoute, pathlike}
return &imgRoute return &imgRoute
} }
func NewTextRoute(urlPattern string, pathlike string, servlet *Servlet) *FileRoute { func NewTextRoute(urlPattern string, pathlike string, servlet *VinegarServlet) *FileRoute {
defaultPrune := strings.Replace(urlPattern, ".*", "", -1) defaultPrune := strings.Replace(urlPattern, ".*", "", -1)
rootRoute := NewServletRoute(urlPattern, createCompressibleFileServletFunction(defaultPrune, pathlike, servlet.Cache)) rootRoute := NewServletRoute(urlPattern, createCompressibleFileServletFunction(defaultPrune, pathlike, servlet.Cache))
fr := FileRoute{rootRoute, pathlike} fr := FileRoute{rootRoute, pathlike}
return &fr return &fr
} }
func NewSingleFileRoute(urlPattern string, pathlike string, servlet *Servlet) *FileRoute { func NewSingleFileRoute(urlPattern string, pathlike string, servlet *VinegarServlet) *FileRoute {
fun := createSingleFileServletFunction(pathlike) fun := createSingleFileServletFunction(pathlike)
route := FileRoute{ route := FileRoute{
ServletRoute: NewServletRoute("^"+urlPattern+"$", fun), VinegarRoute: NewServletRoute("^"+urlPattern+"$", fun),
fileRoot: pathlike, fileRoot: pathlike,
} }
return &route return &route
} }
func createSingleFileServletFunction(pathlike string) ServletHandleFunction { func createSingleFileServletFunction(pathlike string) VinegarHandlerFunction {
cache := NewSingleFileCache(pathlike) cache := cacheutil.NewSingleFileCache(pathlike)
var fun ServletHandleFunction = func(w http.ResponseWriter, req *http.Request) { var fun VinegarHandlerFunction = func(w http.ResponseWriter, req *http.Request) {
w.Header().Add(ContentTypeHeaderKey, cache.Mimetype) w.Header().Add(ContentTypeHeaderKey, cache.Mimetype)
if clientAcceptsGzip(req) { if clientAcceptsGzip(req) {
w.Header().Add(ContentEncodingHeaderKey, "gzip") w.Header().Add(ContentEncodingHeaderKey, "gzip")
w.Write(*cache.CompressedContent) _, err := w.Write(*cache.CompressedContent)
if err != nil {
panic(err)
}
} }
} }
return fun return fun
} }
func createCompressibleFileServletFunction(basePattern string, pathlike string, cache *Lru) ServletHandleFunction { func createCompressibleFileServletFunction(basePattern string, pathlike string, cache *cacheutil.Lru) VinegarHandlerFunction {
var fun ServletHandleFunction = func(w http.ResponseWriter, req *http.Request) { var fun VinegarHandlerFunction = func(w http.ResponseWriter, req *http.Request) {
stub := strings.Replace(req.URL.Path, basePattern, "", 1) stub := strings.Replace(req.URL.Path, basePattern, "", 1)
cachedContent, exists := cache.Get(stub) cachedContent, exists := cache.Get(stub)
if !exists { if !exists {
content, fileExists := GetDiskContent(path.Join(pathlike, stub)) content, fileExists := cacheutil.GetDiskContent(path.Join(pathlike, stub))
if fileExists { if fileExists {
cache.Put(stub, content) cache.Put(stub, content)
cachedContent, _ = cache.Get(stub) cachedContent, _ = cache.Get(stub)
@ -80,13 +84,13 @@ func createCompressibleFileServletFunction(basePattern string, pathlike string,
return fun return fun
} }
func createUncompressedFileServletFunction(basePattern string, pathlike string, cache *Lru) ServletHandleFunction { func createUncompressedFileServletFunction(basePattern string, pathlike string, cache *cacheutil.Lru) VinegarHandlerFunction {
var fun ServletHandleFunction = func(w http.ResponseWriter, req *http.Request) { var fun VinegarHandlerFunction = func(w http.ResponseWriter, req *http.Request) {
stub := strings.Replace(req.URL.Path, basePattern, "", 1) stub := strings.Replace(req.URL.Path, basePattern, "", 1)
entry, exists := cache.Get(stub) entry, exists := cache.Get(stub)
if !exists { if !exists {
fileContent, fExists := GetDiskContent(path.Join(pathlike, stub)) fileContent, fExists := cacheutil.GetDiskContent(path.Join(pathlike, stub))
if fExists { if fExists {
cache.Put(stub, fileContent) cache.Put(stub, fileContent)
entry, exists = cache.Get(stub) entry, exists = cache.Get(stub)