Fixed bug in keepalive code. Cleaned up some exceptions.
Keepalive could cause a segfault if the server closed the connection. This fixes that as well as updates some of the exception-throwing code to use more appropriate ImapErrors.
This commit is contained in:
parent
013f6b57e1
commit
5f6076e8cb
4 changed files with 34 additions and 13 deletions
|
|
@ -56,7 +56,9 @@ public class Geary.Imap.ClientConnection {
|
|||
// TODO: Close connection as gracefully as possible
|
||||
}
|
||||
|
||||
// Generates a unique tag for the IMAP connection in the form of "<a-z><000-999>".
|
||||
/**
|
||||
* Generates a unique tag for the IMAP connection in the form of "<a-z><000-999>".
|
||||
*/
|
||||
public Tag generate_tag() {
|
||||
// watch for odometer rollover
|
||||
if (++tag_counter >= 1000) {
|
||||
|
|
@ -71,9 +73,15 @@ public class Geary.Imap.ClientConnection {
|
|||
return new Tag("%c%03d".printf(tag_prefix, tag_counter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns silently if a connection is already established.
|
||||
*/
|
||||
public async void connect_async(Cancellable? cancellable = null) throws Error {
|
||||
if (cx != null)
|
||||
throw new IOError.EXISTS("Already connected to %s", to_string());
|
||||
if (cx != null) {
|
||||
debug("Already connected to %s", to_string());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
cx = yield socket_client.connect_to_host_async(host_specifier, default_port, cancellable);
|
||||
ser = new Serializer(new BufferedOutputStream(cx.output_stream));
|
||||
|
|
@ -159,7 +167,7 @@ public class Geary.Imap.ClientConnection {
|
|||
|
||||
private void check_for_connection() throws Error {
|
||||
if (cx == null)
|
||||
throw new IOError.CLOSED("Not connected to %s", to_string());
|
||||
throw new ImapError.NOT_CONNECTED("Not connected to %s", to_string());
|
||||
}
|
||||
|
||||
public string to_string() {
|
||||
|
|
|
|||
|
|
@ -337,8 +337,11 @@ public class Geary.Imap.ClientSession {
|
|||
fsm.set_logging(false);
|
||||
}
|
||||
|
||||
public Tag? generate_tag() {
|
||||
return (cx != null) ? cx.generate_tag() : null;
|
||||
public Tag generate_tag() throws ImapError {
|
||||
if (cx == null)
|
||||
throw new ImapError.NOT_CONNECTED("Not connected to %s", to_string());
|
||||
|
||||
return cx.generate_tag();
|
||||
}
|
||||
|
||||
public string? get_current_mailbox() {
|
||||
|
|
@ -559,7 +562,15 @@ public class Geary.Imap.ClientSession {
|
|||
}
|
||||
|
||||
private bool on_keepalive() {
|
||||
send_command_async.begin(new NoopCommand(generate_tag()), null, on_keepalive_completed);
|
||||
try {
|
||||
send_command_async.begin(new NoopCommand(generate_tag()), null, on_keepalive_completed);
|
||||
} catch (ImapError ierr) {
|
||||
message("Unable to keepalive %s, halting attempts: %s", to_string(), ierr.message);
|
||||
|
||||
keepalive_id = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -610,7 +621,7 @@ public class Geary.Imap.ClientSession {
|
|||
if (cmd.has_name(LoginCommand.NAME) || cmd.has_name(LogoutCommand.NAME)
|
||||
|| cmd.has_name(SelectCommand.NAME) || cmd.has_name(ExamineCommand.NAME)
|
||||
|| cmd.has_name(CloseCommand.NAME)) {
|
||||
throw new IOError.NOT_SUPPORTED("Use direct calls rather than commands");
|
||||
throw new ImapError.NOT_SUPPORTED("Use direct calls rather than commands");
|
||||
}
|
||||
|
||||
SendCommandParams params = new SendCommandParams(cmd, cancellable, send_command_async.callback);
|
||||
|
|
@ -937,7 +948,7 @@ public class Geary.Imap.ClientSession {
|
|||
assert(object != null);
|
||||
|
||||
AsyncParams params = (AsyncParams) object;
|
||||
params.err = new IOError.CLOSED("Connection to %s closing or closed", to_string());
|
||||
params.err = new ImapError.NOT_CONNECTED("Connection to %s closing or closed", to_string());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
|
@ -973,7 +984,7 @@ public class Geary.Imap.ClientSession {
|
|||
Cancellable? cancellable = null) {
|
||||
if (cx == null) {
|
||||
return new AsyncCommandResponse(null, user,
|
||||
new IOError.CLOSED("Not connected to %s", server));
|
||||
new ImapError.NOT_CONNECTED("Not connected to %s", server));
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ public errordomain Geary.ImapError {
|
|||
SERVER_ERROR,
|
||||
NOT_CONNECTED,
|
||||
COMMAND_FAILED,
|
||||
UNAUTHENTICATED
|
||||
UNAUTHENTICATED,
|
||||
NOT_SUPPORTED,
|
||||
NOT_SELECTED
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class Geary.Imap.Mailbox : Geary.SmartReference, Geary.Folder {
|
|||
public async Gee.List<EmailHeader>? read(int low, int count, Cancellable? cancellable = null)
|
||||
throws Error {
|
||||
if (mailbox.is_closed())
|
||||
throw new IOError.NOT_FOUND("Mailbox %s closed", mailbox.to_string());
|
||||
throw new ImapError.NOT_SELECTED("Mailbox %s closed", mailbox.to_string());
|
||||
|
||||
CommandResponse resp = yield mailbox.session.send_command_async(
|
||||
new FetchCommand(mailbox.session.generate_tag(), new MessageSet.range(low, count),
|
||||
|
|
@ -53,7 +53,7 @@ public class Geary.Imap.Mailbox : Geary.SmartReference, Geary.Folder {
|
|||
assert(header != null);
|
||||
|
||||
if (mailbox.is_closed())
|
||||
throw new IOError.NOT_FOUND("Folder closed");
|
||||
throw new ImapError.NOT_SELECTED("Folder closed");
|
||||
|
||||
CommandResponse resp = yield mailbox.session.send_command_async(
|
||||
new FetchCommand(mailbox.session.generate_tag(), new MessageSet(hdr.msg_num),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue