Chore: Refactor error handling and resource management across multiple files (golangci-lint)

- Updated error handling to use the error return value for resource closures in tests and functions, ensuring proper error reporting.
- Replaced direct calls to `Close()` with deferred functions that handle errors gracefully.
- Improved readability by using `strings.ReplaceAll` instead of `strings.Replace` for string manipulation.
- Enhanced network connection handling by adding default cases for unsupported network types.
- Updated HTTP response handling to use the appropriate status codes and error messages.
- Removed unused variables and commented-out code to clean up the codebase.
This commit is contained in:
Ralph Slooten
2025-06-22 10:32:03 +12:00
parent 429d2e2b3a
commit f99d9ecf69
35 changed files with 250 additions and 232 deletions

View File

@@ -18,7 +18,7 @@ func fourOFour(w http.ResponseWriter) {
w.Header().Set("Content-Security-Policy", config.ContentSecurityPolicy)
w.WriteHeader(http.StatusNotFound)
w.Header().Set("Content-Type", "text/plain")
fmt.Fprint(w, "404 page not found")
_, _ = fmt.Fprint(w, "404 page not found")
}
// HTTPError returns a basic error message (400 response)
@@ -27,7 +27,7 @@ func httpError(w http.ResponseWriter, msg string) {
w.Header().Set("Content-Security-Policy", config.ContentSecurityPolicy)
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", "text/plain")
fmt.Fprint(w, msg)
_, _ = fmt.Fprint(w, msg)
}
// httpJSONError returns a basic error message (400 response) in JSON format

View File

@@ -49,7 +49,7 @@ func GetMessage(w http.ResponseWriter, r *http.Request) {
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
_, _ = fmt.Fprint(w, err.Error())
return
}
}
@@ -108,7 +108,7 @@ func GetHeaders(w http.ResponseWriter, r *http.Request) {
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
_, _ = fmt.Fprint(w, err.Error())
return
}
}
@@ -179,7 +179,7 @@ func DownloadAttachment(w http.ResponseWriter, r *http.Request) {
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
_, _ = fmt.Fprint(w, err.Error())
return
}
}
@@ -238,7 +238,7 @@ func DownloadRaw(w http.ResponseWriter, r *http.Request) {
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
_, _ = fmt.Fprint(w, err.Error())
return
}
}

View File

@@ -210,7 +210,7 @@ func SpamAssassinCheck(w http.ResponseWriter, r *http.Request) {
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
_, _ = fmt.Fprint(w, err.Error())
return
}
}

View File

@@ -67,7 +67,7 @@ func GetMessageHTML(w http.ResponseWriter, r *http.Request) {
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
_, _ = fmt.Fprint(w, err.Error())
return
}
}
@@ -75,12 +75,12 @@ func GetMessageHTML(w http.ResponseWriter, r *http.Request) {
msg, err := storage.GetMessage(id)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, "Message not found")
_, _ = fmt.Fprint(w, "Message not found")
return
}
if msg.HTML == "" {
w.WriteHeader(404)
fmt.Fprint(w, "This message does not contain a HTML part")
_, _ = fmt.Fprint(w, "This message does not contain a HTML part")
return
}
@@ -161,7 +161,7 @@ func GetMessageText(w http.ResponseWriter, r *http.Request) {
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
_, _ = fmt.Fprint(w, err.Error())
return
}
}
@@ -169,7 +169,7 @@ func GetMessageText(w http.ResponseWriter, r *http.Request) {
msg, err := storage.GetMessage(id)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, "Message not found")
_, _ = fmt.Fprint(w, "Message not found")
return
}

View File

@@ -39,5 +39,5 @@ func RedirectToLatestMessage(w http.ResponseWriter, r *http.Request) {
}
}
http.Redirect(w, r, uri, 302)
http.Redirect(w, r, uri, http.StatusFound)
}

View File

