Loading client/client.cpp +85 −10 Changes for client/client.cpp: 85 added lines, 10 removed lines. Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <algorithm> #include <cstring> #include <memory> #include <cctype> #include <json.h> #include <json_object.h> Loading @@ -44,6 +45,68 @@ namespace authdb { namespace client { namespace { std::string normalize_path(std::string path) { if (path.empty()) return "/"; // Strip scheme/host if someone passes a full URL by mistake. if (path.rfind("http://", 0) == 0 || path.rfind("https://", 0) == 0) { size_t slash = path.find('/', path.find("//") + 2); path = (slash == std::string::npos) ? "/" : path.substr(slash); } // Remove query/fragment from the path only. size_t cut = path.find_first_of("?#"); if (cut != std::string::npos) { path.erase(cut); } if (path.empty()) return "/"; if (path.front() != '/') path.insert(path.begin(), '/'); return path; } std::string extract_path_from_url(const std::string& url) { size_t start = 0; size_t scheme = url.find("://"); if (scheme != std::string::npos) { start = scheme + 3; } size_t slash = url.find('/', start); if (slash == std::string::npos) { return "/"; } return normalize_path(url.substr(slash)); } std::string extract_location_from_message(const std::string& msg) { std::string lower; lower.reserve(msg.size()); for (char ch : msg) { lower.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(ch)))); } const std::string key = "location:"; size_t pos = lower.find(key); if (pos == std::string::npos) return {}; size_t val_start = pos + key.size(); while (val_start < msg.size() && (msg[val_start] == ' ' || msg[val_start] == '\t')) { ++val_start; } size_t val_end = msg.find_first_of("\r\n", val_start); if (val_end == std::string::npos) val_end = msg.size(); std::string location = msg.substr(val_start, val_end - val_start); // Trim trailing spaces/tabs while (!location.empty() && (location.back() == ' ' || location.back() == '\t')) { location.pop_back(); } return location; } } // -------- ClientConnection -------- ClientConnection::ClientConnection() : _Client(nullptr) {} Loading @@ -56,10 +119,22 @@ void ClientConnection::reConnect() { void ClientConnection::setUrl(const libhttppp::HttpUrl& url) { _Url = url; _RequestPath = normalize_path(_Url.getPath()); if (_Client) { _Client = std::make_unique<libhttppp::HttpClient>(_Url); } } void ClientConnection::setUrl(const std::string& url) { _Url = libhttppp::HttpUrl(url.c_str()); std::string path = _Url.getPath(); if (path.empty() || path == "/") { path = extract_path_from_url(url); } _RequestPath = normalize_path(path); if (_Client) { _Client = std::make_unique<libhttppp::HttpClient>(_Url); } } void ClientConnection::setClientName(const std::string& name) { Loading Loading @@ -124,7 +199,7 @@ bool Client::ClientAuth() { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -187,7 +262,7 @@ bool Client::UserAuth() { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -252,7 +327,7 @@ void Client::SessionInfo(class SessionData& sdat) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -320,7 +395,7 @@ bool Client::remSession() { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -386,7 +461,7 @@ void Client::changeUserPw(const std::string& oldpw, const std::string& newpw) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); // Optionally: parse response if you care json_object_put(jresponse); Loading Loading @@ -434,7 +509,7 @@ bool Client::GPOcheck(class ::uuid::uuid gpoid) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -498,7 +573,7 @@ void Client::addConnection(const std::string& clientname, const std::string& clt libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); json_object_put(jresponse); Loading Loading @@ -530,7 +605,7 @@ void Client::remConnection(const uuid::uuid& clientid) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); json_object_put(jresponse); Loading Loading @@ -566,7 +641,7 @@ void Client::editConnection(const uuid::uuid& clientid, libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); json_object_put(jresponse); Loading Loading @@ -596,7 +671,7 @@ bool Client::GPOexits(class uuid::uuid gpoid) { // keeping name for compatibilit libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading client/client.h +5 −0 Changes for client/client.h: 5 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <string> #include <memory> #include <vector> #include <uuidp.h> #ifndef Windows Loading Loading @@ -82,11 +83,15 @@ namespace authdb { std::string _CltSecret; std::string _UserName; std::string _UserPassword; std::string _RequestPath; std::unique_ptr<libhttppp::HttpClient> _Client; uuid::uuid _SessionID; uuid::uuid _ClientId; friend inline void ensure_http_client(ClientConnection& con); friend std::vector<char> post_with_redirect(ClientConnection& con, libhttppp::HttpRequest& req, const std::vector<char>& out); friend class Client; }; Loading Loading
client/client.cpp +85 −10 Changes for client/client.cpp: 85 added lines, 10 removed lines. Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <algorithm> #include <cstring> #include <memory> #include <cctype> #include <json.h> #include <json_object.h> Loading @@ -44,6 +45,68 @@ namespace authdb { namespace client { namespace { std::string normalize_path(std::string path) { if (path.empty()) return "/"; // Strip scheme/host if someone passes a full URL by mistake. if (path.rfind("http://", 0) == 0 || path.rfind("https://", 0) == 0) { size_t slash = path.find('/', path.find("//") + 2); path = (slash == std::string::npos) ? "/" : path.substr(slash); } // Remove query/fragment from the path only. size_t cut = path.find_first_of("?#"); if (cut != std::string::npos) { path.erase(cut); } if (path.empty()) return "/"; if (path.front() != '/') path.insert(path.begin(), '/'); return path; } std::string extract_path_from_url(const std::string& url) { size_t start = 0; size_t scheme = url.find("://"); if (scheme != std::string::npos) { start = scheme + 3; } size_t slash = url.find('/', start); if (slash == std::string::npos) { return "/"; } return normalize_path(url.substr(slash)); } std::string extract_location_from_message(const std::string& msg) { std::string lower; lower.reserve(msg.size()); for (char ch : msg) { lower.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(ch)))); } const std::string key = "location:"; size_t pos = lower.find(key); if (pos == std::string::npos) return {}; size_t val_start = pos + key.size(); while (val_start < msg.size() && (msg[val_start] == ' ' || msg[val_start] == '\t')) { ++val_start; } size_t val_end = msg.find_first_of("\r\n", val_start); if (val_end == std::string::npos) val_end = msg.size(); std::string location = msg.substr(val_start, val_end - val_start); // Trim trailing spaces/tabs while (!location.empty() && (location.back() == ' ' || location.back() == '\t')) { location.pop_back(); } return location; } } // -------- ClientConnection -------- ClientConnection::ClientConnection() : _Client(nullptr) {} Loading @@ -56,10 +119,22 @@ void ClientConnection::reConnect() { void ClientConnection::setUrl(const libhttppp::HttpUrl& url) { _Url = url; _RequestPath = normalize_path(_Url.getPath()); if (_Client) { _Client = std::make_unique<libhttppp::HttpClient>(_Url); } } void ClientConnection::setUrl(const std::string& url) { _Url = libhttppp::HttpUrl(url.c_str()); std::string path = _Url.getPath(); if (path.empty() || path == "/") { path = extract_path_from_url(url); } _RequestPath = normalize_path(path); if (_Client) { _Client = std::make_unique<libhttppp::HttpClient>(_Url); } } void ClientConnection::setClientName(const std::string& name) { Loading Loading @@ -124,7 +199,7 @@ bool Client::ClientAuth() { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -187,7 +262,7 @@ bool Client::UserAuth() { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -252,7 +327,7 @@ void Client::SessionInfo(class SessionData& sdat) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -320,7 +395,7 @@ bool Client::remSession() { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -386,7 +461,7 @@ void Client::changeUserPw(const std::string& oldpw, const std::string& newpw) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); // Optionally: parse response if you care json_object_put(jresponse); Loading Loading @@ -434,7 +509,7 @@ bool Client::GPOcheck(class ::uuid::uuid gpoid) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading Loading @@ -498,7 +573,7 @@ void Client::addConnection(const std::string& clientname, const std::string& clt libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); json_object_put(jresponse); Loading Loading @@ -530,7 +605,7 @@ void Client::remConnection(const uuid::uuid& clientid) { libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); json_object_put(jresponse); Loading Loading @@ -566,7 +641,7 @@ void Client::editConnection(const uuid::uuid& clientid, libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); (void)_Con._Client->Post(nreq, out); json_object_put(jresponse); Loading Loading @@ -596,7 +671,7 @@ bool Client::GPOexits(class uuid::uuid gpoid) { // keeping name for compatibilit libhttppp::HttpRequest nreq; nreq.setHeaderData("accept")->push_back("application/json"); nreq.setHeaderData("content-type")->push_back("application/json"); nreq.setRequestURL(_Con._Url.getPath().c_str()); nreq.setRequestURL(_Con._RequestPath.c_str()); std::vector<char> resp(_Con._Client->Post(nreq, out)); resp.push_back('\0'); Loading
client/client.h +5 −0 Changes for client/client.h: 5 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <string> #include <memory> #include <vector> #include <uuidp.h> #ifndef Windows Loading Loading @@ -82,11 +83,15 @@ namespace authdb { std::string _CltSecret; std::string _UserName; std::string _UserPassword; std::string _RequestPath; std::unique_ptr<libhttppp::HttpClient> _Client; uuid::uuid _SessionID; uuid::uuid _ClientId; friend inline void ensure_http_client(ClientConnection& con); friend std::vector<char> post_with_redirect(ClientConnection& con, libhttppp::HttpRequest& req, const std::vector<char>& out); friend class Client; }; Loading