diff --git a/include/ircd/resource.h b/include/ircd/resource.h index c1082d6cd..afe5229d6 100644 --- a/include/ircd/resource.h +++ b/include/ircd/resource.h @@ -78,8 +78,9 @@ struct ircd::resource::request http::request::content &content; http::query::string query; m::user::id::buf user_id; + vector_view parv; - request(const http::request::head &head, http::request::content &content, http::query::string query); + request(const http::request::head &head, http::request::content &content, http::query::string query, const vector_view &parv); }; template @@ -90,6 +91,7 @@ struct ircd::resource::request::object const http::request::head &head; const http::request::content &content; const http::query::string &query; + const vector_view &parv; const json::object &body; object(resource::request &r) @@ -98,6 +100,7 @@ struct ircd::resource::request::object ,head{r.head} ,content{r.content} ,query{r.query} + ,parv{r.parv} ,body{r} {} }; diff --git a/ircd/resource.cc b/ircd/resource.cc index 1923083cc..c1a325e5f 100644 --- a/ircd/resource.cc +++ b/ircd/resource.cc @@ -31,8 +31,7 @@ resource::resources ircd::resource & ircd::resource::find(string_view path) { - path = strip(path, '/'); - + path = rstrip(path, '/'); auto it(resources.lower_bound(path)); if(it == end(resources)) try { @@ -176,9 +175,21 @@ ircd::resource::operator()(client &client, { auto &method(operator[](head.method)); http::request::content content{pc, head}; + + const auto pathparm + { + lstrip(head.path, this->path) + }; + + string_view param[8]; + const vector_view parv + { + param, tokens(pathparm, '/', param) + }; + resource::request request { - head, content, head.query + head, content, head.query, parv }; if(method.flags & method.REQUIRES_AUTH) @@ -286,11 +297,13 @@ catch(const std::bad_function_call &e) ircd::resource::request::request(const http::request::head &head, http::request::content &content, - http::query::string query) + http::query::string query, + const vector_view &parv) :json::object{content} ,head{head} ,content{content} ,query{std::move(query)} +,parv{parv} { } diff --git a/modules/client/account.cc b/modules/client/account.cc index 9f3ec20a1..ecbb15b05 100644 --- a/modules/client/account.cc +++ b/modules/client/account.cc @@ -26,13 +26,13 @@ struct account { resource deactivate { - "_matrix/client/r0/account/deactivate", + "/_matrix/client/r0/account/deactivate", "Deactivate the user's account, removing all ability for the user to login again. (3.3.3)" }; resource password { - "_matrix/client/r0/account/password", + "/_matrix/client/r0/account/password", "Changes the password for an account on this homeserver. (3.3.4)" }; @@ -40,7 +40,7 @@ struct account } account_resource { - "_matrix/client/r0/account", + "/_matrix/client/r0/account", "Account management (3.3)" }; diff --git a/modules/client/createroom.cc b/modules/client/createroom.cc index 28d035092..be2bcc7e1 100644 --- a/modules/client/createroom.cc +++ b/modules/client/createroom.cc @@ -23,7 +23,7 @@ using namespace ircd; resource createroom { - "_matrix/client/r0/createRoom", + "/_matrix/client/r0/createRoom", "Create a new room with various configuration options. (7.1.1)" }; @@ -94,11 +94,11 @@ catch(const db::not_found &e) }; } -resource::method post +resource::method post_method { createroom, "POST", room_create, { - post.REQUIRES_AUTH + post_method.REQUIRES_AUTH } }; diff --git a/modules/client/events.cc b/modules/client/events.cc index 5a96a7c3a..bf369fecb 100644 --- a/modules/client/events.cc +++ b/modules/client/events.cc @@ -23,7 +23,7 @@ using namespace ircd; resource events_resource { - "_matrix/client/r0/events", + "/_matrix/client/r0/events", "Events (6.2.3) (10.x)" }; diff --git a/modules/client/login.cc b/modules/client/login.cc index 528e03b92..fe79e1381 100644 --- a/modules/client/login.cc +++ b/modules/client/login.cc @@ -23,7 +23,7 @@ using namespace ircd; resource login_resource { - "_matrix/client/r0/login", + "/_matrix/client/r0/login", "Authenticates the user by password, and issues an access token " "they can use to authorize themself in subsequent requests. (3.2.2)" }; diff --git a/modules/client/logout.cc b/modules/client/logout.cc index dd58b6903..161c5a062 100644 --- a/modules/client/logout.cc +++ b/modules/client/logout.cc @@ -23,7 +23,7 @@ using namespace ircd; resource logout_resource { - "_matrix/client/r0/logout", + "/_matrix/client/r0/logout", "Invalidates an existing access token, so that it can no longer be used for " "authorization. (3.2.3)" }; @@ -42,11 +42,11 @@ logout(client &client, const resource::request &request) }; } -resource::method post +resource::method post_method { logout_resource, "POST", logout, { - post.REQUIRES_AUTH + post_method.REQUIRES_AUTH } }; diff --git a/modules/client/publicrooms.cc b/modules/client/publicrooms.cc index 64d488836..23e4effa3 100644 --- a/modules/client/publicrooms.cc +++ b/modules/client/publicrooms.cc @@ -23,7 +23,7 @@ using namespace ircd; resource publicrooms_resource { - "_matrix/client/r0/publicRooms", + "/_matrix/client/r0/publicRooms", "Lists the public rooms on the server. " "This API returns paginated responses. (7.5)" }; diff --git a/modules/client/pushrules.cc b/modules/client/pushrules.cc index 1d04f07df..13b9c8ff2 100644 --- a/modules/client/pushrules.cc +++ b/modules/client/pushrules.cc @@ -23,7 +23,7 @@ using namespace ircd; resource pushrules { - "_matrix/client/r0/pushrules", R"( + "/_matrix/client/r0/pushrules", R"( Retrieve all push rulesets for this user. Clients can "drill-down" on the rulesets by suffixing a scope to this path e.g. /pushrules/global/. This will return a subset of this data under the specified key e.g. the global key. (11.10.1.4.6) @@ -44,7 +44,7 @@ catch(...) throw; } -resource::method get +resource::method get_method { pushrules, "GET", get_pushrules }; diff --git a/modules/client/register.cc b/modules/client/register.cc index 53bcbb4b7..7d852c4db 100644 --- a/modules/client/register.cc +++ b/modules/client/register.cc @@ -175,7 +175,7 @@ handle_post(client &client, resource register_resource { - "_matrix/client/r0/register", + "/_matrix/client/r0/register", "Register for an account on this homeserver. (3.3.1)" }; diff --git a/modules/client/rooms.cc b/modules/client/rooms.cc index 84e57e51e..a9bee2f02 100644 --- a/modules/client/rooms.cc +++ b/modules/client/rooms.cc @@ -24,16 +24,11 @@ using namespace ircd; struct room :resource { - static constexpr const auto base_url - { - "_matrix/client/r0/rooms" - }; - using resource::resource; } rooms_resource { - room::base_url, resource::opts + "/_matrix/client/r0/rooms/", resource::opts { resource::DIRECTORY, "Rooms (7.0)" @@ -48,7 +43,6 @@ mapi::header IRCD_MODULE resource::response get_messages(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id) { const m::event::query event_in_room @@ -101,7 +95,6 @@ get_messages(client &client, resource::response get_members(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id) { @@ -144,7 +137,6 @@ get_members(client &client, resource::response get_state(client &client, const resource::request &request, - const string_view ¶ms, const m::event::query<> &query) { const auto count @@ -179,7 +171,6 @@ get_state(client &client, resource::response get_state(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id, const string_view &type, const string_view &state_key) @@ -191,13 +182,12 @@ get_state(client &client, { "state_key", state_key }, }; - return get_state(client, request, params, query); + return get_state(client, request, query); } resource::response get_state(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id, const string_view &type) { @@ -207,33 +197,29 @@ get_state(client &client, { "type", type } }; - return get_state(client, request, params, query); + return get_state(client, request, query); } resource::response get_state(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id) { - string_view token[4]; - tokens(params, "/", token); - const string_view &type { - token[2] + request.parv[2] }; const string_view &state_key { - token[3] + request.parv[3] }; if(type && state_key) - return get_state(client, request, params, room_id, type, state_key); + return get_state(client, request, room_id, type, state_key); if(type) - return get_state(client, request, params, room_id, type); + return get_state(client, request, room_id, type); const m::event::query query { @@ -241,18 +227,17 @@ get_state(client &client, { "state_key", "" }, }; - return get_state(client, request, params, query); + return get_state(client, request, query); } resource::response get_context(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id) { const m::event::id &event_id { - token(params, '/', 2) + request.parv[2] }; const auto it @@ -280,35 +265,35 @@ get_context(client &client, resource::response get_rooms(client &client, const resource::request &request) { - const auto params - { - lstrip(request.head.path, room::base_url) - }; - - string_view token[2]; - if(tokens(params, '/', token) != 2) - throw m::BAD_REQUEST{"/rooms command required"}; + if(request.parv.size() != 2) + throw m::error + { + http::MULTIPLE_CHOICES, "/rooms command required" + }; m::room::id::buf room_id { - urldecode(token[0], room_id) + urldecode(request.parv[0], room_id) }; - const string_view &cmd{token[1]}; + const string_view &cmd{request.parv[1]}; if(cmd == "context") - return get_context(client, request, params, room_id); + return get_context(client, request, room_id); if(cmd == "state") - return get_state(client, request, params, room_id); + return get_state(client, request, room_id); if(cmd == "members") - return get_members(client, request, params, room_id); + return get_members(client, request, room_id); if(cmd == "messages") - return get_messages(client, request, params, room_id); + return get_messages(client, request, room_id); - throw m::NOT_FOUND{"/rooms command not found"}; + throw m::NOT_FOUND + { + "/rooms command not found" + }; } resource::method method_get @@ -319,20 +304,16 @@ resource::method method_get resource::response put_send(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id) { - string_view token[4]; - tokens(params, '/', token); - const string_view &type { - token[2] + request.parv[2] }; const string_view &txnid { - token[3] + request.parv[3] }; json::iov event; @@ -374,27 +355,21 @@ put_send(client &client, resource::response put_rooms(client &client, const resource::request &request) { - const auto params - { - lstrip(request.head.path, room::base_url) - }; - - string_view token[2]; - if(tokens(params, "/", token) != 2) + if(request.parv.size() != 2) throw m::BAD_REQUEST{"/rooms command required"}; - const m::room::id &room_id + m::room::id::buf room_id { - token[0] + urldecode(request.parv[0], room_id) }; const string_view &cmd { - token[1] + request.parv[1] }; if(cmd == "send") - return put_send(client, request, params, room_id); + return put_send(client, request, room_id); throw m::NOT_FOUND{"/rooms command not found"}; } @@ -410,42 +385,41 @@ resource::method method_put resource::response post_receipt(client &client, const resource::request &request, - const string_view ¶ms, const m::room::id &room_id) { - string_view token[4]; - if(tokens(params, '/', token) != 4) + if(request.parv.size() != 4) throw m::BAD_REQUEST{"receipt type and event_id required"}; - const string_view &receipt_type{token[2]}; - const string_view &event_id{token[3]}; + const string_view &receipt_type{request.parv[2]}; + const string_view &event_id{request.parv[3]}; std::cout << "type: " << receipt_type << " eid: " << event_id << std::endl; } resource::response -post_rooms(client &client, const resource::request &request) +post_rooms(client &client, + const resource::request &request) { - const auto params - { - lstrip(request.head.path, room::base_url) - }; - - string_view token[2]; - if(tokens(params, '/', token) != 2) + if(request.parv.size() != 2) throw m::BAD_REQUEST{"/rooms command required"}; - m::room::id::buf room_id; - urldecode(token[0], room_id); - const string_view &cmd{token[1]}; + m::room::id::buf room_id + { + urldecode(request.parv[0], room_id) + }; + + const string_view &cmd + { + request.parv[1] + }; if(cmd == "receipt") - return post_receipt(client, request, params, room_id); + return post_receipt(client, request, room_id); } -resource::method method_POST +resource::method method_post { rooms_resource, "POST", post_rooms, { - method_put.REQUIRES_AUTH + method_post.REQUIRES_AUTH } }; diff --git a/modules/client/sync.cc b/modules/client/sync.cc index 94ea6d4cd..ec2ec317e 100644 --- a/modules/client/sync.cc +++ b/modules/client/sync.cc @@ -35,7 +35,7 @@ to the state, and to receive new messages. resource sync_resource { - "_matrix/client/r0/sync", + "/_matrix/client/r0/sync", sync_description }; diff --git a/modules/client/user.cc b/modules/client/user.cc index 010602345..40bd278f5 100644 --- a/modules/client/user.cc +++ b/modules/client/user.cc @@ -23,7 +23,7 @@ using namespace ircd; resource user_resource { - "_matrix/client/r0/user", + "/_matrix/client/r0/user/", "User resource", { resource::DIRECTORY @@ -35,12 +35,12 @@ get_filter(client &client, const resource::request &request) { m::user::id::buf user_id { - urldecode(token(request.head.path, '/', 4), user_id) + urldecode(request.parv[4], user_id) }; - const auto filter_id + const auto &filter_id { - token(request.head.path, '/', 6) + request.parv[6] }; const m::event::query query @@ -74,11 +74,11 @@ get_filter(client &client, const resource::request &request) return {}; } -resource::method get +resource::method get_method { user_resource, "GET", get_filter, { - resource::method::REQUIRES_AUTH + get_method.REQUIRES_AUTH } }; @@ -91,7 +91,7 @@ post_filter(client &client, const resource::request::object &re // token must be authorized to make requests for this user id. m::user::id::buf user_id { - urldecode(token(request.head.path, '/', 4), user_id) + urldecode(request.parv[4], user_id) }; user_id.validate(); @@ -161,11 +161,11 @@ post_filter(client &client, const resource::request::object &re }; } -resource::method post +resource::method post_method { user_resource, "POST", post_filter, { - post.REQUIRES_AUTH + post_method.REQUIRES_AUTH } }; diff --git a/modules/client/versions.cc b/modules/client/versions.cc index bbd6e7cd9..95d00cf67 100644 --- a/modules/client/versions.cc +++ b/modules/client/versions.cc @@ -23,7 +23,7 @@ using namespace ircd; resource versions_resource { - "_matrix/client/versions", + "/_matrix/client/versions", "Gets the versions of the specification supported by the server (2.1)" }; diff --git a/modules/client/voip/turnserver.cc b/modules/client/voip/turnserver.cc index 0d140ee29..e7a499757 100644 --- a/modules/client/voip/turnserver.cc +++ b/modules/client/voip/turnserver.cc @@ -28,7 +28,7 @@ mapi::header IRCD_MODULE resource turnserver_resource { - "_matrix/client/r0/voip/turnServer", + "/_matrix/client/r0/voip/turnServer", "This API provides credentials for the client to use when initiating calls." "(11.3.3)" }; diff --git a/modules/key/server.cc b/modules/key/server.cc index c93fa722e..473c03cb6 100644 --- a/modules/key/server.cc +++ b/modules/key/server.cc @@ -29,16 +29,11 @@ mapi::header IRCD_MODULE struct server :resource { - static constexpr const auto base_url - { - "_matrix/key/v2/server/" - }; - using resource::resource; } server_resource { - server::base_url, resource::opts + "/_matrix/key/v2/server/", resource::opts { resource::DIRECTORY, "federation 2.2.1.1: Publishing Keys" @@ -52,11 +47,11 @@ handle_get(client &client, char key_id_buf[256]; const auto key_id { - urldecode(split(request.head.path, server_resource.base_url).second, key_id_buf) + urldecode(request.parv[0], key_id_buf) }; std::string my_key; - m::keys::get(my_host(), [&my_key](const auto &key) + m::keys::get(my_host(), key_id, [&my_key](const auto &key) { my_key = json::string(key); });