diff --git a/src/client.hpp b/src/client.hpp index bb5ab0b46e7601aeaa79876b3dc45866ecb999d8..4e46cc856b60bb759c76b93638bee4b046f87261 100644 --- a/src/client.hpp +++ b/src/client.hpp @@ -299,34 +299,6 @@ private: } } -template<class T> -inline T -deserialize(const std::string &data) -{ - return json::parse(data); -} - -template<> -inline std::string -deserialize<std::string>(const std::string &data) -{ - return data; -} - -template<class T> -inline std::string -serialize(const T &obj) -{ - return json(obj).dump(); -} - -template<> -inline std::string -serialize<std::string>(const std::string &obj) -{ - return obj; -} - template<class Request, class Response> void mtx::client::Client::post(const std::string &endpoint, @@ -342,15 +314,8 @@ mtx::client::Client::post(const std::string &endpoint, return; setup_auth(session.get(), requires_auth); - - session->request.method(boost::beast::http::verb::post); - session->request.target("/_matrix" + endpoint); - session->request.set(boost::beast::http::field::user_agent, "mtxclient v0.1.0"); - session->request.set(boost::beast::http::field::content_type, content_type); - session->request.set(boost::beast::http::field::accept_encoding, "gzip,deflate"); - session->request.set(boost::beast::http::field::host, session->host); - session->request.body() = serialize<Request>(req); - session->request.prepare_payload(); + setup_headers<Request, boost::beast::http::verb::post>( + session.get(), req, endpoint, content_type); do_request(std::move(session)); } @@ -370,15 +335,8 @@ mtx::client::Client::put(const std::string &endpoint, return; setup_auth(session.get(), requires_auth); - - session->request.method(boost::beast::http::verb::put); - session->request.target("/_matrix" + endpoint); - session->request.set(boost::beast::http::field::user_agent, "mtxclient v0.1.0"); - session->request.set(boost::beast::http::field::content_type, "application/json"); - session->request.set(boost::beast::http::field::accept_encoding, "gzip,deflate"); - session->request.set(boost::beast::http::field::host, session->host); - session->request.body() = serialize<Request>(req); - session->request.prepare_payload(); + setup_headers<Request, boost::beast::http::verb::put>( + session.get(), req, endpoint, "application/json"); do_request(std::move(session)); } @@ -410,13 +368,7 @@ mtx::client::Client::get(const std::string &endpoint, return; setup_auth(session.get(), requires_auth); - - session->request.method(boost::beast::http::verb::get); - session->request.target("/_matrix" + endpoint); - session->request.set(boost::beast::http::field::user_agent, "mtxclient v0.1.0"); - session->request.set(boost::beast::http::field::accept_encoding, "gzip,deflate"); - session->request.set(boost::beast::http::field::host, session->host); - session->request.prepare_payload(); + setup_headers<std::string, boost::beast::http::verb::get>(session.get(), {}, endpoint); do_request(std::move(session)); } @@ -454,7 +406,7 @@ mtx::client::Client::create_session(HeadersCallback<Response> callback) // Try to parse the response in case we have an endpoint that // doesn't return an error struct for non 200 requests. try { - response_data = deserialize<Response>(body); + response_data = utils::deserialize<Response>(body); } catch (const nlohmann::json::exception &e) { } @@ -475,7 +427,7 @@ mtx::client::Client::create_session(HeadersCallback<Response> callback) // If we reach that point we most likely have a valid output from the // homeserver. try { - callback(deserialize<Response>(body), header, {}); + callback(utils::deserialize<Response>(body), header, {}); } catch (const nlohmann::json::exception &e) { client_error.parse_error = std::string(e.what()) + ": " + body; callback(response_data, header, client_error); diff --git a/src/session.hpp b/src/session.hpp index adbc48dccf80fff19db031a36ad68267048f6188..ee03e1f814c1cdd227602486d067b767b201dbb2 100644 --- a/src/session.hpp +++ b/src/session.hpp @@ -4,6 +4,8 @@ #include <boost/asio/ssl.hpp> #include <boost/beast.hpp> +#include "utils.hpp" + namespace mtx { namespace client { @@ -59,5 +61,25 @@ struct Session //! Function to be called when the request fails. FailureCallback on_failure; }; + +template<class Request, boost::beast::http::verb HttpVerb> +void +setup_headers(mtx::client::Session *session, + const Request &req, + const std::string &endpoint, + const std::string &content_type = "") +{ + session->request.set(boost::beast::http::field::user_agent, "mtxclient v0.1.0"); + session->request.set(boost::beast::http::field::accept_encoding, "gzip,deflate"); + session->request.set(boost::beast::http::field::host, session->host); + + session->request.method(HttpVerb); + session->request.target("/_matrix" + endpoint); + session->request.body() = utils::serialize(req); + session->request.prepare_payload(); + + if (!content_type.empty()) + session->request.set(boost::beast::http::field::content_type, content_type); +} } } diff --git a/src/utils.hpp b/src/utils.hpp index 0499b0981d6aab054e0a5d0a6e88e9e5763e67a7..5fd4419d1239edcf599b6820246410af34830e50 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -4,6 +4,8 @@ #include <iosfwd> #include <map> +#include <json.hpp> + namespace mtx { namespace client { namespace utils { @@ -19,6 +21,34 @@ query_params(const std::map<std::string, std::string> ¶ms) noexcept; //! Decompress a response. std::string decompress(const boost::iostreams::array_source &src, const std::string &type) noexcept; + +template<class T> +inline T +deserialize(const std::string &data) +{ + return nlohmann::json::parse(data); +} + +template<> +inline std::string +deserialize<std::string>(const std::string &data) +{ + return data; +} + +template<class T> +inline std::string +serialize(const T &obj) +{ + return nlohmann::json(obj).dump(); +} + +template<> +inline std::string +serialize<std::string>(const std::string &obj) +{ + return obj; +} } } }