int ret;
for (;;) {
- /* check whether we can send anything */
- cmd = conn->cmd_send_queue_head;
- if (cmd == NULL)
- return 0;
- if (!smtp_client_command_pipeline_is_open(conn))
- return 0;
+ if (conn->cmd_streaming != NULL) {
+ cmd = conn->cmd_streaming;
+ i_assert(cmd->stream != NULL);
+ } else {
+ /* check whether we can send anything */
+ cmd = conn->cmd_send_queue_head;
+ if (cmd == NULL)
+ return 0;
+ if (!smtp_client_command_pipeline_is_open(conn))
+ return 0;
- cmd->state = SMTP_CLIENT_COMMAND_STATE_SENDING;
- conn->sending_command = TRUE;
+ cmd->state = SMTP_CLIENT_COMMAND_STATE_SENDING;
+ conn->sending_command = TRUE;
- if ((ret=smtp_client_command_send_line(cmd)) <= 0)
- return ret;
+ if ((ret=smtp_client_command_send_line(cmd)) <= 0)
+ return ret;
+
+ /* command line sent. move command to wait list. */
+ smtp_cient_command_wait(cmd);
+ cmd->state = SMTP_CLIENT_COMMAND_STATE_WAITING;
+ }
if (cmd->stream != NULL &&
(ret=smtp_client_command_send_stream(cmd)) <= 0) {
return -1;
smtp_client_command_debug(cmd,
"Blocked while sending payload");
+ conn->cmd_streaming = cmd;
return 0;
}
- /* everything sent. move command to wait list. */
- smtp_cient_command_wait(cmd);
- cmd->state = SMTP_CLIENT_COMMAND_STATE_WAITING;
-
+ conn->cmd_streaming = NULL;
conn->sending_command = FALSE;
smtp_client_command_sent(cmd);
}
return 1;
}
+ if (reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECTION_CLOSED) {
+ smtp_client_connection_fail_reply(conn, reply);
+ return -1;
+ }
+
/* unexpected reply? */
if (conn->cmd_wait_list_head == NULL) {
smtp_client_connection_debug(conn,
"Unexpected reply: %s", smtp_reply_log(reply));
+ smtp_client_connection_fail(conn,
+ SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
+ "Got unexpected reply");
+ return -1;
+ }
- if (reply->status ==
- SMTP_CLIENT_COMMAND_ERROR_CONNECTION_CLOSED) {
- smtp_client_connection_fail_reply(conn, reply);
- } else {
+ /* replied early? */
+ if (conn->cmd_wait_list_head == conn->cmd_streaming &&
+ !conn->cmd_wait_list_head->stream_finished) {
+ smtp_client_connection_debug(conn,
+ "Early reply: %s", smtp_reply_log(reply));
+ if (smtp_reply_is_success(reply)) {
smtp_client_connection_fail(conn,
SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
- "Got unexpected reply");
+ "Got early success reply");
+ return -1;
}
- return -1;
}
/* command reply */
SMTP_CLIENT_COMMAND_ERROR_ABORTED,
"Disconnected from server");
}
+ conn->cmd_streaming = NULL;
}
static struct smtp_client_connection *
/* commands pending in queue to be sent */
struct smtp_client_command *cmd_send_queue_head, *cmd_send_queue_tail;
unsigned int cmd_send_queue_count;
- /* commands that have been sent, waiting for response */
+ /* commands that have been (mostly) sent, waiting for response */
struct smtp_client_command *cmd_wait_list_head, *cmd_wait_list_tail;
unsigned int cmd_wait_list_count;
+ /* command sending data stream */
+ struct smtp_client_command *cmd_streaming;
/* active transactions */
struct smtp_client_transaction *transactions_head, *transactions_tail;