diff --git a/context.go b/context.go index 0699ec5..eec329c 100644 --- a/context.go +++ b/context.go @@ -70,17 +70,9 @@ func (c *Context) NoContent(code int) error { // JSON returns the given status code and writes JSON to the body func (c *Context) JSON(code int, data interface{}) error { - // write to buffer first in case of error - var buf bytes.Buffer - err := json.NewEncoder(&buf).Encode(data) - if err != nil { - return err - } - c.Response.Header().Set(`Content-Type`, `application/json`) c.Response.WriteHeader(code) - _, err = io.Copy(c.Response, &buf) - return err + return json.NewEncoder(c.Response).Encode(data) // TODO: Encode to buffer first to prevent partial responses on error } // Render renders a templating using the Renderer set in router @@ -113,17 +105,14 @@ func (c *Context) Get(key string) interface{} { // RealIP uses proxy headers for the real ip, if none exist the IP of the current connection is returned func (c *Context) RealIP() string { - reqIP := c.Request.RemoteAddr - if ip := c.Request.Header.Get(`X-Forwarded-For`); ip != `` { - reqIP = strings.Split(ip, `, `)[0] - } else if ip := c.Request.Header.Get(`X-Real-IP`); ip != `` { - reqIP = ip + return strings.Split(ip, `, `)[0] } - ra, _, _ := net.SplitHostPort(reqIP) - if ra != `` { - reqIP = ra + if ip := c.Request.Header.Get(`X-Real-IP`); ip != `` { + return ip } - return reqIP + + ra, _, _ := net.SplitHostPort(c.Request.RemoteAddr) + return ra } diff --git a/default.go b/default.go index 075cdf1..ecda050 100644 --- a/default.go +++ b/default.go @@ -13,7 +13,7 @@ func defaultMethodNotAllowedHandler(c *Context) error { return c.StatusText(http.StatusMethodNotAllowed) } -func defaultErrorHandler(c *Context, _ interface{}) { +func defaultErrorHandler(c *Context, err interface{}) { _ = c.StatusText(http.StatusInternalServerError) } diff --git a/go.mod b/go.mod deleted file mode 100644 index 7ae044b..0000000 --- a/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module git.fuyu.moe/Fuyu/router - -go 1.22.0 - -require github.com/julienschmidt/httprouter v1.3.0 diff --git a/go.sum b/go.sum deleted file mode 100644 index 096c54e..0000000 --- a/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= diff --git a/group.go b/group.go index 150876d..e9a1451 100644 --- a/group.go +++ b/group.go @@ -1,9 +1,6 @@ package router -import ( - urlpath "path" - "slices" -) +import urlpath "path" func join(prefix, path string) string { return urlpath.Join(prefix, urlpath.Clean(path)) @@ -18,40 +15,40 @@ type Group struct { // Group creates a new router group with a shared prefix and set of middlewares func (g *Group) Group(prefix string, middleware ...Middleware) *Group { - return &Group{prefix: join(g.prefix, prefix), router: g.router, middleware: slices.Concat(g.middleware, middleware)} + return &Group{prefix: join(g.prefix, prefix), router: g.router, middleware: append(g.middleware, middleware...)} } // GET adds a GET route func (g *Group) GET(path string, handle Handle, middleware ...Middleware) { - g.router.GET(join(g.prefix, path), handle, slices.Concat(g.middleware, middleware)...) + g.router.GET(join(g.prefix, path), handle, append(g.middleware, middleware...)...) } // POST adds a POST route func (g *Group) POST(path string, handle interface{}, middleware ...Middleware) { - g.router.POST(join(g.prefix, path), handle, slices.Concat(g.middleware, middleware)...) + g.router.POST(join(g.prefix, path), handle, append(g.middleware, middleware...)...) } // DELETE adds a DELETE route func (g *Group) DELETE(path string, handle Handle, middleware ...Middleware) { - g.router.DELETE(join(g.prefix, path), handle, slices.Concat(g.middleware, middleware)...) + g.router.DELETE(join(g.prefix, path), handle, append(g.middleware, middleware...)...) } // PUT adds a PUT route func (g *Group) PUT(path string, handle interface{}, middleware ...Middleware) { - g.router.PUT(join(g.prefix, path), handle, slices.Concat(g.middleware, middleware)...) + g.router.PUT(join(g.prefix, path), handle, append(g.middleware, middleware...)...) } // PATCH adds a PATCH route func (g *Group) PATCH(path string, handle interface{}, middleware ...Middleware) { - g.router.PATCH(join(g.prefix, path), handle, slices.Concat(g.middleware, middleware)...) + g.router.PATCH(join(g.prefix, path), handle, append(g.middleware, middleware...)...) } // HEAD adds a HEAD route func (g *Group) HEAD(path string, handle Handle, middleware ...Middleware) { - g.router.HEAD(join(g.prefix, path), handle, slices.Concat(g.middleware, middleware)...) + g.router.HEAD(join(g.prefix, path), handle, append(g.middleware, middleware...)...) } // OPTIONS adds a OPTIONS route func (g *Group) OPTIONS(path string, handle Handle, middleware ...Middleware) { - g.router.OPTIONS(join(g.prefix, path), handle, slices.Concat(g.middleware, middleware)...) + g.router.OPTIONS(join(g.prefix, path), handle, append(g.middleware, middleware...)...) } diff --git a/router.go b/router.go index f3252d9..d869fc6 100644 --- a/router.go +++ b/router.go @@ -3,10 +3,8 @@ package router import ( "context" "crypto/tls" - "errors" "net/http" "reflect" - "slices" "time" "github.com/julienschmidt/httprouter" @@ -46,12 +44,7 @@ type Router struct { // New returns a new Router func New() *Router { - return &Router{ - Reader: defaultReader, - NotFoundHandler: defaultNotFoundHandler, - MethodNotAllowedHandler: defaultMethodNotAllowedHandler, - ErrorHandler: defaultErrorHandler, - } + return &Router{Reader: defaultReader, NotFoundHandler: defaultNotFoundHandler, MethodNotAllowedHandler: defaultMethodNotAllowedHandler, ErrorHandler: defaultErrorHandler} } // Use adds a global middleware @@ -127,7 +120,7 @@ func (r *Router) Stop() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() err := r.server.Shutdown(ctx) - if errors.Is(err, context.DeadlineExceeded) { + if err == context.DeadlineExceeded { err = r.server.Close() } r.server = nil @@ -144,9 +137,11 @@ func (r *Router) getHttpr() http.Handler { handle = handlePOST(r, v.Handle) } - httpr.Handle(v.Method, v.Path, handleReq(r, handle, - slices.Concat(r.middleware, v.Middleware), - )) + middleware := make([]Middleware, len(r.middleware)+len(v.Middleware)) + copy(middleware, r.middleware) + copy(middleware[len(r.middleware):], v.Middleware) + + httpr.Handle(v.Method, v.Path, handleReq(r, handle, middleware)) } httpr.NotFound = http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { @@ -237,6 +232,7 @@ func handleReq(r *Router, handle Handle, m []Middleware) httprouter.Handle { } err := f(c) + if err != nil { r.ErrorHandler(c, err) }