mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Added caching of legacy capabilities
This commit is contained in:
parent
f46d0541c6
commit
aec7afd06a
202
src/xmpp/iq.c
202
src/xmpp/iq.c
@ -96,6 +96,10 @@ static int _ping_timed_handler(xmpp_conn_t * const conn,
|
|||||||
void * const userdata);
|
void * const userdata);
|
||||||
static int _caps_response_handler(xmpp_conn_t *const conn,
|
static int _caps_response_handler(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza, void * const userdata);
|
xmpp_stanza_t * const stanza, void * const userdata);
|
||||||
|
static int _caps_response_handler_for_jid(xmpp_conn_t *const conn,
|
||||||
|
xmpp_stanza_t * const stanza, void * const userdata);
|
||||||
|
static int _caps_response_handler_legacy(xmpp_conn_t *const conn,
|
||||||
|
xmpp_stanza_t * const stanza, void * const userdata);
|
||||||
|
|
||||||
void
|
void
|
||||||
iq_add_handlers(void)
|
iq_add_handlers(void)
|
||||||
@ -201,7 +205,7 @@ _iq_send_caps_request_for_jid(const char * const to, const char * const id,
|
|||||||
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, to, node_str->str);
|
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, to, node_str->str);
|
||||||
g_string_free(node_str, TRUE);
|
g_string_free(node_str, TRUE);
|
||||||
|
|
||||||
xmpp_id_handler_add(conn, _caps_response_handler, id, strdup(to));
|
xmpp_id_handler_add(conn, _caps_response_handler_for_jid, id, strdup(to));
|
||||||
|
|
||||||
xmpp_send(conn, iq);
|
xmpp_send(conn, iq);
|
||||||
xmpp_stanza_release(iq);
|
xmpp_stanza_release(iq);
|
||||||
@ -234,6 +238,33 @@ _iq_send_caps_request(const char * const to, const char * const id,
|
|||||||
xmpp_stanza_release(iq);
|
xmpp_stanza_release(iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_iq_send_caps_request_legacy(const char * const to, const char * const id,
|
||||||
|
const char * const node, const char * const ver)
|
||||||
|
{
|
||||||
|
xmpp_conn_t * const conn = connection_get_conn();
|
||||||
|
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
log_error("Could not create caps request, no node");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!ver) {
|
||||||
|
log_error("Could not create caps request, no ver");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GString *node_str = g_string_new("");
|
||||||
|
g_string_printf(node_str, "%s#%s", node, ver);
|
||||||
|
xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, to, node_str->str);
|
||||||
|
|
||||||
|
xmpp_id_handler_add(conn, _caps_response_handler_legacy, id, node_str->str);
|
||||||
|
g_string_free(node_str, FALSE);
|
||||||
|
|
||||||
|
xmpp_send(conn, iq);
|
||||||
|
xmpp_stanza_release(iq);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_iq_disco_items_request(gchar *jid)
|
_iq_disco_items_request(gchar *jid)
|
||||||
{
|
{
|
||||||
@ -521,40 +552,154 @@ _caps_response_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userdata) {
|
// validate sha1
|
||||||
char *jid = (char *)userdata;
|
gchar **split = g_strsplit(node, "#", -1);
|
||||||
log_info("Associating capabilities with: %s", jid);
|
char *given_sha1 = split[1];
|
||||||
Capabilities *capabilities = caps_create(query);
|
char *generated_sha1 = caps_create_sha1_str(query);
|
||||||
caps_add_by_jid(jid, capabilities);
|
|
||||||
|
if (g_strcmp0(given_sha1, generated_sha1) != 0) {
|
||||||
|
log_warning("Generated sha-1 does not match given:");
|
||||||
|
log_warning("Generated : %s", generated_sha1);
|
||||||
|
log_warning("Given : %s", given_sha1);
|
||||||
} else {
|
} else {
|
||||||
// validate sha1
|
log_info("Valid SHA-1 hash found: %s", given_sha1);
|
||||||
gchar **split = g_strsplit(node, "#", -1);
|
|
||||||
char *given_sha1 = split[1];
|
|
||||||
char *generated_sha1 = caps_create_sha1_str(query);
|
|
||||||
|
|
||||||
if (g_strcmp0(given_sha1, generated_sha1) != 0) {
|
if (caps_contains(given_sha1)) {
|
||||||
log_warning("Generated sha-1 does not match given:");
|
log_info("Capabilties already cached: %s", given_sha1);
|
||||||
log_warning("Generated : %s", generated_sha1);
|
|
||||||
log_warning("Given : %s", given_sha1);
|
|
||||||
} else {
|
} else {
|
||||||
log_info("Valid SHA-1 hash found: %s", given_sha1);
|
log_info("Capabilities not cached: %s, storing", given_sha1);
|
||||||
|
Capabilities *capabilities = caps_create(query);
|
||||||
if (caps_contains(given_sha1)) {
|
caps_add_by_ver(given_sha1, capabilities);
|
||||||
log_info("Capabilties already cached: %s", given_sha1);
|
caps_destroy(capabilities);
|
||||||
} else {
|
|
||||||
log_info("Capabilities not cached: %s, storing", given_sha1);
|
|
||||||
Capabilities *capabilities = caps_create(query);
|
|
||||||
caps_add_by_ver(given_sha1, capabilities);
|
|
||||||
caps_destroy(capabilities);
|
|
||||||
}
|
|
||||||
|
|
||||||
caps_map_jid_to_ver(from, given_sha1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(generated_sha1);
|
caps_map_jid_to_ver(from, given_sha1);
|
||||||
g_strfreev(split);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free(generated_sha1);
|
||||||
|
g_strfreev(split);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_caps_response_handler_for_jid(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
|
||||||
|
void * const userdata)
|
||||||
|
{
|
||||||
|
const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
|
||||||
|
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||||
|
|
||||||
|
char *type = xmpp_stanza_get_type(stanza);
|
||||||
|
// ignore non result
|
||||||
|
if ((g_strcmp0(type, "get") == 0) || (g_strcmp0(type, "set") == 0)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
log_info("Capabilities response handler fired for id %s", id);
|
||||||
|
} else {
|
||||||
|
log_info("Capabilities response handler fired");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||||
|
if (!from) {
|
||||||
|
log_info("No from attribute");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle error responses
|
||||||
|
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||||
|
char *error_message = stanza_get_error_message(stanza);
|
||||||
|
log_warning("Error received for capabilities response from %s: ", from, error_message);
|
||||||
|
free(error_message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query == NULL) {
|
||||||
|
log_warning("No query element found.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
|
||||||
|
if (node == NULL) {
|
||||||
|
log_warning("No node attribute found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *jid = (char *)userdata;
|
||||||
|
log_info("Associating capabilities with: %s", jid);
|
||||||
|
Capabilities *capabilities = caps_create(query);
|
||||||
|
caps_add_by_jid(jid, capabilities);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_caps_response_handler_legacy(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
|
||||||
|
void * const userdata)
|
||||||
|
{
|
||||||
|
const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
|
||||||
|
xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
|
||||||
|
|
||||||
|
char *type = xmpp_stanza_get_type(stanza);
|
||||||
|
// ignore non result
|
||||||
|
if ((g_strcmp0(type, "get") == 0) || (g_strcmp0(type, "set") == 0)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
log_info("Capabilities response handler fired for id %s", id);
|
||||||
|
} else {
|
||||||
|
log_info("Capabilities response handler fired");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||||
|
if (!from) {
|
||||||
|
log_info("No from attribute");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle error responses
|
||||||
|
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||||
|
char *error_message = stanza_get_error_message(stanza);
|
||||||
|
log_warning("Error received for capabilities response from %s: ", from, error_message);
|
||||||
|
free(error_message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query == NULL) {
|
||||||
|
log_warning("No query element found.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
|
||||||
|
if (node == NULL) {
|
||||||
|
log_warning("No node attribute found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *expected_node = (char *)userdata;
|
||||||
|
|
||||||
|
// nodes match
|
||||||
|
if (g_strcmp0(expected_node, node) == 0) {
|
||||||
|
log_info("Legacy capabilities, nodes match %s", node);
|
||||||
|
if (caps_contains(node)) {
|
||||||
|
log_info("Capabilties already cached: %s", node);
|
||||||
|
} else {
|
||||||
|
log_info("Capabilities not cached: %s, storing", node);
|
||||||
|
Capabilities *capabilities = caps_create(query);
|
||||||
|
caps_add_by_ver(node, capabilities);
|
||||||
|
caps_destroy(capabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
caps_map_jid_to_ver(from, node);
|
||||||
|
|
||||||
|
// node match fail
|
||||||
|
} else {
|
||||||
|
log_info("Legacy Capabilities nodes do not match, expeceted %s, given %s.", expected_node, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(expected_node);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1295,6 +1440,7 @@ iq_init_module(void)
|
|||||||
iq_submit_room_config = _iq_submit_room_config;
|
iq_submit_room_config = _iq_submit_room_config;
|
||||||
iq_send_caps_request = _iq_send_caps_request;
|
iq_send_caps_request = _iq_send_caps_request;
|
||||||
iq_send_caps_request_for_jid = _iq_send_caps_request_for_jid;
|
iq_send_caps_request_for_jid = _iq_send_caps_request_for_jid;
|
||||||
|
iq_send_caps_request_legacy = _iq_send_caps_request_legacy;
|
||||||
iq_room_info_request = _iq_room_info_request;
|
iq_room_info_request = _iq_room_info_request;
|
||||||
iq_room_affiliation_set = _iq_room_affiliation_set;
|
iq_room_affiliation_set = _iq_room_affiliation_set;
|
||||||
iq_room_affiliation_list = _iq_room_affiliation_list;
|
iq_room_affiliation_list = _iq_room_affiliation_list;
|
||||||
|
@ -502,7 +502,7 @@ _unavailable_handler(xmpp_conn_t * const conn,
|
|||||||
static void
|
static void
|
||||||
_handle_caps(char *jid, XMPPCaps *caps)
|
_handle_caps(char *jid, XMPPCaps *caps)
|
||||||
{
|
{
|
||||||
// hash supported xep-0115
|
// hash supported, xep-0115, cache against ver
|
||||||
if (g_strcmp0(caps->hash, "sha-1") == 0) {
|
if (g_strcmp0(caps->hash, "sha-1") == 0) {
|
||||||
log_info("Hash %s supported", caps->hash);
|
log_info("Hash %s supported", caps->hash);
|
||||||
if (caps->ver) {
|
if (caps->ver) {
|
||||||
@ -517,17 +517,21 @@ _handle_caps(char *jid, XMPPCaps *caps)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsupported hash
|
// unsupported hash, xep-0115, assoiciate with JID, no cache
|
||||||
} else if (caps->hash) {
|
} else if (caps->hash) {
|
||||||
log_info("Hash %s not supported: %s, sending service discovery request", caps->hash, jid);
|
log_info("Hash %s not supported: %s, sending service discovery request", caps->hash, jid);
|
||||||
char *id = create_unique_id("caps");
|
char *id = create_unique_id("caps");
|
||||||
iq_send_caps_request_for_jid(jid, id, caps->node, caps->ver);
|
iq_send_caps_request_for_jid(jid, id, caps->node, caps->ver);
|
||||||
free(id);
|
free(id);
|
||||||
|
|
||||||
// no hash
|
// no hash, legacy caps, cache against node#ver
|
||||||
|
} else if (caps->node && caps->ver) {
|
||||||
|
log_info("No hash specified: %s, legacy request made for %s#%s", jid, caps->node, caps->ver);
|
||||||
|
char *id = create_unique_id("caps");
|
||||||
|
iq_send_caps_request_legacy(jid, id, caps->node, caps->ver);
|
||||||
|
free(id);
|
||||||
} else {
|
} else {
|
||||||
log_info("No hash specified: %s, not sending service discovery request", jid);
|
log_info("No hash specified: %s, could not create ver string, not sending service disovery request.", jid);
|
||||||
// do legacy
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +194,8 @@ void (*iq_send_caps_request)(const char * const to, const char * const id,
|
|||||||
const char * const node, const char * const ver);
|
const char * const node, const char * const ver);
|
||||||
void (*iq_send_caps_request_for_jid)(const char * const to, const char * const id,
|
void (*iq_send_caps_request_for_jid)(const char * const to, const char * const id,
|
||||||
const char * const node, const char * const ver);
|
const char * const node, const char * const ver);
|
||||||
|
void (*iq_send_caps_request_legacy)(const char * const to, const char * const id,
|
||||||
|
const char * const node, const char * const ver);
|
||||||
void (*iq_room_info_request)(gchar *room);
|
void (*iq_room_info_request)(gchar *room);
|
||||||
void (*iq_room_affiliation_list)(const char * const room, char *affiliation);
|
void (*iq_room_affiliation_list)(const char * const room, char *affiliation);
|
||||||
void (*iq_room_affiliation_set)(const char * const room, const char * const jid, char *affiliation,
|
void (*iq_room_affiliation_set)(const char * const room, const char * const jid, char *affiliation,
|
||||||
|
Loading…
Reference in New Issue
Block a user