@@ -60,7 +60,8 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
return
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(resp.Body)
if err != nil {
logger.Log().Warnf("[proxy] %s", err.Error())
@@ -141,7 +142,7 @@ func absoluteURL(link, baseURL string) (string, error) {
// ensure link is HTTP(S)
if result.Scheme != "http" && result.Scheme != "https" {
return link, fmt.Errorf("Invalid URL: %s", result.String())
return link, fmt.Errorf("invalid URL: %s", result.String())
}
return result.String(), nil
@@ -153,5 +154,5 @@ func httpError(w http.ResponseWriter, msg string) {
w.Header().Set("Content-Security-Policy", config.ContentSecurityPolicy)
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", "text/plain")
fmt.Fprint(w, msg)
_, _ = fmt.Fprint(w, msg)
}

View File

@@ -290,8 +290,9 @@ func middleWareFunc(fn http.HandlerFunc) http.HandlerFunc {
}
// Check basic authentication headers if configured.
// OPTIONS requests are skipped if CORS is enabled, since browsers omit credentials for preflight.
if !(AccessControlAllowOrigin != "" && r.Method == http.MethodOptions) && auth.UICredentials != nil {
// OPTIONS requests are skipped if CORS is enabled, since browsers omit credentials for preflight checks.
isCORSOptionsRequest := AccessControlAllowOrigin != "" && r.Method == http.MethodOptions
if !isCORSOptionsRequest && auth.UICredentials != nil {
user, pass, ok := r.BasicAuth()
if !ok {
@@ -312,7 +313,7 @@ func middleWareFunc(fn http.HandlerFunc) http.HandlerFunc {
w.Header().Set("Content-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
defer func() { _ = gz.Close() }()
gzr := gzipResponseWriter{Writer: gz, ResponseWriter: w}
fn(gzr, r)
}

View File

@@ -345,7 +345,9 @@ func TestSendAPIAuthMiddleware(t *testing.T) {
// Set up UI auth that would normally block requests
testHash, _ := bcrypt.GenerateFromPassword([]byte("testpass"), bcrypt.DefaultCost)
auth.SetUIAuth("testuser:" + string(testHash))
if err := auth.SetUIAuth("testuser:" + string(testHash)); err != nil {
t.Fatalf("Failed to set UI auth: %s", err.Error())
}
r := apiRoutes()
ts := httptest.NewServer(r)
@@ -374,11 +376,15 @@ func TestSendAPIAuthMiddleware(t *testing.T) {
// Set up UI auth
uiHash, _ := bcrypt.GenerateFromPassword([]byte("uipass"), bcrypt.DefaultCost)
auth.SetUIAuth("uiuser:" + string(uiHash))
if err := auth.SetUIAuth("uiuser:" + string(uiHash)); err != nil {
t.Fatalf("Failed to set UI auth: %s", err.Error())
}
// Set up dedicated Send API auth
sendHash, _ := bcrypt.GenerateFromPassword([]byte("sendpass"), bcrypt.DefaultCost)
auth.SetSendAPIAuth("senduser:" + string(sendHash))
if err := auth.SetSendAPIAuth("senduser:" + string(sendHash)); err != nil {
t.Fatalf("Failed to set Send API auth: %s", err.Error())
}
r := apiRoutes()
ts := httptest.NewServer(r)
@@ -421,7 +427,9 @@ func TestSendAPIAuthMiddleware(t *testing.T) {
// Set up only UI auth
uiHash, _ := bcrypt.GenerateFromPassword([]byte("uipass"), bcrypt.DefaultCost)
auth.SetUIAuth("uiuser:" + string(uiHash))
if err := auth.SetUIAuth("uiuser:" + string(uiHash)); err != nil {
t.Fatalf("Failed to set UI auth: %s", err.Error())
}
r := apiRoutes()
ts := httptest.NewServer(r)
@@ -455,9 +463,14 @@ func TestSendAPIAuthMiddleware(t *testing.T) {
// Set up UI auth and Send API auth
uiHash, _ := bcrypt.GenerateFromPassword([]byte("uipass"), bcrypt.DefaultCost)
auth.SetUIAuth("uiuser:" + string(uiHash))
if err := auth.SetUIAuth("uiuser:" + string(uiHash)); err != nil {
t.Fatalf("Failed to set UI auth: %s", err.Error())
}
sendHash, _ := bcrypt.GenerateFromPassword([]byte("sendpass"), bcrypt.DefaultCost)
auth.SetSendAPIAuth("senduser:" + string(sendHash))
if err := auth.SetSendAPIAuth("senduser:" + string(sendHash)); err != nil {
t.Fatalf("Failed to set Send API auth: %s", err.Error())
}
r := apiRoutes()
ts := httptest.NewServer(r)
@@ -604,7 +617,7 @@ func clientGet(url string) ([]byte, error) {
return nil, fmt.Errorf("%s returned status %d", url, resp.StatusCode)
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
data, err := io.ReadAll(resp.Body)
@@ -625,7 +638,7 @@ func clientDelete(url, body string) ([]byte, error) {
return nil, err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s returned status %d", url, resp.StatusCode)
@@ -650,7 +663,7 @@ func clientPut(url, body string) ([]byte, error) {
return nil, err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s returned status %d", url, resp.StatusCode)
@@ -675,7 +688,7 @@ func clientPost(url, body string) ([]byte, error) {
return nil, err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s returned status %d", url, resp.StatusCode)
@@ -702,7 +715,7 @@ func clientPostWithAuth(url, body, username, password string) ([]byte, error) {
return nil, err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s returned status %d", url, resp.StatusCode)
@@ -728,7 +741,7 @@ func clientGetWithAuth(url, username, password string) ([]byte, error) {
return nil, err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s returned status %d", url, resp.StatusCode)

View File

@@ -22,7 +22,7 @@ var (
)
// Send will post the MessageSummary to a webhook (if configured)
func Send(msg interface{}) {
func Send(msg any) {
if config.WebhookURL == "" {
return
}
@@ -70,7 +70,7 @@ func Send(msg interface{}) {
return
}
defer resp.Body.Close()
_ = resp.Body.Close()
})
}()
}