Rex Dieter 8b4426d
From abe71f46c3b2e657db25ac16c43a4c76b2212a9f Mon Sep 17 00:00:00 2001
Rex Dieter 8b4426d
From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com>
Rex Dieter 8b4426d
Date: Wed, 17 Jun 2015 13:04:13 +0200
Rex Dieter 8b4426d
Subject: [PATCH 32/34] Don't throw exception when MOVE handler finds no items
Rex Dieter 8b4426d
 to move
Rex Dieter 8b4426d
Rex Dieter 8b4426d
Instead return "OK MOVE complete" right away. The reason for this is that
Rex Dieter 8b4426d
when client tries to move an Item from a folder into the same folder (it's
Rex Dieter 8b4426d
possible in KMail, also mailfilter agent might trigger this situation) the
Rex Dieter 8b4426d
subsequent command gets eaten by ImapStreamParser and the client's Job gets
Rex Dieter 8b4426d
stuck waiting for response forever. According to Laurent this could also fix
Rex Dieter 8b4426d
the Mail Filter Agent getting stuck occasionally.
Rex Dieter 8b4426d
Rex Dieter 8b4426d
The problem is in ImapStreamParser::atCommandEnd() method, which is called
Rex Dieter 8b4426d
by the Move handler at some point. atCommandEnd() checks whether we reached
Rex Dieter 8b4426d
command end in the stream by looking if the next characters in the stream
Rex Dieter 8b4426d
are "\r\n" and if so it will consume the command end ("\r\n"), effectively
Rex Dieter 8b4426d
moving the streaming position BEYOND the command. In case of MOVE the
Rex Dieter 8b4426d
command has already been completely parsed so we are actually at the end of
Rex Dieter 8b4426d
the command and so ImapStreamParser will consume the "\r\n" and position the
Rex Dieter 8b4426d
stream beyond the command end.
Rex Dieter 8b4426d
Rex Dieter 8b4426d
After that the Move handler tries to get the items from DB and throws the
Rex Dieter 8b4426d
exception (the second part of the condition in the SQL query causes that
Rex Dieter 8b4426d
the query yields no results in this situation)  which gets us back to
Rex Dieter 8b4426d
Connection where we then call ImapStreamParser::skipCommand(). At this point
Rex Dieter 8b4426d
however there are no more data in the stream (because atCommandEnd() moved
Rex Dieter 8b4426d
us beyond the end of the MOVE command) and so ImapStreamParser will block
Rex Dieter 8b4426d
and wait for more data (with 30 seconds timeout). If client sends another
Rex Dieter 8b4426d
command within this time the ImapStreamParser will think that this is the
Rex Dieter 8b4426d
command to be skipped and will consume it. This means that the command never
Rex Dieter 8b4426d
really reaches the Connection as it's consumed as soon as it's captured by
Rex Dieter 8b4426d
ImapStreamParser. And because Akonadi never receives the command it cannot
Rex Dieter 8b4426d
send a response and thus the Job in client will wait forever and ever...
Rex Dieter 8b4426d
Rex Dieter 8b4426d
Proper fix would be to make ImapStreamParser::atCommandEnd() to only peek
Rex Dieter 8b4426d
instead of actually altering the position in the stream however I'm really
Rex Dieter 8b4426d
afraid that it could break some other stuff that relies on this (broken?)
Rex Dieter 8b4426d
behaviour and our test coverage is not sufficient at this point to be
Rex Dieter 8b4426d
reliable enough.
Rex Dieter 8b4426d
---
Rex Dieter 8b4426d
 server/src/handler/move.cpp | 2 +-
Rex Dieter 8b4426d
 1 file changed, 1 insertion(+), 1 deletion(-)
Rex Dieter 8b4426d
Rex Dieter 8b4426d
diff --git a/server/src/handler/move.cpp b/server/src/handler/move.cpp
Rex Dieter 8b4426d
index 0a6c3bf..4cf9d4e 100644
Rex Dieter 8b4426d
--- a/server/src/handler/move.cpp
Rex Dieter 8b4426d
+++ b/server/src/handler/move.cpp
Rex Dieter 8b4426d
@@ -85,7 +85,7 @@ bool Move::parseStream()
Rex Dieter 8b4426d
   if ( qb.exec() ) {
Rex Dieter 8b4426d
     const QVector<PimItem> items = qb.result();
Rex Dieter 8b4426d
     if ( items.isEmpty() ) {
Rex Dieter 8b4426d
-      throw HandlerException( "No items found" );
Rex Dieter 8b4426d
+      return successResponse( "MOVE complete" );
Rex Dieter 8b4426d
     }
Rex Dieter 8b4426d
 
Rex Dieter 8b4426d
     // Split the list by source collection
Rex Dieter 8b4426d
-- 
Rex Dieter 8b4426d
2.4.3
Rex Dieter 8b4426d