From 5168a9476f0e83264ecafc85bc9145e8bdcbb8dc Mon Sep 17 00:00:00 2001 From: Gabriel Arakaki Giovanini Date: Sat, 5 Aug 2023 19:26:29 +0200 Subject: ref: Move net/http I was young and naive, fasthttp does not fit my needs and make development slower. I'll move to net/http since it has a wider support and will spare some time on implementation detail things (like CSRF). It will allow me to reduce a bit of the code since there may be lib for handling cookie encryption and auth in general. --- pkg/ext/fileserver.go | 33 ----------------------- pkg/ext/middleware.go | 74 +++++++++++++++++++++++++-------------------------- pkg/ext/responses.go | 30 +++++---------------- pkg/ext/router.go | 45 ++++++++++++++++--------------- 4 files changed, 65 insertions(+), 117 deletions(-) delete mode 100644 pkg/ext/fileserver.go (limited to 'pkg/ext') diff --git a/pkg/ext/fileserver.go b/pkg/ext/fileserver.go deleted file mode 100644 index 87c1ae8..0000000 --- a/pkg/ext/fileserver.go +++ /dev/null @@ -1,33 +0,0 @@ -package ext - -import ( - "io/fs" - "mime" - "path/filepath" - - "github.com/valyala/fasthttp" -) - -type FileSystem interface { - Open(name string) (fs.File, error) -} - -// This is a VERY simple file server. It does not take a lot into consideration -// and it should only be used to return small predictable files, like in the -// static folder. -func FileServer(rootFS FileSystem) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { - path := ctx.UserValue("filepath").(string) - - f, err := rootFS.Open(path) - if err != nil { - InternalServerError(ctx, err) - return - } - defer f.Close() - - m := mime.TypeByExtension(filepath.Ext(path)) - ctx.SetContentType(m) - ctx.SetBodyStream(f, -1) - } -} diff --git a/pkg/ext/middleware.go b/pkg/ext/middleware.go index bcc6c5f..fe2d185 100644 --- a/pkg/ext/middleware.go +++ b/pkg/ext/middleware.go @@ -1,22 +1,22 @@ package ext import ( + "context" "encoding/base64" + "errors" + "net/http" "time" "github.com/sirupsen/logrus" - "github.com/valyala/fasthttp" "git.sr.ht/~gabrielgio/img/pkg/database/repository" "git.sr.ht/~gabrielgio/img/pkg/service" ) -func HTML(next fasthttp.RequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { - if len(ctx.Request.Header.ContentType()) > 0 { - ctx.Response.Header.SetContentType("text/html") - } - next(ctx) +func HTML(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html") + next(w, r) } } @@ -30,17 +30,15 @@ func NewLogMiddleare(log *logrus.Entry) *LogMiddleware { } } -func (l *LogMiddleware) HTTP(next fasthttp.RequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { +func (l *LogMiddleware) HTTP(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { start := time.Now() - next(ctx) + next(w, r) elapsed := time.Since(start) l.entry. WithField("time", elapsed). - WithField("code", ctx.Response.StatusCode()). - WithField("path", string(ctx.Path())). - WithField("bytes", len(ctx.Response.Body())). - Info(string(ctx.Request.Header.Method())) + WithField("path", r.URL.Path). + Info(r.Method) } } @@ -56,23 +54,23 @@ func NewAuthMiddleware(key []byte, log *logrus.Entry) *AuthMiddleware { } } -func (a *AuthMiddleware) LoggedIn(next fasthttp.RequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { - path := string(ctx.Path()) +func (a *AuthMiddleware) LoggedIn(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + path := string(r.URL.Path) if path == "/login" || path == "/initial" { - next(ctx) + next(w, r) return } redirectLogin := "/login?redirect=" + path - authBase64 := ctx.Request.Header.Cookie("auth") - if authBase64 == nil { + authBase64, err := r.Cookie("auth") + if errors.Is(err, http.ErrNoCookie) { a.entry.Info("No auth provided") - ctx.Redirect(redirectLogin, 307) + http.Redirect(w, r, redirectLogin, http.StatusTemporaryRedirect) return } - auth, err := base64.StdEncoding.DecodeString(string(authBase64)) + auth, err := base64.StdEncoding.DecodeString(authBase64.Value) if err != nil { a.entry.Error(err) return @@ -81,20 +79,20 @@ func (a *AuthMiddleware) LoggedIn(next fasthttp.RequestHandler) fasthttp.Request token, err := service.ReadToken(auth, a.key) if err != nil { a.entry.Error(err) - ctx.Redirect(redirectLogin, 307) + http.Redirect(w, r, redirectLogin, http.StatusTemporaryRedirect) return } - ctx.SetUserValue("token", token) + r = r.WithContext(context.WithValue(r.Context(), "token", token)) a.entry. WithField("userID", token.UserID). WithField("username", token.Username). Info("user recognized") - next(ctx) + next(w, r) } } -func GetTokenFromCtx(ctx *fasthttp.RequestCtx) *service.Token { - tokenValue := ctx.UserValue("token") +func GetTokenFromCtx(w http.ResponseWriter, r *http.Request) *service.Token { + tokenValue := r.Context().Value("token") if token, ok := tokenValue.(*service.Token); ok { return token } @@ -111,31 +109,31 @@ func NewInitialSetupMiddleware(userRepository repository.UserRepository) *Initia } } -func (i *InitialSetupMiddleware) Check(next fasthttp.RequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { +func (i *InitialSetupMiddleware) Check(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { // if user has been set to context it is logged in already - _, ok := ctx.UserValue("token").(*service.Token) - if ok { - next(ctx) + token := GetTokenFromCtx(w, r) + if token == nil { + next(w, r) return } - path := string(ctx.Path()) + path := r.URL.Path if path == "/initial" { - next(ctx) + next(w, r) return } - exists, err := i.userRepository.Any(ctx) + exists, err := i.userRepository.Any(r.Context()) if err != nil { - InternalServerError(ctx, err) + InternalServerError(w, err) return } if exists { - next(ctx) + next(w, r) return } - ctx.Redirect("/initial", 307) + http.Redirect(w, r, "/initial", http.StatusTemporaryRedirect) } } diff --git a/pkg/ext/responses.go b/pkg/ext/responses.go index dbad5b2..ba58dd5 100644 --- a/pkg/ext/responses.go +++ b/pkg/ext/responses.go @@ -1,39 +1,21 @@ package ext import ( - "bytes" "fmt" - - "github.com/valyala/fasthttp" + "net/http" "git.sr.ht/~gabrielgio/img/templates" ) -var ( - ContentTypeHTML = []byte("text/html") -) - -func NotFoundHTML(ctx *fasthttp.RequestCtx) { - templates.WritePageTemplate(ctx, &templates.ErrorPage{ +func NotFound(w http.ResponseWriter, r *http.Request) { + templates.WritePageTemplate(w, &templates.ErrorPage{ Err: "Not Found", }) } -func NotFound(ctx *fasthttp.RequestCtx) { - ctx.Response.SetStatusCode(404) - ct := ctx.Response.Header.ContentType() - if bytes.Equal(ct, ContentTypeHTML) { - NotFoundHTML(ctx) - } -} - -func InternalServerError(ctx *fasthttp.RequestCtx, err error) { - ctx.Response.SetStatusCode(500) - templates.WritePageTemplate(ctx, &templates.ErrorPage{ +func InternalServerError(w http.ResponseWriter, err error) { + w.WriteHeader(http.StatusInternalServerError) + templates.WritePageTemplate(w, &templates.ErrorPage{ Err: fmt.Sprintf("Internal Server Error:\n%s", err.Error()), }) } - -func NoContent(ctx *fasthttp.RequestCtx) { - ctx.Response.SetStatusCode(204) -} diff --git a/pkg/ext/router.go b/pkg/ext/router.go index 74f0a95..8b9a310 100644 --- a/pkg/ext/router.go +++ b/pkg/ext/router.go @@ -1,51 +1,52 @@ package ext import ( - "github.com/fasthttp/router" - "github.com/valyala/fasthttp" + "net/http" + + "github.com/gorilla/mux" ) type ( Router struct { middlewares []Middleware - fastRouter *router.Router + router *mux.Router } - Middleware func(next fasthttp.RequestHandler) fasthttp.RequestHandler - ErrorRequestHandler func(ctx *fasthttp.RequestCtx) error + Middleware func(next http.HandlerFunc) http.HandlerFunc + ErrorRequestHandler func(w http.ResponseWriter, r *http.Request) error ) -func NewRouter(nestedRouter *router.Router) *Router { +func NewRouter(nestedRouter *mux.Router) *Router { return &Router{ - fastRouter: nestedRouter, + router: nestedRouter, } } -func (self *Router) AddMiddleware(middleware Middleware) { - self.middlewares = append(self.middlewares, middleware) +func (r *Router) AddMiddleware(middleware Middleware) { + r.middlewares = append(r.middlewares, middleware) } -func wrapError(next ErrorRequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { - if err := next(ctx); err != nil { - ctx.Response.SetStatusCode(500) - InternalServerError(ctx, err) +func wrapError(next ErrorRequestHandler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if err := next(w, r); err != nil { + w.WriteHeader(http.StatusInternalServerError) + InternalServerError(w, err) } } } -func (self *Router) run(next ErrorRequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { +func (r *Router) run(next ErrorRequestHandler) http.HandlerFunc { + return func(w http.ResponseWriter, re *http.Request) { req := wrapError(next) - for _, r := range self.middlewares { + for _, r := range r.middlewares { req = r(req) } - req(ctx) + req(w, re) } } -func (self *Router) GET(path string, handler ErrorRequestHandler) { - self.fastRouter.GET(path, self.run(handler)) +func (r *Router) GET(path string, handler ErrorRequestHandler) { + r.router.HandleFunc(path, r.run(handler)).Methods("GET") } -func (self *Router) POST(path string, handler ErrorRequestHandler) { - self.fastRouter.POST(path, self.run(handler)) +func (r *Router) POST(path string, handler ErrorRequestHandler) { + r.router.HandleFunc(path, r.run(handler)).Methods("POSt") } -- cgit v1.2.3