diff --git a/ircd/m.cc b/ircd/m.cc index df1c336ea..3f458c565 100644 --- a/ircd/m.cc +++ b/ircd/m.cc @@ -4585,28 +4585,27 @@ ircd::m::id::room ircd::m::room_id(const mutable_buffer &out, const id::room_alias &room_alias) { - using prototype = id::room (const mutable_buffer &, const id::room_alias &); - - static mods::import function + room::id ret; + room::aliases::cache::get(room_alias, [&out, &ret] + (const room::id &room_id) { - "client_directory_room", "room_id__room_alias" - }; + ret = string_view { data(out), copy(out, room_id) }; + }); - return function(out, room_alias); + return ret; } bool ircd::m::exists(const id::room_alias &room_alias, const bool &remote_query) { - using prototype = bool (const id::room_alias, const bool &); + if(room::aliases::cache::has(room_alias)) + return true; - static mods::import function - { - "client_directory_room", "room_alias_exists" - }; + if(!remote_query) + return false; - return function(room_alias, remote_query); + return room::aliases::cache::get(std::nothrow, room_alias, [](const room::id &room_id) {}); } /////////////////////////////////////////////////////////////////////////////// diff --git a/modules/client/directory/room.cc b/modules/client/directory/room.cc index 36f6bc2c2..5c989affc 100644 --- a/modules/client/directory/room.cc +++ b/modules/client/directory/room.cc @@ -16,12 +16,6 @@ IRCD_MODULE "Client 7.2 :Room aliases" }; -const ircd::m::room::id::buf -alias_room_id -{ - "alias", ircd::my_host() -}; - resource directory_room_resource { @@ -32,13 +26,15 @@ directory_room_resource } }; -extern "C" m::id::room -room_id__room_alias(const mutable_buffer &out, - const m::id::room_alias &); +static resource::response +get__directory_room(client &client, + const resource::request &request); -extern "C" bool -room_alias_exists(const m::id::room_alias &, - const bool &remote_query); +resource::method +directory_room_get +{ + directory_room_resource, "GET", get__directory_room +}; resource::response get__directory_room(client &client, @@ -49,10 +45,9 @@ get__directory_room(client &client, url::decode(room_alias, request.parv[0]) }; - char buf[256]; - const m::room::id room_id + const m::room::id::buf room_id { - m::room_id(buf, room_alias) + m::room_id(room_alias) }; return resource::response @@ -64,10 +59,14 @@ get__directory_room(client &client, }; } +static resource::response +put__directory_room(client &client, + const resource::request &request); + resource::method -directory_room_get +directory_room_put { - directory_room_resource, "GET", get__directory_room + directory_room_resource, "PUT", put__directory_room }; resource::response @@ -97,176 +96,3 @@ put__directory_room(client &client, client, http::OK }; } - -resource::method -directory_room_put -{ - directory_room_resource, "PUT", put__directory_room -}; - -static json::object -room_alias_fetch(const mutable_buffer &out, - const m::id::room_alias &alias); - -bool -room_alias_exists(const m::id::room_alias &alias, - const bool &remote_query) -try -{ - const m::room alias_room{alias_room_id}; - if(alias_room.has("ircd.alias", alias)) - return true; - - if(!remote_query) - return false; - - char buf[256]; - room_id__room_alias(buf, alias); - return true; -} -catch(const m::NOT_FOUND &) -{ - return false; -} - -conf::item -room_alias_cache_ttl -{ - { "name", "ircd.client.directory.room.alias.cache.ttl" }, - { "default", 60 * 60 * 72L }, -}; - -/// Translate a room alias into a room_id. This function first checks the -/// local cache. A cache miss will then cause in a query to the remote, the -/// result of which will be added to cache. -m::id::room -room_id__room_alias(const mutable_buffer &out, - const m::id::room_alias &alias) -try -{ - m::id::room ret; - const auto cache_closure{[&out, &ret] - (const m::event &event) - { - const string_view &room_id - { - unquote(at<"content"_>(event).get("room_id")) - }; - - if(!room_id) - return; - - const auto age - { - ircd::now() - milliseconds(at<"origin_server_ts"_>(event)) - }; - - if(age > seconds(room_alias_cache_ttl)) - return; - - ret = string_view { data(out), copy(out, room_id) }; - }}; - - const m::room alias_room{alias_room_id}; - alias_room.get(std::nothrow, "ircd.alias", alias, cache_closure); - if(ret) - return ret; - - // Buf has to hold our output headers, their received headers, and - // the received aliasing content. - const unique_buffer buf - { - 32_KiB - }; - - const json::object &response - { - room_alias_fetch(buf, alias) - }; - - const m::id::room &room_id - { - unquote(response.at("room_id")) - }; - - // Cache the result - send(alias_room, m::me.user_id, "ircd.alias", alias, response); - - return m::room::id - { - string_view - { - data(out), copy(out, room_id) - } - }; -} -catch(const http::error &e) -{ - if(e.code == http::NOT_FOUND) - throw m::NOT_FOUND{}; - - throw; -} -catch(const json::not_found &e) -{ - throw m::NOT_FOUND - { - "Remote sent malformed response: %s", e.what() - }; -} - -conf::item -room_alias_fetch_timeout -{ - { "name", "ircd.client.directory.room.alias.fetch.timeout" }, - { "default", 20L }, -}; - -/// This function makes a room alias request to a remote. The alias -/// room cache is not checked or updated from here, this is only the -/// query operation. -json::object -room_alias_fetch(const mutable_buffer &out, - const m::id::room_alias &alias) -{ - m::v1::query::directory federation_request - { - alias, out, m::v1::query::opts - { - alias.host() - } - }; - - if(!federation_request.wait(seconds(room_alias_fetch_timeout), std::nothrow)) - throw http::error - { - http::REQUEST_TIMEOUT - }; - - const http::code &code - { - federation_request.get() - }; - - const json::object &response - { - federation_request - }; - - return response; -} - -const m::hookfn -_create_alias_room -{ - { - { "_site", "vm.effect" }, - { "room_id", "!ircd" }, - { "type", "m.room.create" }, - }, - - [](const m::event &, m::vm::eval &) - { - m::create(alias_room_id, m::me.user_id); - } -};