Compare commits
2 Commits
fix/pad-de
...
fix/autopi
| Author | SHA1 | Date | |
|---|---|---|---|
|
15dfc2bdb4
|
|||
|
02e679c277
|
@@ -47,6 +47,7 @@ static char* _notify_autocomplete(ProfWin* window, const char* const input, gboo
|
||||
static char* _theme_autocomplete(ProfWin* window, const char* const input, gboolean previous);
|
||||
static char* _spellcheck_autocomplete(ProfWin* window, const char* const input, gboolean previous);
|
||||
static char* _autoaway_autocomplete(ProfWin* window, const char* const input, gboolean previous);
|
||||
static char* _autoping_autocomplete(ProfWin* window, const char* const input, gboolean previous);
|
||||
static char* _autoconnect_autocomplete(ProfWin* window, const char* const input, gboolean previous);
|
||||
static char* _account_autocomplete(ProfWin* window, const char* const input, gboolean previous);
|
||||
static char* _who_autocomplete(ProfWin* window, const char* const input, gboolean previous);
|
||||
@@ -1056,6 +1057,7 @@ cmd_ac_init(void)
|
||||
|
||||
autocomplete_add(autoping_ac, "set");
|
||||
autocomplete_add(autoping_ac, "timeout");
|
||||
autocomplete_add(autoping_ac, "warning");
|
||||
|
||||
autocomplete_add(plugins_ac, "install");
|
||||
autocomplete_add(plugins_ac, "update");
|
||||
@@ -1407,6 +1409,7 @@ cmd_ac_init(void)
|
||||
g_hash_table_insert(ac_funcs, "/alias", _alias_autocomplete);
|
||||
g_hash_table_insert(ac_funcs, "/autoaway", _autoaway_autocomplete);
|
||||
g_hash_table_insert(ac_funcs, "/autoconnect", _autoconnect_autocomplete);
|
||||
g_hash_table_insert(ac_funcs, "/autoping", _autoping_autocomplete);
|
||||
g_hash_table_insert(ac_funcs, "/avatar", _avatar_autocomplete);
|
||||
g_hash_table_insert(ac_funcs, "/ban", _ban_autocomplete);
|
||||
g_hash_table_insert(ac_funcs, "/blocked", _blocked_autocomplete);
|
||||
@@ -1934,7 +1937,6 @@ _cmd_ac_complete_params(ProfWin* window, const char* const input, gboolean previ
|
||||
{ "/prefs", prefs_ac },
|
||||
{ "/disco", disco_ac },
|
||||
{ "/room", room_ac },
|
||||
{ "/autoping", autoping_ac },
|
||||
{ "/mainwin", winpos_ac },
|
||||
{ "/inputwin", winpos_ac },
|
||||
};
|
||||
@@ -4264,6 +4266,20 @@ _executable_autocomplete(ProfWin* window, const char* const input, gboolean prev
|
||||
return result;
|
||||
}
|
||||
|
||||
static char*
|
||||
_autoping_autocomplete(ProfWin* window, const char* const input, gboolean previous)
|
||||
{
|
||||
char* result = NULL;
|
||||
|
||||
result = autocomplete_param_with_ac(input, "/autoping", autoping_ac, TRUE, previous);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = autocomplete_param_with_func(input, "/autoping warning", prefs_autocomplete_boolean_choice, previous, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
static char*
|
||||
_lastactivity_autocomplete(ProfWin* window, const char* const input, gboolean previous)
|
||||
{
|
||||
|
||||
@@ -1964,12 +1964,14 @@ static const struct cmd_t command_defs[] = {
|
||||
CMD_TAG_CONNECTION)
|
||||
CMD_SYN(
|
||||
"/autoping set <seconds>",
|
||||
"/autoping timeout <seconds>")
|
||||
"/autoping timeout <seconds>",
|
||||
"/autoping warning on|off")
|
||||
CMD_DESC(
|
||||
"Set the interval between sending ping requests to the server to ensure the connection is kept alive.")
|
||||
CMD_ARGS(
|
||||
{ "set <seconds>", "Number of seconds between sending pings, a value of 0 disables autoping." },
|
||||
{ "timeout <seconds>", "Seconds to wait for autoping responses, after which the connection is considered broken." })
|
||||
{ "timeout <seconds>", "Seconds to wait for autoping responses, after which the connection is considered broken." },
|
||||
{ "warning on|off", "Enable or disable autoping availability warning." })
|
||||
},
|
||||
|
||||
{ CMD_PREAMBLE("/ping",
|
||||
|
||||
@@ -6374,6 +6374,8 @@ cmd_autoping(ProfWin* window, const char* const command, gchar** args)
|
||||
cons_bad_cmd_usage(command);
|
||||
}
|
||||
|
||||
} else if (g_strcmp0(cmd, "warning") == 0) {
|
||||
_cmd_set_boolean_preference(value, "Autoping availability warning", PREF_AUTOPING_WARNING);
|
||||
} else {
|
||||
cons_bad_cmd_usage(command);
|
||||
}
|
||||
|
||||
@@ -2290,6 +2290,7 @@ _get_group(preference_t pref)
|
||||
case PREF_TRAY:
|
||||
case PREF_TRAY_READ:
|
||||
case PREF_ADV_NOTIFY_DISCO_OR_VERSION:
|
||||
case PREF_AUTOPING_WARNING:
|
||||
return PREF_GROUP_NOTIFICATIONS;
|
||||
case PREF_DBLOG:
|
||||
case PREF_CHLOG:
|
||||
@@ -2646,6 +2647,8 @@ _get_key(preference_t pref)
|
||||
return "enabled";
|
||||
case PREF_SPELLCHECK_LANG:
|
||||
return "lang";
|
||||
case PREF_AUTOPING_WARNING:
|
||||
return "autoping.warning";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -2699,6 +2702,7 @@ _get_default_boolean(preference_t pref)
|
||||
case PREF_MOOD:
|
||||
case PREF_STROPHE_SM_ENABLED:
|
||||
case PREF_STROPHE_SM_RESEND:
|
||||
case PREF_AUTOPING_WARNING:
|
||||
return TRUE;
|
||||
case PREF_SPELLCHECK_ENABLE:
|
||||
case PREF_PGP_PUBKEY_AUTOIMPORT:
|
||||
|
||||
@@ -169,6 +169,7 @@ typedef enum {
|
||||
PREF_FORCE_ENCRYPTION_MODE,
|
||||
PREF_SPELLCHECK_ENABLE,
|
||||
PREF_SPELLCHECK_LANG,
|
||||
PREF_AUTOPING_WARNING
|
||||
} preference_t;
|
||||
|
||||
typedef struct prof_alias_t
|
||||
|
||||
@@ -1703,6 +1703,11 @@ cons_notify_setting(void)
|
||||
else
|
||||
cons_show("Subscription requests (/notify sub) : OFF");
|
||||
|
||||
if (prefs_get_boolean(PREF_AUTOPING_WARNING))
|
||||
cons_show("Autoping warning (/autoping warning): ON");
|
||||
else
|
||||
cons_show("Autoping warning (/autoping warning): OFF");
|
||||
|
||||
gint remind_period = prefs_get_notify_remind();
|
||||
if (remind_period == 0) {
|
||||
cons_show("Reminder period (/notify remind) : OFF");
|
||||
@@ -2003,21 +2008,26 @@ cons_autoping_setting(void)
|
||||
{
|
||||
gint autoping_interval = prefs_get_autoping();
|
||||
if (autoping_interval == 0) {
|
||||
cons_show("Autoping interval (/autoping) : OFF");
|
||||
cons_show("Autoping interval (/autoping) : OFF");
|
||||
} else if (autoping_interval == 1) {
|
||||
cons_show("Autoping interval (/autoping) : 1 second");
|
||||
cons_show("Autoping interval (/autoping) : 1 second");
|
||||
} else {
|
||||
cons_show("Autoping interval (/autoping) : %d seconds", autoping_interval);
|
||||
cons_show("Autoping interval (/autoping) : %d seconds", autoping_interval);
|
||||
}
|
||||
|
||||
gint autoping_timeout = prefs_get_autoping_timeout();
|
||||
if (autoping_timeout == 0) {
|
||||
cons_show("Autoping timeout (/autoping) : OFF");
|
||||
cons_show("Autoping timeout (/autoping) : OFF");
|
||||
} else if (autoping_timeout == 1) {
|
||||
cons_show("Autoping timeout (/autoping) : 1 second");
|
||||
cons_show("Autoping timeout (/autoping) : 1 second");
|
||||
} else {
|
||||
cons_show("Autoping timeout (/autoping) : %d seconds", autoping_timeout);
|
||||
cons_show("Autoping timeout (/autoping) : %d seconds", autoping_timeout);
|
||||
}
|
||||
|
||||
if (prefs_get_boolean(PREF_AUTOPING_WARNING))
|
||||
cons_show("Autoping warning (/autoping warning): ON");
|
||||
else
|
||||
cons_show("Autoping warning (/autoping warning): OFF");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -99,6 +99,7 @@ static void _disco_items_result_handler(xmpp_stanza_t* const stanza);
|
||||
static void _last_activity_get_handler(xmpp_stanza_t* const stanza);
|
||||
static void _version_get_handler(xmpp_stanza_t* const stanza);
|
||||
static void _ping_get_handler(xmpp_stanza_t* const stanza);
|
||||
static void _disco_autoping_warning_message(GHashTable* features);
|
||||
|
||||
static int _version_result_id_handler(xmpp_stanza_t* const stanza, void* const userdata);
|
||||
static int _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdata);
|
||||
@@ -2429,6 +2430,12 @@ _disco_info_response_id_handler_onconnect(xmpp_stanza_t* const stanza, void* con
|
||||
}
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
|
||||
// Prevent repetitions by avoiding checks of disco items (from connection_set_disco_items)
|
||||
const char* domain = connection_get_domain();
|
||||
if (from && domain && g_ascii_strcasecmp(from, domain) == 0) {
|
||||
_disco_autoping_warning_message(features);
|
||||
}
|
||||
}
|
||||
|
||||
connection_features_received(from);
|
||||
@@ -2436,6 +2443,21 @@ _disco_info_response_id_handler_onconnect(xmpp_stanza_t* const stanza, void* con
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_disco_autoping_warning_message(GHashTable* features)
|
||||
{
|
||||
gboolean server_supports_ping = g_hash_table_contains(features, "urn:xmpp:ping");
|
||||
gboolean user_prefers_warning = prefs_get_boolean(PREF_AUTOPING_WARNING);
|
||||
gboolean is_autoping_enabled = prefs_get_autoping() != 0;
|
||||
|
||||
if (!is_autoping_enabled && server_supports_ping && user_prefers_warning) {
|
||||
cons_show("This server supports XEP-0199: XMPP Ping (better keepalive detection),\n"
|
||||
"but autoping feature is currently disabled in settings.\n"
|
||||
"Consider enabling it (e.g., `/autoping set 30`) for improved connection stability.\n"
|
||||
"Use `/autoping warning off` to disable this message.");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_http_upload_response_id_handler(xmpp_stanza_t* const stanza, void* const userdata)
|
||||
{
|
||||
|
||||
@@ -150,6 +150,14 @@ main(int argc, char* argv[])
|
||||
PROF_FUNC_TEST(autoping_sends_ping_after_interval),
|
||||
PROF_FUNC_TEST(autoping_server_not_supporting_ping),
|
||||
|
||||
/* Autoping availability warning - negative cases wait ~3s */
|
||||
PROF_FUNC_TEST(autoping_warning_shown_when_disabled),
|
||||
PROF_FUNC_TEST(autoping_warning_not_shown_when_server_unsupported),
|
||||
PROF_FUNC_TEST(autoping_warning_not_shown_when_autoping_enabled),
|
||||
PROF_FUNC_TEST(autoping_warning_not_shown_when_user_disabled),
|
||||
PROF_FUNC_TEST(autoping_warning_not_shown_for_user_jid),
|
||||
PROF_FUNC_TEST(autoping_warning_not_shown_for_subdomain_service),
|
||||
|
||||
/* Service Discovery - XEP-0030 */
|
||||
PROF_FUNC_TEST(disco_info_shows_identity),
|
||||
PROF_FUNC_TEST(disco_info_shows_features),
|
||||
|
||||
@@ -112,3 +112,144 @@ autoping_server_not_supporting_ping(void** state)
|
||||
// Should show error about ping not being supported
|
||||
assert_true(prof_output_regex("Server ping not supported"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Autoping availability warning.
|
||||
*
|
||||
* The warning fires from the on-connect disco handler, so the three inputs
|
||||
* (server ping support, autoping interval, warning preference) must all be
|
||||
* set before prof_connect().
|
||||
*/
|
||||
|
||||
/* Stable substring of the warning text emitted by iq.c. */
|
||||
#define AUTOPING_WARNING_MATCH "This server supports XEP-0199"
|
||||
|
||||
static void
|
||||
_stub_server_disco(gboolean with_ping)
|
||||
{
|
||||
if (with_ping) {
|
||||
stbbr_for_query("http://jabber.org/protocol/disco#info",
|
||||
"<iq to='stabber@localhost/profanity' type='result' from='localhost'>"
|
||||
"<query xmlns='http://jabber.org/protocol/disco#info'>"
|
||||
"<identity category='server' type='im' name='Stabber'/>"
|
||||
"<feature var='urn:xmpp:ping'/>"
|
||||
"</query>"
|
||||
"</iq>"
|
||||
);
|
||||
} else {
|
||||
stbbr_for_query("http://jabber.org/protocol/disco#info",
|
||||
"<iq to='stabber@localhost/profanity' type='result' from='localhost'>"
|
||||
"<query xmlns='http://jabber.org/protocol/disco#info'>"
|
||||
"<identity category='server' type='im' name='Stabber'/>"
|
||||
"</query>"
|
||||
"</iq>"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
autoping_warning_shown_when_disabled(void** state)
|
||||
{
|
||||
// All conditions met: server supports ping, autoping off, warning on (default).
|
||||
_stub_server_disco(TRUE);
|
||||
|
||||
prof_input("/autoping set 0");
|
||||
assert_true(prof_output_exact("Autoping disabled."));
|
||||
|
||||
prof_connect();
|
||||
|
||||
assert_true(prof_output_regex(AUTOPING_WARNING_MATCH));
|
||||
}
|
||||
|
||||
void
|
||||
autoping_warning_not_shown_when_server_unsupported(void** state)
|
||||
{
|
||||
// Server does not advertise urn:xmpp:ping -> no warning even with autoping off.
|
||||
_stub_server_disco(FALSE);
|
||||
|
||||
prof_input("/autoping set 0");
|
||||
assert_true(prof_output_exact("Autoping disabled."));
|
||||
|
||||
prof_connect();
|
||||
|
||||
prof_timeout(NEGATIVE_ASSERT_TIMEOUT);
|
||||
assert_false(prof_output_regex(AUTOPING_WARNING_MATCH));
|
||||
}
|
||||
|
||||
void
|
||||
autoping_warning_not_shown_when_autoping_enabled(void** state)
|
||||
{
|
||||
// Warning is suppressed while autoping is enabled.
|
||||
_stub_server_disco(TRUE);
|
||||
|
||||
prof_input("/autoping set 30");
|
||||
assert_true(prof_output_exact("Autoping interval set to 30 seconds."));
|
||||
|
||||
prof_connect();
|
||||
|
||||
prof_timeout(NEGATIVE_ASSERT_TIMEOUT);
|
||||
assert_false(prof_output_regex(AUTOPING_WARNING_MATCH));
|
||||
}
|
||||
|
||||
void
|
||||
autoping_warning_not_shown_when_user_disabled(void** state)
|
||||
{
|
||||
// User opted out -> no warning.
|
||||
_stub_server_disco(TRUE);
|
||||
|
||||
prof_input("/autoping set 0");
|
||||
assert_true(prof_output_exact("Autoping disabled."));
|
||||
|
||||
prof_input("/autoping warning off");
|
||||
assert_true(prof_output_exact("Autoping availability warning disabled."));
|
||||
|
||||
prof_connect();
|
||||
|
||||
prof_timeout(NEGATIVE_ASSERT_TIMEOUT);
|
||||
assert_false(prof_output_regex(AUTOPING_WARNING_MATCH));
|
||||
}
|
||||
|
||||
void
|
||||
autoping_warning_not_shown_for_user_jid(void** state)
|
||||
{
|
||||
// disco#info from a user JID (with '@') should not trigger the warning,
|
||||
// only server responses (no '@') should.
|
||||
stbbr_for_query("http://jabber.org/protocol/disco#info",
|
||||
"<iq to='stabber@localhost/profanity' type='result' from='buddy1@localhost'>"
|
||||
"<query xmlns='http://jabber.org/protocol/disco#info'>"
|
||||
"<identity category='person' type='chat' name='Buddy1'/>"
|
||||
"<feature var='urn:xmpp:ping'/>"
|
||||
"</query>"
|
||||
"</iq>"
|
||||
);
|
||||
|
||||
prof_input("/autoping set 0");
|
||||
assert_true(prof_output_exact("Autoping disabled."));
|
||||
|
||||
prof_connect();
|
||||
|
||||
prof_timeout(NEGATIVE_ASSERT_TIMEOUT);
|
||||
assert_false(prof_output_regex(AUTOPING_WARNING_MATCH));
|
||||
}
|
||||
|
||||
void
|
||||
autoping_warning_not_shown_for_subdomain_service(void** state)
|
||||
{
|
||||
// disco#info from a subdomain service should not trigger the warning, only the server's own domain should
|
||||
stbbr_for_query("http://jabber.org/protocol/disco#info",
|
||||
"<iq to='stabber@localhost/profanity' type='result' from='conf.localhost'>"
|
||||
"<query xmlns='http://jabber.org/protocol/disco#info'>"
|
||||
"<identity category='conference' type='text' name='Conference Service'/>"
|
||||
"<feature var='urn:xmpp:ping'/>"
|
||||
"</query>"
|
||||
"</iq>"
|
||||
);
|
||||
|
||||
prof_input("/autoping set 0");
|
||||
assert_true(prof_output_exact("Autoping disabled."));
|
||||
|
||||
prof_connect();
|
||||
|
||||
prof_timeout(NEGATIVE_ASSERT_TIMEOUT);
|
||||
assert_false(prof_output_regex(AUTOPING_WARNING_MATCH));
|
||||
}
|
||||
|
||||
@@ -4,3 +4,9 @@ void autoping_timeout_set(void** state);
|
||||
void autoping_timeout_zero_disables(void** state);
|
||||
void autoping_sends_ping_after_interval(void** state);
|
||||
void autoping_server_not_supporting_ping(void** state);
|
||||
void autoping_warning_shown_when_disabled(void** state);
|
||||
void autoping_warning_not_shown_when_server_unsupported(void** state);
|
||||
void autoping_warning_not_shown_when_autoping_enabled(void** state);
|
||||
void autoping_warning_not_shown_when_user_disabled(void** state);
|
||||
void autoping_warning_not_shown_for_user_jid(void** state);
|
||||
void autoping_warning_not_shown_for_subdomain_service(void** state);
|
||||
|
||||
Reference in New Issue
Block a user