#include "stdafx.h" #include "CNetWork.h" #include #include #include "Logger.h" CNetWork::CNetWork() : m_http_ret(HTTPRET::http_f) { initSessionPool(100); } CNetWork::~CNetWork(void) { DestoryOneConnSessionPool(); } int CNetWork::GetHttpStatus() { return m_http_status; } HTTPRET CNetWork::GetloginByUrl(LPCSTR key,std::string & data) { std::vector p; p.push_back({ "redirect", "dashboard"}); p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() }); p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() }); std::string text = PostUrl("/api/v1/manage/auth/getQuickLoginUrl", p, ""); if (text.empty()) { return HTTPRET::http_f; } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::GetMySub(std::string& data) { std::vector p; p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() }); p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() }); std::string text = GetUrl("/api/v1/manager/getSubscribe", p, ""); if (text.empty()) { return HTTPRET::http_f; } data = text.c_str(); return HTTPRET::http_yes; return HTTPRET(); } void CNetWork::SetUrlArray(std::vector data) { m_url_list = data; } HTTPRET CNetWork::Version(std::string& data) { std::vector p; p.push_back({ "from","win" }); p.push_back({ "version",S_CW2A(VERSION).GetBuffer(0) }); p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() }); p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() }); std::string text = PostUrl("/api/v1/manage/app/getVersion", p, ""); if (text.empty()) { return HTTPRET::http_f; } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::Refresh(std::string& data) { std::vector p; std::string text = GetUrl("/api/client/v3/refresh", p, CApp::getSingletonPtr()->GetLoginInfo()->token); if (text.empty()) { return HTTPRET::http_f; } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::Auth(std::string& data){ std::vector p; std::string text = GetUrl("/api/client/v3/authUser",p,CApp::getSingletonPtr()->GetLoginInfo()->token); if (text.empty()) { return HTTPRET::http_f; } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::GetServerNode(std::string& data) { std::vector p; p.push_back({ "token", CApp::getSingletonPtr()->GetLoginInfo()->token.c_str() }); p.push_back({ "auth_data", CApp::getSingletonPtr()->GetLoginInfo()->auth_data.c_str() }); std::string text = GetUrl("/api/v1/manager/server/fetch",p,""); if (text.empty()) { return HTTPRET::http_f; } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::GetSysConfig(std::string& data) { AutoToggleNode(); std::vector p; std::string text = GetUrl("/api/v1/manage/getUrl", p); if (text.empty()) { if (m_http_status == 445) { return HTTPRET::http_user_expired_at; } else if (m_http_status == 446) { return HTTPRET::http_user_transfer_enable; } else { return HTTPRET::http_f; } } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::PostReg(LPCSTR username, LPCSTR password, std::string& data) { std::vector p; p.push_back({ "username",""}); p.push_back({ "email",username }); p.push_back({ "password",password }); std::string text = PostUrl("/api/client/v2/register", p); if (text.empty()) { if (m_http_status == 445) { return HTTPRET::http_user_expired_at; } else if (m_http_status == 446) { return HTTPRET::http_user_transfer_enable; } else if (m_http_status == 447) { return HTTPRET::http_user_enable; } else { return HTTPRET::http_f; } } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::PostLogin(LPCSTR username, LPCSTR password, std::string& data) { std::vector p; p.push_back({ "email",username }); p.push_back({ "password",password }); std::string text = PostUrl("/api/v1/manage/auth/login/", p); if (text.empty()) { if (m_http_status == 445) { return HTTPRET::http_user_expired_at; } else if (m_http_status == 446) { return HTTPRET::http_user_transfer_enable; } else if (m_http_status == 447) { return HTTPRET::http_user_enable; } else { return HTTPRET::http_f; } } data = text.c_str(); return HTTPRET::http_yes; } HTTPRET CNetWork::GetSysConfigFromUser(LPCSTR username, LPCSTR password, std::string& data) { std::vector p; p.push_back({ "email",username }); p.push_back({ "password",password }); std::string text = GetUrl("/api/client/v3/getconfig", p); if (text.empty()) { if (m_http_status == 445) { return HTTPRET::http_user_expired_at; } else if (m_http_status == 446) { return HTTPRET::http_user_transfer_enable; } else { return HTTPRET::http_f; } } data = text.c_str(); return HTTPRET::http_yes; } void CNetWork::SetUrl(LPCSTR url) { m_url = url; } void CNetWork::initSessionPool(int szie) { for (int i = 0 ; i < szie ; i++) { std::shared_ptr pp = std::make_shared(); m_session_vect.push_back(std::move(pp)); } } void CNetWork::DestoryOneConnSessionPool() { for (auto &conn : m_session_vect) { std::move(m_session_vect.front()); } } std::shared_ptr CNetWork::GetSession() { std::shared_ptr pp = nullptr; m_mutx.lock(); if (m_session_vect.size() > 0) { pp = m_session_vect.front(); m_session_vect.pop_back(); } m_mutx.unlock(); /*if (pp == nullptr) { pp = std::make_shared(); }*/ return pp; } void CNetWork::pullSession(std::shared_ptr &p) { m_mutx.lock(); m_session_vect.push_back(p); m_mutx.unlock(); } SStringA CNetWork::GetLastErrorA() { return SStringA().Format("%s", m_error_msg.c_str()).GetBuffer(0); } SStringW CNetWork::GetLastErrorW() { return S_CA2W(m_error_msg.c_str(),CP_UTF8).GetBuffer(0); } std::string CNetWork::GetUrl(std::string path, std::vector parame,std::string token) { cpr::Parameters ps; std::vector::iterator it_i; for (it_i = parame.begin(); it_i != parame.end(); ++it_i) { ps.Add(*it_i); //ps(cpr::Parameter({ it->first, it->second })); } cpr::Header hander; if (!token.empty()) { hander = cpr::Header{ {"accept", "application/json"} , {"Authorization", "bearer " + token} }; } else { hander = cpr::Header{ {"accept", "application/json"} }; } cpr::Response r; std::string res_test = ""; //auto session = GetSession(); int count = 3; /*int serverurlid = 0;*/ do { if (count <= 0) { break; } auto s = fmt::format("{0}{1}", m_url, path.c_str()); if (parame.empty()) { m_session.SetHeader(hander); m_session.SetVerifySsl(false); m_session.SetTimeout(cpr::Timeout{TIMEOUTE}); m_session.SetUrl(s.c_str()); //session->SetDebugCallback() r = m_session.Get(); //r = cpr::Get(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, hander, cpr::Timeout{ 60 * 1000 }); } else { m_session.SetHeader(hander); m_session.SetVerifySsl(false); m_session.SetTimeout(cpr::Timeout{ TIMEOUTE }); m_session.SetUrl(s.c_str()); m_session.SetParameters(ps); r = m_session.Get(); //r = cpr::Get(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, ps, hander, cpr::Timeout{ 60 * 1000 }); } if (r.status_code == 200 || r.status_code == 201) { res_test = r.text; break; } else { m_http_status = r.status_code; if (r.error.message.empty()) { m_error_msg = r.status_line; } else { m_error_msg = UpdateError(r.error.code, r.error.message); } } if (!res_test.empty()) { break; } Sleep(3000); count--; Logger::getSingletonPtr()->INFO("get 重试" + std::to_string(count) + "次数"); } while (res_test.empty()); //pullSession(session); return res_test; } std::string CNetWork::PostUrl(std::string path, std::vector parame, std::string token) { auto s = fmt::format("{0}{1}", m_url, path.c_str()); cpr::Header hander; if (!token.empty()) { hander = cpr::Header{ {"accept", "application/json"} , {"Authorization", "bearer " + token} }; } else { hander = cpr::Header{ {"accept", "application/json"} }; } cpr::Response r; std::string res_test = ""; /** * \brief * \param * \param * \param * \return */ int count = 3; do { if (count <= 0) { break; } if (parame.empty()) { //r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::VerifySsl{false}, cpr::Timeout{ 60 * 1000 }); m_session.SetHeader(hander); m_session.SetVerifySsl(false); m_session.SetTimeout(cpr::Timeout{ TIMEOUTE }); m_session.SetUrl(s.c_str()); r = m_session.Get(); } else { m_session.SetHeader(hander); m_session.SetVerifySsl(false); m_session.SetTimeout(cpr::Timeout{ TIMEOUTE }); m_session.SetUrl(s.c_str()); m_session.SetPayload(cpr::Payload{ parame.begin(),parame.end() }); r = m_session.Post(); //r = cpr::Post(cpr::Url{ s.c_str() }, cpr::VerifySsl{ false }, cpr::Payload{ parame.begin(),parame.end() }, hander, cpr::Timeout{ 60 * 1000 }); } //Logger::getSingletonPtr()->DEBUG(r.url.c_str()); if (r.status_code == 200 || r.status_code == 201) { res_test = std::move(r.text); break; } else { m_http_status = r.status_code; if (r.error.message.empty()) { m_error_msg = r.status_line; } else { m_error_msg = UpdateError(r.error.code, r.error.message); } } if (!res_test.empty()) { break; } Logger::getSingletonPtr()->INFO("重试" + std::to_string(count) + "次数"); count--; } while (res_test.empty()); //pullSession(session); return res_test; } void CNetWork::AutoToggleNode() { cpr::Header hander; hander = cpr::Header{ {"accept", "application/json"} }; std::vector p; p.push_back({ "tag","win" }); p.push_back({ "appverion",S_CW2A(VERSION).GetBuffer(0) }); cpr::Parameters ps; std::vector::iterator it_i; for (it_i = p.begin(); it_i != p.end(); ++it_i) { ps.Add(*it_i); //ps(cpr::Parameter({ it->first, it->second })); } //m_url_list.reserve(m_url.size()); //切换节点, for each (ServerListUrl itme in m_url_list) { cpr::Session m_session; auto s = fmt::format("{0}{1}", itme.url, "/api/v1/manage/getUrl"); m_session.SetHeader(hander); m_session.SetVerifySsl(false); m_session.SetTimeout(cpr::Timeout{ TIMEOUTE }); m_session.SetUrl(s.c_str()); m_session.SetParameters(ps); auto r = m_session.Get(); if (r.status_code != 200) { continue; } else { if (m_url != itme.url) { m_url = itme.url; Logger::getSingletonPtr()->INFO(S_CW2A(itme.name).GetBuffer(0)); } break; } } } std::string CNetWork::Retrying(std::string path, std::vector parame, std::string token) { std::string res_test = ""; int count = 3; do { if (count <= 0) { break; } res_test = GetUrl(path, parame, token); if (!res_test.empty()) { break; } count--; } while (res_test.empty()); return res_test; } bool write_data(std::string /*data*/, intptr_t /*userdata*/) { return true; } bool CNetWork::Download(std::string path) { //return false; std::string configdir = std::filesystem::current_path().string() + "\\" + S_CW2A(CLASH_ASSETS_DIR_NAME).GetBuffer(0); std::filesystem::path p(configdir); if (!std::filesystem::exists(p)) { std::filesystem::create_directory(p); } std::string configname = configdir + "\\" + CLASHCONFIGDIR; std::ofstream ofs(configname); cpr::Url url{ path }; cpr::Session session; session.SetUrl(url); cpr::Response response = session.Download(ofs); return response.status_code == 200; } void CNetWork::Init() { } void CNetWork::UnInit() { } std::string CNetWork::UpdateError(cpr::ErrorCode code, std::string msg) { if (code == cpr::ErrorCode::HOST_RESOLUTION_FAILURE) { m_error_msg = "解析域名失败"; } else if (code == cpr::ErrorCode::OPERATION_TIMEDOUT) { m_error_msg = "请求数据超时,请重新请求"; } else if (code == cpr::ErrorCode::CONNECTION_FAILURE) { m_error_msg = "发送服务器失败"; } else if (code == cpr::ErrorCode::INVALID_URL_FORMAT) { m_error_msg = "未知URL错误"; } else if (code == cpr::ErrorCode::SSL_CONNECT_ERROR) { m_error_msg = "SSL连接错误"; } else { m_error_msg = msg; } return m_error_msg; }