[geary/mjog/bad-literal-timeouts: 3/3] Geary.Imap.ClientConnection: Fix command timeout mid-literal




commit f7e5a4d71cbd04788adf48bd3d09084eeaba7abe
Author: Michael Gratton <mike vee net>
Date:   Sun Feb 28 20:06:34 2021 +1100

    Geary.Imap.ClientConnection: Fix command timeout mid-literal
    
    On slow connections and/or for large literal data blocks, commands can
    time out while still reading literal data.
    
    Ensure that command timeouts are updated whenever we also notify
    higher level components of data being received.

 src/engine/imap/command/imap-command.vala             | 13 +++++++++++++
 src/engine/imap/transport/imap-client-connection.vala |  5 +++++
 2 files changed, 18 insertions(+)
---
diff --git a/src/engine/imap/command/imap-command.vala b/src/engine/imap/command/imap-command.vala
index caa40e511..25a3cb292 100644
--- a/src/engine/imap/command/imap-command.vala
+++ b/src/engine/imap/command/imap-command.vala
@@ -307,6 +307,19 @@ public abstract class Geary.Imap.Command : BaseObject {
             : "%s %s %s".printf(this.tag.to_string(), this.name, args);
     }
 
+    /**
+     * Updates the commands response timer, if running.
+     *
+     * This will reset the command's response timer, preventing the
+     * command from timing out for another {@link response_timeout}
+     * seconds.
+     */
+    internal virtual void update_response_timer() {
+        if (this.response_timer.is_running) {
+            this.response_timer.start();
+        }
+    }
+
     /**
      * Called when a tagged status response is received for this command.
      *
diff --git a/src/engine/imap/transport/imap-client-connection.vala 
b/src/engine/imap/transport/imap-client-connection.vala
index 25156ec3a..97ec7e16e 100644
--- a/src/engine/imap/transport/imap-client-connection.vala
+++ b/src/engine/imap/transport/imap-client-connection.vala
@@ -566,6 +566,11 @@ public class Geary.Imap.ClientConnection : BaseObject, Logging.Source {
         this.bytes_accumulator += bytes;
         var now = GLib.get_real_time();
         if (this.last_seen + 1000000 <= now) {
+            // Touch any sent commands so they don't time out while
+            // downloading large literal blocks.
+            foreach (var command in this.sent_queue) {
+                command.update_response_timer();
+            }
             received_bytes(this.bytes_accumulator);
             this.bytes_accumulator = 0;
             this.last_seen = now;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]