]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Send unhibernation OK reply to imap-hibernate only after creating client
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 17 Aug 2020 11:48:01 +0000 (14:48 +0300)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Fri, 21 Aug 2020 08:51:13 +0000 (08:51 +0000)
The following commit adds unhibernation event, which would be much more
difficult to implement for this error path without this change.

The OK reply is still sent before client_create_finish(), which is the part
that could be slow.

src/imap/imap-master-client.c

index f23a91bce205dd9e5f8121377e830be109575027..9fe82c5b6896b488cd70bc610866b176993ab1ca 100644 (file)
@@ -227,11 +227,6 @@ imap_master_client_input_args(struct connection *conn, const char *const *args,
                i_close_fd(&fd_client);
                return -1;
        }
-       /* Send a success notification before we start anything that lasts
-          potentially a long time. imap-hibernate process is waiting for us
-          to answer. Even if we fail later, we log the error anyway. */
-       o_stream_nsend_str(conn->output, "+\n");
-       (void)o_stream_flush(conn->output);
 
        /* NOTE: before client_create_from_input() on failures we need to close
           fd_client, but afterward it gets closed by client_destroy() */
@@ -241,6 +236,8 @@ imap_master_client_input_args(struct connection *conn, const char *const *args,
                e_error(conn->event,
                        "imap-master(%s): Failed to create client: %s",
                        input.username, error);
+               o_stream_nsend_str(conn->output, t_strdup_printf(
+                       "-Failed to create client: %s\n", error));
                i_close_fd(&fd_client);
                return -1;
        }
@@ -261,6 +258,12 @@ imap_master_client_input_args(struct connection *conn, const char *const *args,
                        "imap-master: Unhibernated because IDLE was stopped with DONE");
        }
 
+       /* Send a success notification before we start anything that lasts
+          potentially a long time. imap-hibernate process is waiting for us
+          to answer. Even if we fail later, we log the error anyway. */
+       o_stream_nsend_str(conn->output, "+\n");
+       (void)o_stream_flush(conn->output);
+
        if (client_create_finish(imap_client, &error) < 0) {
                e_error(imap_client->event, "imap-master(%s): %s",
                        input.username, error);