]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: client: Fix handling of non-blocking command payload stream.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sun, 11 Nov 2018 22:25:50 +0000 (23:25 +0100)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Thu, 21 Mar 2019 08:02:41 +0000 (10:02 +0200)
By inference, this fixes the handling of non-blocking transaction payload as
well. No io was created when the payload stream returned no data.

src/lib-smtp/smtp-client-command.c
src/lib-smtp/smtp-client-connection.c
src/lib-smtp/smtp-client-private.h

index 6cbed574451b22fef5ece496e1c51d332c42c298..df17040f84f9bc67c2d354cda04e45ab2d244ad1 100644 (file)
@@ -448,6 +448,15 @@ smtp_client_command_finish_dot_stream(struct smtp_client_command *cmd)
        return 1;
 }
 
+static void smtp_client_command_payload_input(struct smtp_client_command *cmd)
+{
+       struct smtp_client_connection *conn = cmd->conn;
+
+       io_remove(&conn->io_cmd_payload);
+
+       smtp_client_connection_trigger_output(conn);
+}
+
 static int
 smtp_client_command_send_stream(struct smtp_client_command *cmd)
 {
@@ -457,6 +466,8 @@ smtp_client_command_send_stream(struct smtp_client_command *cmd)
        enum ostream_send_istream_result res;
        int ret;
 
+       io_remove(&conn->io_cmd_payload);
+
        if (cmd->stream_finished) {
                if ((ret=smtp_client_command_finish_dot_stream(cmd)) <= 0)
                        return ret;
@@ -493,7 +504,12 @@ smtp_client_command_send_stream(struct smtp_client_command *cmd)
                i_stream_unref(&cmd->stream);
                return 1;
        case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT:
+               /* input is blocking (client needs to act; disable timeout) */
+               conn->io_cmd_payload = io_add_istream(
+                       stream, smtp_client_command_payload_input, cmd);
+               return 0;
        case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
+               smtp_client_command_debug(cmd, "Partially sent payload");
                i_assert(cmd->stream_size == 0 ||
                        stream->v_offset < cmd->stream_size);
                return 0;
index 83dfdc4d1c9c949d918f8fdbf42eddcea91befef..dd40de8fbddbde5c2c0a768d048de2d649d9176c 100644 (file)
@@ -1802,6 +1802,7 @@ void smtp_client_connection_disconnect(struct smtp_client_connection *conn)
 
        if (conn->dns_lookup != NULL)
                dns_lookup_abort(&conn->dns_lookup);
+       io_remove(&conn->io_cmd_payload);
        timeout_remove(&conn->to_connect);
        timeout_remove(&conn->to_trans);
        timeout_remove(&conn->to_commands);
@@ -2065,6 +2066,8 @@ void smtp_client_connection_switch_ioloop(struct smtp_client_connection *conn)
 {
        struct smtp_client_transaction *trans;
 
+       if (conn->io_cmd_payload != NULL)
+               conn->io_cmd_payload = io_loop_move_io(&conn->io_cmd_payload);
        if (conn->to_connect != NULL)
                conn->to_connect = io_loop_move_timeout(&conn->to_connect);
        if (conn->to_trans != NULL)
index 7ef852b22a16a77e7f69e7e0e222c17d3444c50c..3da54d9c37e98cf9c6c43d1ffb75dc1dab64f4cc 100644 (file)
@@ -171,6 +171,7 @@ struct smtp_client_connection {
        struct dns_lookup *dns_lookup;
        struct dsasl_client *sasl_client;
        struct timeout *to_connect, *to_trans, *to_commands;
+       struct io *io_cmd_payload;
 
        struct istream *raw_input;
        struct ostream *raw_output, *dot_output;