From: PhiTux Date: Sat, 16 Aug 2025 16:37:40 +0000 (+0200) Subject: removed timeout from potentially-long functions X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=02b9ef8b5c996074cf3ddc0f9bd28ce23e624b53;p=DailyTxT.git removed timeout from potentially-long functions --- diff --git a/backend/go.mod b/backend/go.mod index 36168cc..b4e967a 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -4,11 +4,9 @@ go 1.24 require ( github.com/golang-jwt/jwt/v5 v5.2.0 + github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a github.com/google/uuid v1.6.0 golang.org/x/crypto v0.19.0 ) -require ( - github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a // indirect - golang.org/x/sys v0.17.0 // indirect -) +require golang.org/x/sys v0.17.0 // indirect diff --git a/backend/handlers/additional.go b/backend/handlers/additional.go index 9be842f..5818479 100644 --- a/backend/handlers/additional.go +++ b/backend/handlers/additional.go @@ -514,19 +514,21 @@ func UploadFile(w http.ResponseWriter, r *http.Request) { } defer file.Close() - // Read file - fileBytes, err := io.ReadAll(file) + // Get encryption key first (before reading large file) + encKey, err := utils.GetEncryptionKey(userID, derivedKey) if err != nil { - http.Error(w, fmt.Sprintf("Error reading file: %v", err), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("Error getting encryption key: %v", err), http.StatusInternalServerError) return } - // Get encryption key - encKey, err := utils.GetEncryptionKey(userID, derivedKey) + // Read file into a buffer (more memory efficient) + fileBytes, err := io.ReadAll(file) if err != nil { - http.Error(w, fmt.Sprintf("Error getting encryption key: %v", err), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("Error reading file: %v", err), http.StatusInternalServerError) return } + // Ensure fileBytes is cleared when function exits + defer func() { fileBytes = nil }() // Encrypt file encryptedFile, err := utils.EncryptFile(fileBytes, encKey) @@ -534,6 +536,11 @@ func UploadFile(w http.ResponseWriter, r *http.Request) { http.Error(w, fmt.Sprintf("Error encrypting file: %v", err), http.StatusInternalServerError) return } + // Ensure encryptedFile is cleared when function exits + defer func() { encryptedFile = nil }() + + // Clear original file data from memory immediately after encryption + fileBytes = nil // Write file if err := utils.WriteFile(encryptedFile, userID, uuid); err != nil { @@ -541,6 +548,9 @@ func UploadFile(w http.ResponseWriter, r *http.Request) { return } + // Clear encrypted data from memory immediately after writing + encryptedFile = nil + // Get month data content, err := utils.GetMonth(userID, year, month) if err != nil { @@ -651,6 +661,8 @@ func DownloadFile(w http.ResponseWriter, r *http.Request) { http.Error(w, fmt.Sprintf("Error reading file: %v", err), http.StatusInternalServerError) return } + // Ensure encryptedFile is cleared when function exits + defer func() { encryptedFile = nil }() // Decrypt file decryptedFile, err := utils.DecryptFile(encryptedFile, encKey) @@ -658,6 +670,11 @@ func DownloadFile(w http.ResponseWriter, r *http.Request) { http.Error(w, fmt.Sprintf("Error decrypting file: %v", err), http.StatusInternalServerError) return } + // Ensure decryptedFile is cleared when function exits + defer func() { decryptedFile = nil }() + + // Clear encrypted data from memory immediately after decryption + encryptedFile = nil // Set response headers for streaming w.Header().Set("Content-Type", "application/octet-stream") diff --git a/backend/main.go b/backend/main.go index 338dd44..e430cde 100644 --- a/backend/main.go +++ b/backend/main.go @@ -14,6 +14,29 @@ import ( "github.com/phitux/dailytxt/backend/utils" ) +// longTimeoutEndpoints defines endpoints that need extended timeouts +var longTimeoutEndpoints = map[string]bool{ + "/logs/uploadFile": true, + "/logs/downloadFile": true, + "/logs/exportData": true, + "/users/login": true, +} + +// timeoutMiddleware applies different timeouts based on the endpoint +func timeoutMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Check if this endpoint needs a long timeout + if longTimeoutEndpoints[r.URL.Path] { + // No timeout for these endpoints - let them run as long as needed + next.ServeHTTP(w, r) + } else { + // Apply 15 second timeout for normal endpoints + handler := http.TimeoutHandler(next, 15*time.Second, "Request timeout") + handler.ServeHTTP(w, r) + } + }) +} + func main() { // Setup logging logger := log.New(os.Stdout, "dailytxt: ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile) @@ -66,17 +89,15 @@ func main() { mux.HandleFunc("GET /logs/deleteDay", middleware.RequireAuth(handlers.DeleteDay)) mux.HandleFunc("GET /logs/exportData", middleware.RequireAuth(handlers.ExportData)) - // Create a handler chain with Logger and CORS middleware - // Logger middleware will be executed first, then CORS - handler := middleware.Logger(middleware.CORS(mux)) + // Create a handler chain with Timeout, Logger and CORS middleware + // Timeout middleware will be executed first, then Logger, then CORS + handler := timeoutMiddleware(middleware.Logger(middleware.CORS(mux))) - // Create the server + // Create the server without ReadTimeout/WriteTimeout (managed by middleware) server := &http.Server{ - Addr: ":8000", - Handler: handler, - ReadTimeout: 15 * time.Second, - WriteTimeout: 15 * time.Second, - IdleTimeout: 60 * time.Second, + Addr: ":8000", + Handler: handler, + IdleTimeout: 60 * time.Second, // Keep IdleTimeout for cleanup } // Start the server in a goroutine