dovecot-2.2: pop3: Send "OK Logged in" before reading mailbox.

dovecot at dovecot.org dovecot at dovecot.org
Wed Nov 18 11:12:49 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/5528fd720619
changeset: 19389:5528fd720619
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Nov 18 13:08:57 2015 +0200
description:
pop3: Send "OK Logged in" before reading mailbox.
This way if the reading takes a long time, the client still sees that the
login itself was successful. This is especially useful to avoid unnecessary
errors logged by proxies.

diffstat:

 src/pop3/main.c        |  13 +++++-
 src/pop3/pop3-client.c |  90 +++++++++++++++++++++++++------------------------
 src/pop3/pop3-client.h |   1 +
 3 files changed, 57 insertions(+), 47 deletions(-)

diffs (172 lines):

diff -r 3d209e0982bf -r 5528fd720619 src/pop3/main.c
--- a/src/pop3/main.c	Wed Nov 18 12:40:42 2015 +0200
+++ b/src/pop3/main.c	Wed Nov 18 13:08:57 2015 +0200
@@ -85,8 +85,6 @@
 	output = client->output;
 	o_stream_ref(output);
 	o_stream_cork(output);
-	if (!IS_STANDALONE())
-		client_send_line(client, "+OK Logged in.");
 	(void)client_handle_input(client);
 	o_stream_uncork(output);
 	o_stream_unref(&output);
@@ -103,6 +101,7 @@
 	struct mail_user *mail_user;
 	struct client *client;
 	const struct pop3_settings *set;
+	const char *error;
 
 	if (mail_storage_service_lookup_next(storage_service, input,
 					     &user, &mail_user, error_r) <= 0) {
@@ -118,8 +117,16 @@
 		verbose_proctitle = TRUE;
 
 	if (client_create(fd_in, fd_out, input->session_id,
-			  mail_user, user, set, &client) == 0)
+			  mail_user, user, set, &client) < 0)
+		return 0;
+	if (!IS_STANDALONE())
+		client_send_line(client, "+OK Logged in.");
+	if (client_init_mailbox(client, &error) == 0)
 		client_add_input(client, input_buf);
+	else {
+		i_error("%s", error);
+		client_destroy(client, error);
+	}
 	return 0;
 }
 
diff -r 3d209e0982bf -r 5528fd720619 src/pop3/pop3-client.c
--- a/src/pop3/pop3-client.c	Wed Nov 18 12:40:42 2015 +0200
+++ b/src/pop3/pop3-client.c	Wed Nov 18 13:08:57 2015 +0200
@@ -369,11 +369,7 @@
 		  struct mail_storage_service_user *service_user,
 		  const struct pop3_settings *set, struct client **client_r)
 {
-	struct mail_storage *storage;
-	const char *ident;
 	struct client *client;
-        enum mailbox_flags flags;
-	const char *errmsg;
 	pool_t pool;
 	int ret;
 
@@ -405,41 +401,7 @@
 
 	client->user = user;
 
-	pop3_client_count++;
-	DLLIST_PREPEND(&pop3_clients, client);
-
-	client->inbox_ns = mail_namespace_find_inbox(user->namespaces);
-	i_assert(client->inbox_ns != NULL);
-
-	if (set->pop3_lock_session && (ret = pop3_lock_session(client)) <= 0) {
-		client_send_line(client, ret < 0 ?
-			"-ERR [SYS/TEMP] Failed to create POP3 session lock." :
-			"-ERR [IN-USE] Mailbox is locked by another POP3 session.");
-		client_destroy(client, "Couldn't lock POP3 session");
-		return -1;
-	}
-
-	flags = MAILBOX_FLAG_POP3_SESSION;
-	if (!set->pop3_no_flag_updates)
-		flags |= MAILBOX_FLAG_DROP_RECENT;
-	client->mailbox = mailbox_alloc(client->inbox_ns->list, "INBOX", flags);
-	storage = mailbox_get_storage(client->mailbox);
-	if (mailbox_open(client->mailbox) < 0) {
-		i_error("Couldn't open INBOX: %s",
-			mailbox_get_last_error(client->mailbox, NULL));
-		client_send_storage_error(client);
-		client_destroy(client, "Couldn't open INBOX");
-		return -1;
-	}
-	client->mail_set = mail_storage_get_settings(storage);
-
-	if (init_pop3_deleted_flag(client, &errmsg) < 0 ||
-	    init_mailbox(client, &errmsg) < 0) {
-		i_error("Couldn't init INBOX: %s", errmsg);
-		client_destroy(client, "Mailbox init failed");
-		return -1;
-	}
-
+	client->mail_set = mail_user_set_get_storage_set(user);
 	client->uidl_keymask =
 		parse_uidl_keymask(client->mail_set->pop3_uidl_format);
 	if (client->uidl_keymask == 0)
@@ -454,7 +416,51 @@
 		client->message_uidls_save = TRUE;
 	}
 
