From 94e9036e87c88d179bad3f6aa754e3308c1c2b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Sat, 31 Jan 2026 18:44:52 +0100 Subject: [PATCH] Increase avatar download timeout and retries; add verification for uploaded avatars with fallback caching --- go_cloud/internal/config/config.go | 4 +-- go_cloud/internal/http/routes.go | 45 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/go_cloud/internal/config/config.go b/go_cloud/internal/config/config.go index d305d40..70061e1 100644 --- a/go_cloud/internal/config/config.go +++ b/go_cloud/internal/config/config.go @@ -39,8 +39,8 @@ func Load() *Config { NextcloudBase: getEnv("NEXTCLOUD_BASEPATH", "/"), AllowedOrigins: getEnv("ALLOWED_ORIGINS", "https://b0esche.cloud,https://www.b0esche.cloud,https://*.b0esche.cloud,http://localhost:8080"), AvatarCacheDir: getEnv("AVATAR_CACHE_DIR", "/var/cache/b0esche/avatars"), - AvatarDownloadTimeoutSeconds: getEnvInt("AVATAR_DOWNLOAD_TIMEOUT_SECONDS", 10), - AvatarDownloadRetries: getEnvInt("AVATAR_DOWNLOAD_RETRIES", 2), + AvatarDownloadTimeoutSeconds: getEnvInt("AVATAR_DOWNLOAD_TIMEOUT_SECONDS", 20), + AvatarDownloadRetries: getEnvInt("AVATAR_DOWNLOAD_RETRIES", 3), } log.Printf("[CONFIG] Nextcloud URL: %q, User: %q, BasePath: %q, AvatarCacheDir: %q, AvatarDownloadTimeoutSeconds: %d, AvatarDownloadRetries: %d\n", cfg.NextcloudURL, cfg.NextcloudUser, cfg.NextcloudBase, cfg.AvatarCacheDir, cfg.AvatarDownloadTimeoutSeconds, cfg.AvatarDownloadRetries) return cfg diff --git a/go_cloud/internal/http/routes.go b/go_cloud/internal/http/routes.go index f8670b9..073352b 100644 --- a/go_cloud/internal/http/routes.go +++ b/go_cloud/internal/http/routes.go @@ -4216,6 +4216,29 @@ func uploadUserAvatarHandler(w http.ResponseWriter, r *http.Request, db *databas return } + // Verify uploaded avatar is available on WebDAV (best-effort, retry) + verified := false + verifyRetries := 3 + verifyTimeout := 5 // seconds + for i := 0; i < verifyRetries; i++ { + vctx, vcancel := context.WithTimeout(r.Context(), time.Duration(verifyTimeout)*time.Second) + resp, derr := client.Download(vctx, avatarPath, "") + vcancel() + if derr == nil && resp != nil { + resp.Body.Close() + verified = true + break + } + fmt.Printf("[WARN] avatar verification attempt %d/%d failed for %s: %v\n", i+1, verifyRetries, avatarPath, derr) + time.Sleep(time.Duration(300*(1<