thunderbird / thunderbird-android

K-9 Mail – Open Source Email App for Android
https://k9mail.app/
Apache License 2.0
9.47k stars 2.42k forks source link

IMAP: Don't check for existence of a folder before performing an operation #7783

Closed cketti closed 2 weeks ago

cketti commented 2 weeks ago

Checking the existence of a folder before performing an operation is not doing anything useful. When a folder doesn't exist, we want the operation to fail.

Here's partial protocol logs without the changes applied (before) and with the changes applied (after):

connX: IMAP connection number X >>>: commands sent to the server <<<: responses received from the server

Empty trash

Before

conn1>>> 4 STATUS "Trash" (UIDVALIDITY)
conn1<<<#null# [STATUS, Trash, [UIDVALIDITY, 1264001650]]
conn1<<<#4# [OK, STATUS completed]

conn2>>> 5 NOOP
conn2<<<#5# [OK, NOOP completed]
conn2>>> 6 SELECT "Trash"
conn2<<<#null# …
conn2<<<#6# [OK, [READ-WRITE], SELECT completed]
conn2>>> 7 NOOP
conn2<<<#7# [OK, NOOP completed]
conn2>>> 8 UID STORE 1:* +FLAGS.SILENT (\Deleted)
conn2<<<#8# [OK, STORE completed]

After

conn1>>> 5 SELECT "Trash"
conn1<<<#null# …
conn1<<<#5# [OK, [READ-WRITE], SELECT completed]
conn1>>> 6 NOOP
conn1<<<#6# [OK, NOOP completed]
conn1>>> 7 UID STORE 1:* +FLAGS.SILENT (\Deleted)
conn1<<<#7# [OK, STORE completed]

Expunge command

Before

conn1>>> 4 STATUS "Trash" (UIDVALIDITY)
conn1<<<#null# [STATUS, Trash, [UIDVALIDITY, 1264001650]]
conn1<<<#4# [OK, STATUS completed]

conn2>>> 5 NOOP
conn2<<<#5# [OK, NOOP completed]
conn2>>> 6 SELECT "Trash"
conn2<<<#null# …
conn2<<<#6# [OK, [READ-WRITE], SELECT completed]
conn2>>> 7 NOOP
conn2<<<#7# [OK, NOOP completed]
conn2>>> 8 EXPUNGE
conn2<<<#8# [OK, EXPUNGE completed]

After

conn1>>> 5 SELECT "Trash"
conn1<<<#null# …
conn1<<<#5# [OK, [READ-WRITE], SELECT completed]
conn1>>> 6 NOOP
conn1<<<#6# [OK, NOOP completed]
conn1>>> 7 EXPUNGE
conn1<<<#7# [OK, EXPUNGE completed]

Expunge message

Before

conn1>>> 7 STATUS "[Google Mail]/Trash" (UIDVALIDITY)
conn1<<<#null# [STATUS, [Google Mail]/Trash, [UIDVALIDITY, 8]]
conn1<<<#7# [OK, Success]

conn2>>> 11 NOOP
conn2<<<#11# [OK, Success]
conn2>>> 12 SELECT "[Google Mail]/Trash"
conn2<<<#null# …
conn2<<<#12# [OK, [READ-WRITE], [Google Mail]/Trash selected. (Success)]
conn2>>> 13 NOOP
conn2<<<#13# [OK, Success]
conn2>>> 14 UID EXPUNGE 4411
conn2<<<#null# [7, EXPUNGE]
conn2<<<#null# [8, EXISTS]
conn2<<<#14# [OK, Success]

After

conn1>>> 30 SELECT "[Google Mail]/Trash"
conn1<<<#null# …
conn1<<<#30# [OK, [READ-WRITE], [Google Mail]/Trash selected. (Success)]
conn1>>> 31 NOOP
conn1<<<#31# [OK, Success]
conn1>>> 32 UID EXPUNGE 4412
conn1<<<#null# [8, EXPUNGE]
conn1<<<#null# [9, EXISTS]
conn1<<<#32# [OK, Success]

Mark all as read

Before

conn1>>> 4 STATUS "Trash" (UIDVALIDITY)
conn1<<<#null# [STATUS, Trash, [UIDVALIDITY, 1264001650]]
conn1<<<#4# [OK, STATUS completed]

conn2>>> 5 NOOP
conn2<<<#5# [OK, NOOP completed]
conn2>>> 6 SELECT "Trash"
conn2<<<#null# …
conn2<<<#6# [OK, [READ-WRITE], SELECT completed]
conn2>>> 7 NOOP
conn2<<<#7# [OK, NOOP completed]
conn2>>> 8 UID STORE 1:* +FLAGS.SILENT (\Seen)
conn2<<<#8# [OK, STORE completed]

After

conn1>>> 5 SELECT "Trash"
conn1<<<#null# …
conn1<<<#5# [OK, [READ-WRITE], SELECT completed]
conn1>>> 6 NOOP
conn1<<<#6# [OK, NOOP completed]
conn1>>> 7 UID STORE 1:* +FLAGS.SILENT (\Seen)
conn1<<<#7# [OK, No matching messages]

Copy message

Before

conn1>>> 5 STATUS "INBOX" (UIDVALIDITY)
conn1<<<#null# [STATUS, INBOX, [UIDVALIDITY, 1264001496]]
conn1<<<#5# [OK, STATUS completed]
conn1>>> 6 NOOP
conn1<<<#6# [OK, NOOP completed]
conn1>>> 7 SELECT "INBOX"
conn1<<<#null# …
conn1<<<#7# [OK, [READ-WRITE], SELECT completed]
conn1>>> 8 STATUS "[test]" (RECENT)
conn1<<<#null# [STATUS, [test], [RECENT, 7]]
conn1<<<#8# [OK, STATUS completed]
conn1>>> 9 UID COPY 12569 "[test]"
conn1<<<#9# [OK, [COPYUID, 1443304134, 12569, 15], COPY completed]

After

conn1>>> 5 SELECT "INBOX"
conn1<<<#null# …
conn1<<<#5# [OK, [READ-WRITE], SELECT completed]
conn1>>> 6 UID COPY 12569 "[test]"
conn1<<<#6# [OK, [COPYUID, 1443304134, 12569, 16], COPY completed]

Set flag

Before

conn1>>> 4 STATUS "[test]" (UIDVALIDITY)
conn1<<<#null# [STATUS, [test], [UIDVALIDITY, 1443304134]]
conn1<<<#4# [OK, STATUS completed]

conn2>>> 5 NOOP
conn2<<<#5# [OK, NOOP completed]
conn2>>> 6 SELECT "[test]"
conn2<<<#null# …
conn2<<<#6# [OK, [READ-WRITE], SELECT completed]
conn2>>> 7 NOOP
conn2<<<#7# [OK, NOOP completed]
conn2>>> 8 UID STORE 15 -FLAGS.SILENT (\Seen)
conn2<<<#8# [OK, STORE completed]

After

conn1>>> 5 SELECT "[test]"
conn1<<<#null# …
conn1<<<#5# [OK, [READ-WRITE], SELECT completed]
conn1>>> 6 NOOP
conn1<<<#6# [OK, NOOP completed]
conn1>>> 7 UID STORE 16 -FLAGS.SILENT (\Seen)
conn1<<<#7# [OK, STORE completed]

There's still lots of potential to get rid of unnecessary commands (and even connections). But this PR is solely about the folder existence checks.