-	if (!set->pop3_no_flag_updates && client->messages_count > 0)
+	pop3_client_count++;
+	DLLIST_PREPEND(&pop3_clients, client);
+
+	client->inbox_ns = mail_namespace_find_inbox(user->namespaces);
+	i_assert(client->inbox_ns != NULL);
+
+	if (hook_client_created != NULL)
+		hook_client_created(&client);
+
+	if (set->pop3_lock_session && (ret = pop3_lock_session(client)) <= 0) {
+		client_send_line(client, ret < 0 ?
+			"-ERR [SYS/TEMP] Failed to create POP3 session lock." :
+			"-ERR [IN-USE] Mailbox is locked by another POP3 session.");
+		client_destroy(client, "Couldn't lock POP3 session");
+		return -1;
+	}
+
+	*client_r = client;
+	return 0;
+
+}
+
+int client_init_mailbox(struct client *client, const char **error_r)
+{
+        enum mailbox_flags flags;
+	const char *ident, *errmsg;
+
+	flags = MAILBOX_FLAG_POP3_SESSION;
+	if (!client->set->pop3_no_flag_updates)
+		flags |= MAILBOX_FLAG_DROP_RECENT;
+	client->mailbox = mailbox_alloc(client->inbox_ns->list, "INBOX", flags);
+	if (mailbox_open(client->mailbox) < 0) {
+		*error_r = t_strdup_printf("Couldn't open INBOX: %s",
+			mailbox_get_last_error(client->mailbox, NULL));
+		client_send_storage_error(client);
+		return -1;
+	}
+
+	if (init_pop3_deleted_flag(client, &errmsg) < 0 ||
+	    init_mailbox(client, &errmsg) < 0) {
+		*error_r = t_strdup_printf("Couldn't init INBOX: %s", errmsg);
+		return -1;
+	}
+
+	if (!client->set->pop3_no_flag_updates && client->messages_count > 0)
 		client->seen_bitmask = i_malloc(MSGS_BITMASK_SIZE(client));
 
 	ident = mail_user_get_anvil_userip_ident(client->user);
@@ -464,11 +470,7 @@
 		client->anvil_sent = TRUE;
 	}
 
-	if (hook_client_created != NULL)
-		hook_client_created(&client);
-
 	pop3_refresh_proctitle();
-	*client_r = client;
 	return 0;
 }
 
diff -r 3d209e0982bf -r 5528fd720619 src/pop3/pop3-client.h
--- a/src/pop3/pop3-client.h	Wed Nov 18 12:40:42 2015 +0200
+++ b/src/pop3/pop3-client.h	Wed Nov 18 13:08:57 2015 +0200
@@ -123,6 +123,7 @@
 		  struct mail_user *user,
 		  struct mail_storage_service_user *service_user,
 		  const struct pop3_settings *set, struct client **client_r);
+int client_init_mailbox(struct client *client, const char **error_r);
 void client_destroy(struct client *client, const char *reason) ATTR_NULL(2);
 
 /* Disconnect client connection */


More information about the dovecot-cvs mailing list