changeset 22221:a4f2e85c9cc8

pop3: send back auth reply sooner If possible (i.e., pop3_lock_session=no), we can send back the OK response earlier.
author Josef 'Jeff' Sipek <jeff.sipek@dovecot.fi>
date Tue, 23 May 2017 14:12:49 +0300
parents b4c9f96470ca
children 03534f251ebb
files src/pop3/main.c
diffstat 1 files changed, 31 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/pop3/main.c	Tue May 23 13:01:48 2017 +0300
+++ b/src/pop3/main.c	Tue May 23 14:12:49 2017 +0300
@@ -128,9 +128,9 @@
 	int ret;
 
 	i_assert(client->user->namespaces != NULL);
+	i_assert(client->set->pop3_lock_session);
 
-	if (client->set->pop3_lock_session &&
-	    (ret = pop3_lock_session(client)) <= 0) {
+	if ((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.");
@@ -168,14 +168,37 @@
 {
 	const char *error;
 
-	if (init_namespaces(client, FALSE) < 0)
-		return; /* no need to propagate an error */
+	/*
+	 * RFC 1939 requires that the session lock gets acquired before the
+	 * positive response is sent to the client indicating a transition
+	 * to the TRANSACTION state.
+	 *
+	 * Since the session lock is stored under the INBOX's storage
+	 * directory, the locking code requires that the namespaces are
+	 * initialized first.
+	 *
+	 * If the system administrator configured dovecot to not use session
+	 * locks, we can send back the positive response before the
+	 * potentially long-running namespace initialization occurs.  This
+	 * avoids the client possibly timing out during authentication due
+	 * to storage initialization taking too long.
+	 */
+	if (client->set->pop3_lock_session) {
+		if (init_namespaces(client, FALSE) < 0)
+			return; /* no need to propagate an error */
 
-	if (lock_session(client) < 0)
-		return; /* no need to propagate an error */
+		if (lock_session(client) < 0)
+			return; /* no need to propagate an error */
 
-	if (!IS_STANDALONE())
-		client_send_line(client, "+OK Logged in.");
+		if (!IS_STANDALONE())
+			client_send_line(client, "+OK Logged in.");
+	} else {
+		if (!IS_STANDALONE())
+			client_send_line(client, "+OK Logged in.");
+
+		if (init_namespaces(client, TRUE) < 0)
+			return; /* no need to propagate an error */
+	}
 
 	if (client_init_mailbox(client, &error) < 0) {
 		i_error("%s", error);