From a321452897d932667f6e1090c3a7712c78652515 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Mon, 25 Apr 2011 16:32:55 +0300 Subject: [PATCH] Handle RPL_TRYAGAIN messages in response to RequestContactInfo This message is received when the server drops our WHOIS query without processing it and wants us to try again later. We convey this to the client by returning a ServiceBusy error. Fixes: https://bugs.freedesktop.org/34796 --- src/idle-contact-info.c | 33 +++++++++++++++++++++++++++++++++ src/idle-parser.c | 1 + src/idle-parser.h | 1 + 3 files changed, 35 insertions(+), 0 deletions(-) diff --git a/src/idle-contact-info.c b/src/idle-contact-info.c index 809d8cf..b91e93d 100644 --- a/src/idle-contact-info.c +++ b/src/idle-contact-info.c @@ -238,6 +238,38 @@ cleanup: return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; } +static IdleParserHandlerResult _try_again_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { + IdleConnection *conn = IDLE_CONNECTION(user_data); + ContactInfoRequest *request; + const gchar *command; + const gchar *msg; + GError *error = NULL; + + /* The RPL_TRYAGAIN message does not contain the nick for which the request was issued, but only the type of the message, which in this case is + * WHOIS. So we assume that the last WHOIS request that we had issued has resulted in this RPL_TRYAGAIN. This is fine as long nobody else is + * issuing a WHOIS because we issue a new request only after the earlier one was successfully completed or resulted in an error. + */ + + if (g_queue_is_empty(conn->contact_info_requests)) + return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; + + command = g_value_get_string(g_value_array_get_nth(args, 0)); + if (g_ascii_strcasecmp(command, "WHOIS")) + return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; + + request = g_queue_peek_head(conn->contact_info_requests); + + msg = g_value_get_string(g_value_array_get_nth(args, 1)); + + error = g_error_new_literal(TP_ERRORS, TP_ERROR_SERVICE_BUSY, msg); + dbus_g_method_return_error(request->context, error); + g_error_free(error); + + _dequeue_request_contact_info(conn); + + return IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; +} + static IdleParserHandlerResult _whois_channels_handler(IdleParser *parser, IdleParserMessageCode code, GValueArray *args, gpointer user_data) { IdleConnection *conn = IDLE_CONNECTION(user_data); ContactInfoRequest *request; @@ -410,6 +442,7 @@ void idle_contact_info_init (IdleConnection *conn) { idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_ENDOFWHOIS, _end_of_whois_handler, conn); idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_NOSUCHSERVER, _no_such_server_handler, conn); + idle_parser_add_handler(conn->parser, IDLE_PARSER_NUMERIC_TRYAGAIN, _try_again_handler, conn); } void idle_contact_info_iface_init(gpointer g_iface, gpointer iface_data) { diff --git a/src/idle-parser.c b/src/idle-parser.c index 68a6bcb..afb58f3 100644 --- a/src/idle-parser.c +++ b/src/idle-parser.c @@ -107,6 +107,7 @@ static const MessageSpec message_specs[] = { {"306", "III", IDLE_PARSER_NUMERIC_NOWAWAY}, {"332", "IIIr:", IDLE_PARSER_NUMERIC_TOPIC}, {"333", "IIIrcd", IDLE_PARSER_NUMERIC_TOPIC_STAMP}, + {"263", "IIIs:", IDLE_PARSER_NUMERIC_TRYAGAIN}, {"305", "III", IDLE_PARSER_NUMERIC_UNAWAY}, {"001", "IIc", IDLE_PARSER_NUMERIC_WELCOME}, {"319", "IIIc.", IDLE_PARSER_NUMERIC_WHOISCHANNELS}, diff --git a/src/idle-parser.h b/src/idle-parser.h index 3cbb9d3..4a91241 100644 --- a/src/idle-parser.h +++ b/src/idle-parser.h @@ -80,6 +80,7 @@ typedef enum { IDLE_PARSER_NUMERIC_NOWAWAY, IDLE_PARSER_NUMERIC_TOPIC, IDLE_PARSER_NUMERIC_TOPIC_STAMP, + IDLE_PARSER_NUMERIC_TRYAGAIN, IDLE_PARSER_NUMERIC_UNAWAY, IDLE_PARSER_NUMERIC_WELCOME, IDLE_PARSER_NUMERIC_WHOISCHANNELS, -- 1.7.4.4