removed timeout from potentially-long functions
authorPhiTux <redacted>
Sat, 16 Aug 2025 16:37:40 +0000 (18:37 +0200)
committerPhiTux <redacted>
Sat, 16 Aug 2025 16:37:40 +0000 (18:37 +0200)
backend/go.mod
backend/handlers/additional.go
backend/main.go

index 36168cc6738d165476093208bd00a0ea7e832833..b4e967ae7407b8e805bb0b2a3160fa2181789594 100644 (file)
@@ -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
index 9be842fc444016e4a5f7106545ff3dad7e885cbe..5818479a05184012cc9424708db4aabf6b03b65d 100644 (file)
@@ -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")
index 338dd44b3d4306544853e7a54fbaad26e41b221a..e430cdead3ef2b5867082370fb9f9fa6fafdbdb2 100644 (file)
@@ -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
git clone https://git.99rst.org/PROJECT