extract HTTP logic to shared module
11 files changed, 174 insertions(+), 111 deletions(-)
M domain/content/publisher/app.go → domain/content/publisher/app.go
@@ -7,10 +7,10 @@ "github.com/Southclaws/fault" "github.com/Southclaws/fault/fmsg" "go.hacdias.com/indielib/indieauth" - ihttp "alin.ovh/homestead/domain/web/middleware" "alin.ovh/homestead/domain/web/server" "alin.ovh/homestead/domain/web/templates" "alin.ovh/homestead/shared/config" + ihttp "alin.ovh/homestead/shared/http" "alin.ovh/x/log" )
M domain/content/publisher/mux.go → domain/content/publisher/mux.go
@@ -4,8 +4,8 @@ import ( "net/http" pubtpl "alin.ovh/homestead/domain/content/publisher/templates" - ihttp "alin.ovh/homestead/domain/web/middleware" "alin.ovh/homestead/domain/web/templates" + ihttp "alin.ovh/homestead/shared/http" ) func (app *App) Index(w http.ResponseWriter, _ *http.Request) *ihttp.Error {
D domain/web/middleware/error.go
@@ -1,20 +0,0 @@ -package http - -import ( - "fmt" - "net/http" -) - -type Error struct { - Code int - Message string - Cause error -} - -func (e *Error) Error() string { - if e.Message == "" { - e.Message = http.StatusText(e.Code) - } - - return fmt.Sprintf("%d %s", e.Code, e.Message) -}
D domain/web/middleware/mux.go
@@ -1,50 +0,0 @@ -package http - -import ( - "net/http" - - "alin.ovh/x/log" -) - -type HandleFunc func(http.ResponseWriter, *http.Request) *Error -type Handler interface { - ServeHTTP(http.ResponseWriter, *http.Request) *Error -} -type ErrorHandler func(*Error, http.ResponseWriter, *http.Request) - -type ServeMux struct { - log *log.Logger - errorHandler ErrorHandler - *http.ServeMux -} - -func NewServeMux() *ServeMux { - return &ServeMux{ - ServeMux: http.NewServeMux(), - errorHandler: func(err *Error, w http.ResponseWriter, _ *http.Request) { - http.Error(w, err.Message, err.Code) - }, - } -} - -func (sm *ServeMux) Handle(pattern string, handler Handler) { - sm.HandleFunc(pattern, handler.ServeHTTP) -} - -func (sm *ServeMux) HandleFunc(pattern string, handler HandleFunc) { - sm.ServeMux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { - defer func() { - if fail := recover(); fail != nil { - w.WriteHeader(http.StatusInternalServerError) - sm.log.Error("runtime panic!", "error", fail) - } - }() - if err := handler(w, r); err != nil { - sm.errorHandler(err, w, r) - } - }) -} - -func (sm *ServeMux) HandleError(fn ErrorHandler) { - sm.errorHandler = fn -}
D domain/web/middleware/redirect.go
@@ -1,14 +0,0 @@ -package http - -import ( - "net/http" - "net/url" -) - -func Redirect(w http.ResponseWriter, r *http.Request, url *url.URL, code int) { - http.Redirect(w, r, url.String(), code) -} - -func RedirectHandler(url *url.URL, code int) http.Handler { - return http.RedirectHandler(url.String(), code) -}
M domain/web/mux.go → domain/web/mux.go
@@ -9,9 +9,9 @@ "slices" "strings" calendar "alin.ovh/homestead/domain/calendar/templates" - ihttp "alin.ovh/homestead/domain/web/middleware" "alin.ovh/homestead/domain/web/server" "alin.ovh/homestead/domain/web/templates" + ihttp "alin.ovh/homestead/shared/http" "github.com/kevinpollet/nego" )@@ -21,18 +21,13 @@ if r.URL.Query().Get("resource") == website.acctResource { w.Header().Add("Content-Type", "application/jrd+json") w.Header().Add("Access-Control-Allow-Origin", "*") if err := json.NewEncoder(w).Encode(website.me); err != nil { - return &ihttp.Error{ - Code: http.StatusInternalServerError, - Cause: err, - } + return ihttp.InternalServerError("Failed to encode webfinger response", err) } return nil } - return &ihttp.Error{ - Code: http.StatusNotFound, - } + return ihttp.NotFound("Resource not found") } func (website *Website) ErrorHandler(err *ihttp.Error, w http.ResponseWriter, r *http.Request) {@@ -63,18 +58,12 @@ file, err := website.reader.GetFile(urlPath) if err != nil { website.log.Warn("Error reading file", "error", err) - return &ihttp.Error{ - Message: "Error reading file", - Code: http.StatusInternalServerError, - } + return ihttp.InternalServerError("Error reading file", err) } if file == nil { website.counter.Count(r, "404") - return &ihttp.Error{ - Message: "File not found", - Code: http.StatusNotFound, - } + return ihttp.NotFound("File not found") } website.counter.Count(r, file.Title) w.Header().Add("ETag", file.Etag)@@ -133,16 +122,11 @@ case r.URL.Query().Has("go-get") && r.URL.Query().Get("go-get") == "1": return website.ServeHTTP(w, r) case slices.Contains(website.config.Domains, r.Host): path, _ := website.reader.CanonicalisePath(r.URL.Path) - ihttp.Redirect( - w, - r, - website.config.BaseURL.JoinPath(path), - http.StatusMovedPermanently, - ) + ihttp.PermanentRedirect(w, r, website.config.BaseURL.JoinPath(path)) case re.MatchString(r.Host): url := website.config.BaseURL.JoinPath() url.Host = re.ReplaceAllString(r.Host, replace) - ihttp.Redirect(w, r, url, http.StatusTemporaryRedirect) + ihttp.TemporaryRedirect(w, r, url) case true: http.NotFound(w, r) }
M domain/web/templates/error.go → domain/web/templates/error.go
@@ -5,7 +5,7 @@ "strconv" g "alin.ovh/gomponents" . "alin.ovh/gomponents/html" - http "alin.ovh/homestead/domain/web/middleware" + http "alin.ovh/homestead/shared/http" ) func Error(site SiteSettings, err *http.Error) g.Node {
M domain/web/website.go → domain/web/website.go
@@ -14,12 +14,12 @@ "alin.ovh/homestead/domain/analytics/goatcounter" "alin.ovh/homestead/domain/analytics/nullcounter" "alin.ovh/homestead/domain/calendar" "alin.ovh/homestead/domain/content/fetcher" - ihttp "alin.ovh/homestead/domain/web/middleware" "alin.ovh/homestead/domain/web/server" "alin.ovh/homestead/domain/web/templates" "alin.ovh/homestead/shared/config" "alin.ovh/homestead/shared/events" "alin.ovh/homestead/shared/file" + ihttp "alin.ovh/homestead/shared/http" "alin.ovh/homestead/shared/storage" "alin.ovh/homestead/shared/storage/sqlite" "alin.ovh/x/log"