cleanup of codesmells and architecture
This commit is contained in:
parent
7f4b41247e
commit
ca65acbea1
39
servlet/Router.go
Normal file
39
servlet/Router.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package servlet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"geniuscartel.xyz/vinegar/vinegarUtil"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
VinegarWebRouter struct {
|
||||||
|
Routes []*VinegarWebRoute
|
||||||
|
}
|
||||||
|
|
||||||
|
VinegarWebRoute struct {
|
||||||
|
Pattern *regexp.Regexp
|
||||||
|
Handler VinegarHandlerFunction
|
||||||
|
Cache vinegarUtil.Cache
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *VinegarWebRouter) AddRoute(route *VinegarWebRoute) {
|
||||||
|
route.Announce()
|
||||||
|
s.Routes = append(s.Routes, route)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *VinegarWebRouter) RouteRequest(w http.ResponseWriter, req *http.Request) error {
|
||||||
|
path := req.URL.Path
|
||||||
|
for _, route := range r.Routes {
|
||||||
|
if route.Pattern.MatchString(path) {
|
||||||
|
//fmt.Printf("SERVING: [%s]=>{%s}\n", path, route.Pattern.String())
|
||||||
|
go route.Handler(w, req)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("failed to match route for [" + path + "]")
|
||||||
|
}
|
||||||
@ -96,7 +96,7 @@ func CreateBlankConfig() *Config {
|
|||||||
return &conf
|
return &conf
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig(pathlike string) (*VinegarHttpServlet, error) {
|
func LoadConfig(pathlike string) (*VinegarWebServlet, error) {
|
||||||
contents, err := vinegarUtil.GetDiskContent(pathlike)
|
contents, err := vinegarUtil.GetDiskContent(pathlike)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
CreateBlankConfig()
|
CreateBlankConfig()
|
||||||
@ -123,7 +123,7 @@ func LoadConfig(pathlike string) (*VinegarHttpServlet, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e ConfigEntry) toRoute(serv *VinegarHttpServlet) error {
|
func (e ConfigEntry) toRoute(serv *VinegarWebServlet) error {
|
||||||
constructor, err := getConstructorFunction(e.ConfigType)
|
constructor, err := getConstructorFunction(e.ConfigType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -9,39 +9,30 @@ import (
|
|||||||
type (
|
type (
|
||||||
ApiRoute struct {
|
ApiRoute struct {
|
||||||
VinegarRoute *VinegarWebRoute
|
VinegarRoute *VinegarWebRoute
|
||||||
HttpMethodRoutes *map[HttpMethod]VinegarHandlerFunction
|
HttpMethodRoutes *map[string]VinegarHandlerFunction
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
//NewApiRoute this will cause a panic if serv is nil
|
||||||
HttpMethod int
|
func NewApiRoute(serv *VinegarWebServlet, pattern string) *ApiRoute {
|
||||||
)
|
functionMap := make(map[string]VinegarHandlerFunction)
|
||||||
|
|
||||||
const (
|
|
||||||
GET HttpMethod = iota
|
|
||||||
POST
|
|
||||||
PUT
|
|
||||||
PATCH
|
|
||||||
DELETE
|
|
||||||
UNDEFINED
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewApiRoute(serv *VinegarHttpServlet, pattern string) *ApiRoute {
|
|
||||||
functionMap := make(map[HttpMethod]VinegarHandlerFunction)
|
|
||||||
ancestorRoute := NewServletRoute(pattern, createMethodHandler(&functionMap))
|
ancestorRoute := NewServletRoute(pattern, createMethodHandler(&functionMap))
|
||||||
route := ApiRoute{
|
route := ApiRoute{
|
||||||
ancestorRoute,
|
ancestorRoute,
|
||||||
&functionMap,
|
&functionMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
serv.AddRoute(route.VinegarRoute)
|
if serv != nil { //this will happen during testing
|
||||||
|
serv.Router.AddRoute(route.VinegarRoute)
|
||||||
|
}
|
||||||
|
|
||||||
return &route
|
return &route
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMethodHandler(m *map[HttpMethod]VinegarHandlerFunction) VinegarHandlerFunction {
|
func createMethodHandler(m *map[string]VinegarHandlerFunction) VinegarHandlerFunction {
|
||||||
return func(w http.ResponseWriter, req *http.Request) {
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
method := getHttpMethod(req)
|
|
||||||
fn, exists := (*m)[method]
|
fn, exists := (*m)[req.Method]
|
||||||
if exists {
|
if exists {
|
||||||
fn(w, req)
|
fn(w, req)
|
||||||
} else {
|
} else {
|
||||||
@ -55,27 +46,12 @@ func createMethodHandler(m *map[HttpMethod]VinegarHandlerFunction) VinegarHandle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ApiRoute) RegisterHttpMethodHandler(method HttpMethod, handler VinegarHandlerFunction) {
|
func (api *ApiRoute) RegisterHttpMethodHandler(method string, handler VinegarHandlerFunction) {
|
||||||
(*api.HttpMethodRoutes)[method] = handler
|
(*api.HttpMethodRoutes)[method] = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHttpMethod(req *http.Request) HttpMethod {
|
func (api *ApiRoute) AddGetHandler(handler VinegarHandlerFunction) {
|
||||||
switch req.Method {
|
(*api.HttpMethodRoutes)[http.MethodGet] = handler
|
||||||
case http.MethodGet:
|
|
||||||
return GET
|
|
||||||
case "POST":
|
|
||||||
return POST
|
|
||||||
case "PUT":
|
|
||||||
return PUT
|
|
||||||
case "PATCH":
|
|
||||||
return PATCH
|
|
||||||
case "DELETE":
|
|
||||||
return DELETE
|
|
||||||
case "UNDEFINED":
|
|
||||||
default:
|
|
||||||
return UNDEFINED
|
|
||||||
}
|
|
||||||
return UNDEFINED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendApiError(w http.ResponseWriter, httpCode int, messageCode int, message string) {
|
func SendApiError(w http.ResponseWriter, httpCode int, messageCode int, message string) {
|
||||||
|
|||||||
@ -2,13 +2,14 @@ package servlet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"geniuscartel.xyz/vinegar/vinegarUtil"
|
"geniuscartel.xyz/vinegar/vinegarUtil"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -24,31 +25,20 @@ type ErrorResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// VinegarHttpServlet is the main server struct that handles HTTP requests and routing.
|
VinegarWebServlet struct {
|
||||||
// It contains the TCP port to listen on, the routes to match requests against,
|
|
||||||
// and a map of status code to error handling routes.
|
|
||||||
VinegarHttpServlet struct {
|
|
||||||
Port string
|
Port string
|
||||||
Routes []*VinegarWebRoute
|
Router VinegarWebRouter
|
||||||
ErrorRoutes map[int]*TemplateRoute
|
ErrorRoutes map[int]*TemplateRoute
|
||||||
}
|
interrupts chan struct{}
|
||||||
|
errors chan error
|
||||||
// VinegarWebRoute defines a single route in the router.
|
|
||||||
// It contains a regex Pattern to match against the URL path,
|
|
||||||
// a Handler function to call when the route matches,
|
|
||||||
// and an optional Cache to enable caching for the route.
|
|
||||||
VinegarWebRoute struct {
|
|
||||||
Pattern *regexp.Regexp
|
|
||||||
Handler VinegarHandlerFunction
|
|
||||||
Cache vinegarUtil.Cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VinegarHandlerFunction func(w http.ResponseWriter, req *http.Request)
|
VinegarHandlerFunction func(w http.ResponseWriter, req *http.Request)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewServlet(port string) *VinegarHttpServlet {
|
func NewServlet(port string) *VinegarWebServlet {
|
||||||
errs := make(map[int]*TemplateRoute)
|
errs := make(map[int]*TemplateRoute)
|
||||||
srv := VinegarHttpServlet{Port: port, ErrorRoutes: errs}
|
srv := VinegarWebServlet{Port: port, ErrorRoutes: errs, interrupts: make(chan struct{})}
|
||||||
|
|
||||||
return &srv
|
return &srv
|
||||||
}
|
}
|
||||||
@ -60,48 +50,62 @@ func NewServletRoute(routePattern string, handleFunc VinegarHandlerFunction) *Vi
|
|||||||
return &route
|
return &route
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *VinegarHttpServlet) AddRoute(route *VinegarWebRoute) {
|
func (s *VinegarWebServlet) AddErrorRoute(code int, route *TemplateRoute) {
|
||||||
route.Announce()
|
|
||||||
s.Routes = append(s.Routes, route)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *VinegarHttpServlet) AddErrorRoute(code int, route *TemplateRoute) {
|
|
||||||
route.Announce()
|
route.Announce()
|
||||||
s.ErrorRoutes[code] = route
|
s.ErrorRoutes[code] = route
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *VinegarHttpServlet) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (s *VinegarWebServlet) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
path := req.URL.Path
|
err := s.Router.RouteRequest(w, req)
|
||||||
for _, route := range s.Routes {
|
if err != nil {
|
||||||
if route.Pattern.MatchString(path) {
|
s.SendError(w, req, 404, "Resource not found", err)
|
||||||
//fmt.Printf("SERVING: [%s]=>{%s}\n", path, route.Pattern.String())
|
|
||||||
go route.Handler(w, req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
s.SendError(w, req, 404, "Couldn't find your content.", errors.New("failed to match route for ["+path+"]"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *VinegarHttpServlet) Start() error {
|
func (s *VinegarWebServlet) Start() error {
|
||||||
if len(s.Routes) < 1 {
|
if len(s.Router.Routes) < 1 {
|
||||||
log.Fatal("No routes found for server. Nothing to listen and serve.")
|
log.Fatal("No routes found for server. Nothing to listen and serve.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l, listenErr := net.Listen("tcp", s.Port)
|
||||||
|
|
||||||
|
if listenErr != nil {
|
||||||
|
return listenErr
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
err := http.Serve(l, s)
|
||||||
|
if err != nil {
|
||||||
|
s.errors <- err
|
||||||
|
}
|
||||||
|
}()
|
||||||
log.Printf("Listening on [%s]\n", s.Port)
|
log.Printf("Listening on [%s]\n", s.Port)
|
||||||
|
for {
|
||||||
|
|
||||||
err := http.ListenAndServe(s.Port, s)
|
select {
|
||||||
|
case err := <-s.errors:
|
||||||
|
log.Printf("server on port %s failed: %v", s.Port, err)
|
||||||
|
|
||||||
if err != nil {
|
case <-s.interrupts:
|
||||||
return err
|
err := l.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
time.Sleep(5)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *VinegarWebServlet) Shutdown() {
|
||||||
|
s.interrupts <- struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *VinegarWebRoute) Announce() {
|
func (r *VinegarWebRoute) Announce() {
|
||||||
log.Printf("Added route for [%s]\n", r.Pattern.String())
|
log.Printf("Added route for [%s]\n", r.Pattern.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *VinegarHttpServlet) SendError(w http.ResponseWriter, req *http.Request, code int, msg string, aErr error) {
|
func (s *VinegarWebServlet) SendError(w http.ResponseWriter, req *http.Request, code int, msg string, aErr error) {
|
||||||
fmt.Printf("[%d][%s]. Rendering template for code %d with message: %s\n", code, req.URL.Path, code, msg)
|
fmt.Printf("[%d][%s]. Rendering template for code %d with message: %s\n", code, req.URL.Path, code, msg)
|
||||||
out, _ := json.Marshal(aErr)
|
out, _ := json.Marshal(aErr)
|
||||||
fmt.Println(string(out))
|
fmt.Println(string(out))
|
||||||
|
|||||||
@ -1,11 +1,16 @@
|
|||||||
package servlet
|
package servlet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewServlet(t *testing.T) {
|
func TestNewServlet(t *testing.T) {
|
||||||
|
|
||||||
port := ":8080"
|
port := ":8080"
|
||||||
|
|
||||||
srv := NewServlet(port)
|
srv := NewServlet(port)
|
||||||
@ -14,7 +19,7 @@ func TestNewServlet(t *testing.T) {
|
|||||||
t.Errorf("Expected port %s, got %s", port, srv.Port)
|
t.Errorf("Expected port %s, got %s", port, srv.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
if srv.Routes != nil {
|
if srv.Router.Routes != nil {
|
||||||
t.Error("Expected Routes to be nil")
|
t.Error("Expected Routes to be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,3 +27,113 @@ func TestNewServlet(t *testing.T) {
|
|||||||
t.Error("Expected ErrorRoutes to be initialized")
|
t.Error("Expected ErrorRoutes to be initialized")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServletServeTraffic(t *testing.T) {
|
||||||
|
|
||||||
|
// Create a new servlet
|
||||||
|
srv := NewServlet(":8080")
|
||||||
|
|
||||||
|
// Add a test route
|
||||||
|
srv.Router.AddRoute(&VinegarWebRoute{
|
||||||
|
Pattern: regexp.MustCompile("/test"),
|
||||||
|
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("hello"))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Start the server in a goroutine
|
||||||
|
go srv.Start()
|
||||||
|
defer srv.Shutdown()
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
// Make a request to the test route
|
||||||
|
res, err := http.Get("http://localhost:8080/test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify successful response
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
t.Errorf("Expected status OK, got %d", res.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, _ := io.ReadAll(res.Body)
|
||||||
|
res.Body.Close()
|
||||||
|
if string(body) != "hello" {
|
||||||
|
t.Errorf("Unexpected response body %s", string(body))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApiRoute(t *testing.T) {
|
||||||
|
|
||||||
|
// Create a new API route
|
||||||
|
route := NewApiRoute(nil, "/hello")
|
||||||
|
|
||||||
|
// Add a handler for GET requests
|
||||||
|
route.AddGetHandler(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("hello"))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create a request
|
||||||
|
req, _ := http.NewRequest(http.MethodGet, "localhost:8080/hello", nil)
|
||||||
|
|
||||||
|
// Create a ResponseRecorder to record the response
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// Call the handler
|
||||||
|
route.VinegarRoute.Handler(rr, req)
|
||||||
|
|
||||||
|
// Check the status code
|
||||||
|
if status := rr.Code; status != http.StatusOK {
|
||||||
|
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the response body
|
||||||
|
expected := "hello"
|
||||||
|
if rr.Body.String() != expected {
|
||||||
|
t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApiRouteStress(t *testing.T) {
|
||||||
|
route := NewApiRoute(nil, "/hello")
|
||||||
|
|
||||||
|
route.AddGetHandler(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("hello"))
|
||||||
|
})
|
||||||
|
|
||||||
|
n := 1000 // number of requests
|
||||||
|
c := make(chan struct{}, n) // concurrency control
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
go func() {
|
||||||
|
|
||||||
|
// Create a request
|
||||||
|
req, _ := http.NewRequest(http.MethodGet, "localhost:8080/hello", nil)
|
||||||
|
|
||||||
|
// Create a ResponseRecorder to record the response
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
|
||||||
|
// Call the handler
|
||||||
|
route.VinegarRoute.Handler(rr, req)
|
||||||
|
c <- struct{}{}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for requests to complete
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
<-c
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsed := time.Since(start)
|
||||||
|
|
||||||
|
// Print performance stats
|
||||||
|
log.Printf("Completed %d requests in %s", n, elapsed)
|
||||||
|
avg := elapsed / time.Duration(n)
|
||||||
|
log.Printf("Average request time: %s", avg)
|
||||||
|
|
||||||
|
requestsPerSec := float64(n) / elapsed.Seconds()
|
||||||
|
log.Printf("Requests per second: %f", requestsPerSec)
|
||||||
|
}
|
||||||
|
|||||||
@ -18,8 +18,8 @@ type (
|
|||||||
// VinegarRoute is the base route containing the URL pattern and handler.
|
// VinegarRoute is the base route containing the URL pattern and handler.
|
||||||
VinegarRoute *VinegarWebRoute
|
VinegarRoute *VinegarWebRoute
|
||||||
|
|
||||||
// srv is the VinegarHttpServlet instance that this route is attached to.
|
// srv is the VinegarWebServlet instance that this route is attached to.
|
||||||
srv *VinegarHttpServlet
|
srv *VinegarWebServlet
|
||||||
|
|
||||||
// fileRoot is the base file path to serve files from.
|
// fileRoot is the base file path to serve files from.
|
||||||
fileRoot string
|
fileRoot string
|
||||||
@ -32,7 +32,7 @@ type (
|
|||||||
//
|
//
|
||||||
//Params:
|
//Params:
|
||||||
//
|
//
|
||||||
//servlet - The VinegarHttpServlet instance to add the route to
|
//servlet - The VinegarWebServlet instance to add the route to
|
||||||
//
|
//
|
||||||
//urlPattern - The URL regex pattern for route to match
|
//urlPattern - The URL regex pattern for route to match
|
||||||
//
|
//
|
||||||
@ -40,13 +40,13 @@ type (
|
|||||||
//
|
//
|
||||||
//useCache - Whether to use caching for this route
|
//useCache - Whether to use caching for this route
|
||||||
//
|
//
|
||||||
// A RouteConstructor is a function that accepts a VinegarHttpServlet, urlPattern, file path, and cache option. It uses
|
// A RouteConstructor is a function that accepts a VinegarWebServlet, urlPattern, file path, and cache option. It uses
|
||||||
// these to construct and return a FileRoute.
|
// these to construct and return a FileRoute.
|
||||||
// The return value is a FileRoute that will serve the files from the given path.
|
// The return value is a FileRoute that will serve the files from the given path.
|
||||||
//
|
//
|
||||||
// This function signature allows encapsulating the creation of different types of FileRoutes. It is used to define
|
// This function signature allows encapsulating the creation of different types of FileRoutes. It is used to define
|
||||||
// constructor functions for each file type, like NewTextRoute or NewImageRoute.
|
// constructor functions for each file type, like NewTextRoute or NewImageRoute.
|
||||||
RouteConstructor func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error)
|
RouteConstructor func(servlet *VinegarWebServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error)
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewTextRoute creates a new FileRoute for serving text files.
|
// NewTextRoute creates a new FileRoute for serving text files.
|
||||||
@ -55,7 +55,7 @@ type (
|
|||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
//
|
//
|
||||||
// servlet - The VinegarHttpServlet instance to attach the route to.
|
// servlet - The VinegarWebServlet instance to attach the route to.
|
||||||
//
|
//
|
||||||
// urlPattern - The URL regex pattern that triggers this route.
|
// urlPattern - The URL regex pattern that triggers this route.
|
||||||
//
|
//
|
||||||
@ -66,8 +66,8 @@ type (
|
|||||||
// Returns:
|
// Returns:
|
||||||
//
|
//
|
||||||
// A FileRoute instance configured for serving text files, added to
|
// A FileRoute instance configured for serving text files, added to
|
||||||
// the provided VinegarHttpServlet.
|
// the provided VinegarWebServlet.
|
||||||
var NewTextRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error) {
|
var NewTextRoute RouteConstructor = func(servlet *VinegarWebServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error) {
|
||||||
fileRoot := filepath.Clean(pathlike)
|
fileRoot := filepath.Clean(pathlike)
|
||||||
if strings.Contains(fileRoot, "../") {
|
if strings.Contains(fileRoot, "../") {
|
||||||
return nil, errors.New("Traversing the directory is not allowed, use an absolute filepath instead")
|
return nil, errors.New("Traversing the directory is not allowed, use an absolute filepath instead")
|
||||||
@ -78,12 +78,12 @@ var NewTextRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPattern
|
|||||||
rootRoute := NewServletRoute(urlPattern, textRouteHandler) //i *still* kinda don't like this pattern
|
rootRoute := NewServletRoute(urlPattern, textRouteHandler) //i *still* kinda don't like this pattern
|
||||||
route.VinegarRoute = rootRoute
|
route.VinegarRoute = rootRoute
|
||||||
|
|
||||||
servlet.AddRoute(route.VinegarRoute)
|
servlet.Router.AddRoute(route.VinegarRoute)
|
||||||
|
|
||||||
return &route, nil
|
return &route, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var NewImageRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error) {
|
var NewImageRoute RouteConstructor = func(servlet *VinegarWebServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error) {
|
||||||
fileRoot := filepath.Clean(pathlike)
|
fileRoot := filepath.Clean(pathlike)
|
||||||
if strings.Contains(fileRoot, "../") {
|
if strings.Contains(fileRoot, "../") {
|
||||||
return nil, errors.New("Traversing the directory is not allowed, use an absolute filepath instead")
|
return nil, errors.New("Traversing the directory is not allowed, use an absolute filepath instead")
|
||||||
@ -93,11 +93,11 @@ var NewImageRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPatter
|
|||||||
rootRoute := NewServletRoute(urlPattern, createUncompressedFileServletFunction(&route, defaultPrune, pathlike))
|
rootRoute := NewServletRoute(urlPattern, createUncompressedFileServletFunction(&route, defaultPrune, pathlike))
|
||||||
route.VinegarRoute = rootRoute //i *kinda* don't like this pattern
|
route.VinegarRoute = rootRoute //i *kinda* don't like this pattern
|
||||||
|
|
||||||
servlet.AddRoute(route.VinegarRoute)
|
servlet.Router.AddRoute(route.VinegarRoute)
|
||||||
return &route, nil
|
return &route, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var NewSingleFileRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error) {
|
var NewSingleFileRoute RouteConstructor = func(servlet *VinegarWebServlet, urlPattern string, pathlike string, useCache bool) (*FileRoute, error) {
|
||||||
route := FileRoute{
|
route := FileRoute{
|
||||||
srv: servlet,
|
srv: servlet,
|
||||||
fileRoot: pathlike,
|
fileRoot: pathlike,
|
||||||
@ -115,7 +115,7 @@ var NewSingleFileRoute RouteConstructor = func(servlet *VinegarHttpServlet, urlP
|
|||||||
|
|
||||||
route.VinegarRoute = parentRoute
|
route.VinegarRoute = parentRoute
|
||||||
|
|
||||||
servlet.AddRoute(route.VinegarRoute)
|
servlet.Router.AddRoute(route.VinegarRoute)
|
||||||
|
|
||||||
return &route, nil
|
return &route, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import (
|
|||||||
type (
|
type (
|
||||||
TemplateRoute struct {
|
TemplateRoute struct {
|
||||||
*VinegarWebRoute
|
*VinegarWebRoute
|
||||||
srv *VinegarHttpServlet
|
srv *VinegarWebServlet
|
||||||
fileRoot string
|
fileRoot string
|
||||||
TemplateManager *TemplateManager
|
TemplateManager *TemplateManager
|
||||||
UseCache bool
|
UseCache bool
|
||||||
@ -16,7 +16,7 @@ type (
|
|||||||
TemplateRouteHandlerFunc func(w http.ResponseWriter, r *http.Request, tm *TemplateManager)
|
TemplateRouteHandlerFunc func(w http.ResponseWriter, r *http.Request, tm *TemplateManager)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTemplateRoute(servlet *VinegarHttpServlet, urlPattern string, templatePath string, componentPath string, handler TemplateRouteHandlerFunc) *TemplateRoute {
|
func NewTemplateRoute(servlet *VinegarWebServlet, urlPattern string, templatePath string, componentPath string, handler TemplateRouteHandlerFunc) *TemplateRoute {
|
||||||
defaultPrune := strings.Replace(urlPattern, ".*", "", -1)
|
defaultPrune := strings.Replace(urlPattern, ".*", "", -1)
|
||||||
tm := NewTemplateManager(templatePath, componentPath)
|
tm := NewTemplateManager(templatePath, componentPath)
|
||||||
rootRoute := NewServletRoute(defaultPrune, createTemplateRouteFunction(tm, handler))
|
rootRoute := NewServletRoute(defaultPrune, createTemplateRouteFunction(tm, handler))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user