changeset 22220:b4c9f96470ca

pop3: initialize namespaces explicitly (instead of relying on mail user initialization to instantiate them for us)
author Josef 'Jeff' Sipek <jeff.sipek@dovecot.fi>
date Tue, 23 May 2017 13:01:48 +0300
parents bb35e45650fe
children a4f2e85c9cc8
files src/pop3/main.c src/pop3/pop3-client.c
diffstat 2 files changed, 36 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/pop3/main.c	Fri May 19 10:58:18 2017 +0300
+++ b/src/pop3/main.c	Tue May 23 13:01:48 2017 +0300
@@ -16,6 +16,7 @@
 #include "var-expand.h"
 #include "mail-error.h"
 #include "mail-user.h"
+#include "mail-namespace.h"
 #include "mail-storage-service.h"
 
 #include <stdio.h>
@@ -126,6 +127,8 @@
 {
 	int ret;
 
+	i_assert(client->user->namespaces != NULL);
+
 	if (client->set->pop3_lock_session &&
 	    (ret = pop3_lock_session(client)) <= 0) {
 		client_send_line(client, ret < 0 ?
@@ -138,11 +141,36 @@
 	return 0;
 }
 
+#define MSG_BYE_INTERNAL_ERROR "-ERR "MAIL_ERRSTR_CRITICAL_MSG
+static int init_namespaces(struct client *client, bool already_logged_in)
+{
+	const char *error;
+
+	/* finish initializing the user (see comment in main()) */
+	if (mail_namespaces_init(client->user, &error) < 0) {
+		if (!already_logged_in)
+			client_send_line(client, MSG_BYE_INTERNAL_ERROR);
+
+		i_error("%s", error);
+		client_destroy(client, error);
+		return -1;
+	}
+
+	i_assert(client->inbox_ns == NULL);
+	client->inbox_ns = mail_namespace_find_inbox(client->user->namespaces);
+	i_assert(client->inbox_ns != NULL);
+
+	return 0;
+}
+
 static void add_input(struct client *client,
 		      const buffer_t *input_buf)
 {
 	const char *error;
 
+	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 */
 
@@ -271,6 +299,14 @@
 			MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT;
 	}
 
+	/*
+	 * We include MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES so that the
+	 * mail_user initialization is fast and we can quickly send back the
+	 * OK response to LOGIN/AUTHENTICATE.  Otherwise we risk a very slow
+	 * namespace initialization to cause client timeouts on login.
+	 */
+	storage_service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES;
+
 	master_service = master_service_init("pop3", service_flags,
 					     &argc, &argv, "a:t:u:");
 	while ((c = master_getopt(master_service)) > 0) {
--- a/src/pop3/pop3-client.c	Fri May 19 10:58:18 2017 +0300
+++ b/src/pop3/pop3-client.c	Tue May 23 13:01:48 2017 +0300
@@ -434,9 +434,6 @@
 	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);