Geary.Imap: Update IMAP quirks based on server greeting rather type

Use server greeting to update IMAP quirks, so that if e.g. a GMail
account is configured as a generic account, it still gets the right
quirks.
This commit is contained in:
Michael Gratton 2020-08-18 15:12:26 +10:00 committed by Michael James Gratton
parent 15a87be780
commit ebf7a8ad1d
5 changed files with 52 additions and 43 deletions

View file

@ -284,10 +284,7 @@ public class Geary.Engine : BaseObject {
(security, cx) => account.untrusted_host(service, security, cx)
);
var client = new Imap.ClientSession(
endpoint,
Imap.ClientService.new_quirks_for_provider(account.service_provider)
);
var client = new Imap.ClientSession(endpoint, new Imap.Quirks());
GLib.Error? imap_err = null;
try {
yield client.connect_async(

View file

@ -39,36 +39,6 @@ public class Geary.Imap.ClientService : Geary.ClientService {
private const int CHECK_NOOP_THRESHOLD_SEC = 5;
public static Quirks new_quirks_for_provider(ServiceProvider provider) {
var quirks = new Quirks();
switch (provider) {
case GMAIL:
// As of 2020-05-02, GMail doesn't seem to quote flag
// atoms containing reserved characters, and at least one
// use of both `]` and ` ` have been found. This works
// around the former. See #746
quirks.flag_atom_exceptions = "]";
break;
case ServiceProvider.OUTLOOK:
// As of June 2016, outlook.com's IMAP servers have a bug
// where a large number (~50) of pipelined STATUS commands
// on mailboxes with many messages will eventually cause
// it to break command parsing and return a BAD response,
// causing us to drop the connection. Limit the number of
// pipelined commands per batch to work around this. See
// b.g.o Bug 766552
quirks.max_pipeline_batch_size = 25;
break;
default:
// noop
break;
}
return quirks;
}
/**
* Set to zero or negative value if keepalives should be disabled when a connection has not
* selected a mailbox. (This is not recommended.)
@ -131,7 +101,7 @@ public class Geary.Imap.ClientService : Geary.ClientService {
get { return LOGGING_DOMAIN; }
}
private Quirks quirks;
private Quirks quirks = new Quirks();
private Nonblocking.Mutex sessions_mutex = new Nonblocking.Mutex();
private Gee.Set<ClientSession> all_sessions =
@ -147,7 +117,6 @@ public class Geary.Imap.ClientService : Geary.ClientService {
ServiceInformation configuration,
Endpoint remote) {
base(account, configuration, remote);
this.quirks = new_quirks_for_provider(account.service_provider);
}
/**
@ -403,6 +372,7 @@ public class Geary.Imap.ClientService : Geary.ClientService {
// An error was thrown, so close the pool
this.close_pool.begin(true);
} else {
this.quirks.update_for_server(new_session);
try {
yield this.sessions_mutex.execute_locked(() => {
this.all_sessions.add(new_session);

View file

@ -39,4 +39,46 @@ public class Geary.Imap.Quirks : BaseObject {
public uint max_pipeline_batch_size { get; set; default = 0; }
public void update_for_server(ClientSession session) {
if (session.server_greeting != null) {
var greeting = session.server_greeting.get_text() ?? "";
if (greeting.has_prefix("Gimap")) {
update_for_gmail();
} else if (greeting.has_prefix("The Microsoft Exchange")) {
update_for_outlook();
}
}
}
/**
* Updates this quirks object with known quirks for GMail.
*
* As of 2020-05-02, GMail doesn't seem to quote flag
* atoms containing reserved characters, and at least one
* use of both `]` and ` ` have been found. This works
* around the former.
*
* See [[https://gitlab.gnome.org/GNOME/geary/-/issues/746]]
*/
public void update_for_gmail() {
this.flag_atom_exceptions = "]";
}
/**
* Updates this quirks object with known quirks for Outlook.com.
*
* As of June 2016, outlook.com's IMAP servers have a bug where a
* large number (~50) of pipelined STATUS commands on mailboxes
* with many messages will eventually cause it to break command
* parsing and return a BAD response, causing us to drop the
* connection. Limit the number of pipelined commands per batch to
* work around this.
*
* See [[https://bugzilla.gnome.org/show_bug.cgi?id=766552]]
*/
public void update_for_outlook() {
this.max_pipeline_batch_size = 25;
}
}

View file

@ -202,7 +202,6 @@ class Geary.Imap.DeserializerTest : TestCase {
string greeting = "* OK Gimap ready for requests from 115.187.245.46 c194mb399904375ivc";
this.stream.add_data(greeting.data);
this.stream.add_data(EOL.data);
this.deser.quirks = ClientService.new_quirks_for_provider(GMAIL);
this.process.begin(Expect.MESSAGE, this.async_completion);
RootParameters? message = this.process.end(async_result());
@ -249,7 +248,8 @@ class Geary.Imap.DeserializerTest : TestCase {
string flags = """* FLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing)""";
this.stream.add_data(flags.data);
this.stream.add_data(EOL.data);
this.deser.quirks = ClientService.new_quirks_for_provider(GMAIL);
this.deser.quirks = new Imap.Quirks();
this.deser.quirks.update_for_gmail();
this.process.begin(Expect.MESSAGE, this.async_completion);
RootParameters? message = this.process.end(async_result());
@ -261,7 +261,8 @@ class Geary.Imap.DeserializerTest : TestCase {
string flags = """* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing \*)] Flags permitted.""";
this.stream.add_data(flags.data);
this.stream.add_data(EOL.data);
this.deser.quirks = ClientService.new_quirks_for_provider(GMAIL);
this.deser.quirks = new Imap.Quirks();
this.deser.quirks.update_for_gmail();
this.process.begin(Expect.MESSAGE, this.async_completion);
RootParameters? message = this.process.end(async_result());
@ -275,7 +276,8 @@ class Geary.Imap.DeserializerTest : TestCase {
string flags = """* FLAGS (\Answered \Flagged \Draft \Deleted \Seen $Forwarded $MDNSent $NotPhishing $Phishing Junk LoadRemoteImages NonJunk OIB-Seen-INBOX OIB-Seen-Unsubscribe OIB-Seen-[Gmail]/Important OIB-Seen-[Gmail]/Spam OIB-Seen-[Gmail]/Tous les messages)""";
this.stream.add_data(flags.data);
this.stream.add_data(EOL.data);
this.deser.quirks = ClientService.new_quirks_for_provider(GMAIL);
this.deser.quirks = new Imap.Quirks();
this.deser.quirks.update_for_gmail();
this.process.begin(Expect.MESSAGE, this.async_completion);
RootParameters? message = this.process.end(async_result());

View file

@ -29,9 +29,7 @@ class Integration.Imap.ClientSession : TestCase {
public override void set_up() {
this.session = new Geary.Imap.ClientSession(
this.config.target,
Geary.Imap.ClientService.new_quirks_for_provider(
this.config.provider
)
new Geary.Imap.Quirks()
);
}