// 独立测试程序 - 不依赖外部库 // 使用Windows原生WinHTTP进行HTTP请求 #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #include #pragma comment(lib, "winhttp.lib") #else #include #include #include #include #endif #include "json.hpp" #include #include #include #include #include using json = nlohmann::json; // ============================================================================ // WinHTTP客户端 // ============================================================================ class HttpClient { public: HttpClient() { #ifdef _WIN32 hSession_ = WinHttpOpen(L"VerifySDK/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); #endif } ~HttpClient() { #ifdef _WIN32 if (hConnect_) WinHttpCloseHandle(hConnect_); if (hSession_) WinHttpCloseHandle(hSession_); #endif } std::string get(const std::string& url) { return request(url, "GET", ""); } std::string post(const std::string& url, const std::string& body) { return request(url, "POST", body); } private: #ifdef _WIN32 HINTERNET hSession_ = nullptr; HINTERNET hConnect_ = nullptr; #endif std::string request(const std::string& url, const std::string& method, const std::string& body) { std::string result; #ifdef _WIN32 // 解析URL std::wstring wurl(url.begin(), url.end()); URL_COMPONENTS uc = { sizeof(uc) }; wchar_t host[256] = {0}; wchar_t path[1024] = {0}; uc.lpszHostName = host; uc.dwHostNameLength = 256; uc.lpszUrlPath = path; uc.dwUrlPathLength = 1024; if (!WinHttpCrackUrl(wurl.c_str(), 0, 0, &uc)) { throw std::runtime_error("Failed to parse URL"); } // 连接服务器 std::wstring whost(host); hConnect_ = WinHttpConnect(hSession_, whost.c_str(), uc.nPort, 0); if (!hConnect_) { throw std::runtime_error("Failed to connect to server"); } // 创建请求 std::wstring wpath(path); std::wstring wmethod(method.begin(), method.end()); DWORD flags = (uc.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0; HINTERNET hRequest = WinHttpOpenRequest(hConnect_, wmethod.c_str(), wpath.c_str(), nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, flags); if (!hRequest) { throw std::runtime_error("Failed to create request"); } // 发送请求 LPCWSTR headers = L"Content-Type: application/json\r\n"; BOOL bResult = WinHttpSendRequest(hRequest, headers, -1, (LPVOID)body.c_str(), body.length(), body.length(), 0); if (!bResult) { WinHttpCloseHandle(hRequest); throw std::runtime_error("Failed to send request"); } // 接收响应 bResult = WinHttpReceiveResponse(hRequest, nullptr); if (!bResult) { WinHttpCloseHandle(hRequest); throw std::runtime_error("Failed to receive response"); } // 读取数据 DWORD dwSize = 0; DWORD dwDownloaded = 0; do { dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) break; if (dwSize == 0) break; std::vector buffer(dwSize + 1); if (WinHttpReadData(hRequest, &buffer[0], dwSize, &dwDownloaded)) { result.append(buffer.data(), dwDownloaded); } } while (dwSize > 0); WinHttpCloseHandle(hRequest); #else // Linux实现(简化版) result = curl_request(url, method, body); #endif return result; } #ifndef _WIN32 std::string curl_request(const std::string& url, const std::string& method, const std::string& body) { // 简化的socket实现(仅用于演示) return "{\"code\": 200, \"message\": \"success\", \"data\": {}}"; } #endif }; // ============================================================================ // 验证客户端 // ============================================================================ class VerifyClient { public: VerifyClient(const std::string& baseUrl, const std::string& appKey) : baseUrl_(baseUrl), appKey_(appKey) { // 移除末尾斜杠 if (!baseUrl_.empty() && baseUrl_.back() == '/') { baseUrl_.pop_back(); } } void setToken(const std::string& token) { token_ = token; } // 获取应用信息 json getAppInfo() { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/info"; std::string response = http_.get(url); return json::parse(response); } // 检查更新 json checkUpdate(const std::string& version = "") { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/check-update"; if (!version.empty()) { url += "?version=" + version; } std::string response = http_.get(url); return json::parse(response); } // 用户登录 json login(const std::string& username, const std::string& password, const std::string& deviceId) { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/login"; json body; body["username"] = username; body["password"] = password; body["device_id"] = deviceId; std::string response = http_.post(url, body.dump()); json result = json::parse(response); // 自动设置token if (result["code"].get_int() == 200 && result["data"].contains("token")) { token_ = result["data"]["token"].get_string(); } return result; } // 用户注册 json registerUser(const std::string& username, const std::string& password, const std::string& deviceId) { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/register"; json body; body["username"] = username; body["password"] = password; body["device_id"] = deviceId; std::string response = http_.post(url, body.dump()); return json::parse(response); } // 心跳 json heartbeat(uint64_t userId, const std::string& deviceId, const std::string& instanceId = "") { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/heartbeat"; json body; body["user_id"] = userId; body["device_id"] = deviceId; if (!instanceId.empty()) { body["instance_id"] = instanceId; } std::string response = http_.post(url, body.dump()); return json::parse(response); } // 卡密充值 json recharge(const std::string& username, const std::string& cardKey, const std::string& deviceId) { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/recharge"; json body; body["username"] = username; body["card_key"] = cardKey; body["device_id"] = deviceId; std::string response = http_.post(url, body.dump()); return json::parse(response); } // 获取设备列表 json getDevices() { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/devices"; std::string response = http_.get(url); return json::parse(response); } // 获取云端变量 json getVariables() { std::string url = baseUrl_ + "/api/v1/app/" + appKey_ + "/variables"; std::string response = http_.get(url); return json::parse(response); } private: std::string baseUrl_; std::string appKey_; std::string token_; HttpClient http_; }; // ============================================================================ // 测试函数 // ============================================================================ void printSeparator(const std::string& title) { std::cout << "\n"; std::cout << "========================================\n"; std::cout << title << "\n"; std::cout << "========================================\n"; } void testJson() { printSeparator("JSON功能测试"); // 创建JSON对象 json obj = json::object(); obj["name"] = "测试应用"; obj["version"] = "1.0.0"; obj["active"] = true; obj["count"] = 100; std::cout << "[创建对象] "; std::cout << obj.dump() << "\n"; // 创建数组 json arr = json::array(); arr.push_back("item1"); arr.push_back("item2"); arr.push_back(123); std::cout << "[创建数组] "; std::cout << arr.dump() << "\n"; // 解析JSON std::string jsonStr = R"({"code":200,"message":"success","data":{"user_id":1,"token":"abc123"}})"; json parsed = json::parse(jsonStr); std::cout << "[解析结果]\n"; std::cout << " code: " << parsed["code"].get_int() << "\n"; std::cout << " message: " << parsed["message"].get_string() << "\n"; std::cout << " user_id: " << parsed["data"]["user_id"].get_uint64() << "\n"; std::cout << "\nJSON测试通过!\n"; } void testApi(const std::string& baseUrl, const std::string& appKey) { printSeparator("API测试"); std::cout << "服务器: " << baseUrl << "\n"; std::cout << "AppKey: " << appKey << "\n\n"; VerifyClient client(baseUrl, appKey); // 测试获取应用信息 std::cout << "[测试] 获取应用信息...\n"; try { json info = client.getAppInfo(); if (info["code"].get_int() == 200) { std::cout << " [成功] 应用名称: " << info["data"]["name"].get_string() << "\n"; std::cout << " [成功] 状态: " << info["data"]["status"].get_string() << "\n"; } else { std::cout << " [错误] " << info["message"].get_string() << "\n"; } } catch (const std::exception& e) { std::cout << " [异常] " << e.what() << "\n"; } // 测试检查更新 std::cout << "\n[测试] 检查更新...\n"; try { json update = client.checkUpdate("1.0.0"); if (update["code"].get_int() == 200) { std::cout << " [成功] 最新版本: " << update["data"]["latest_version"].get_string() << "\n"; std::cout << " [成功] 有更新: " << (update["data"]["has_update"].get_bool() ? "是" : "否") << "\n"; } else { std::cout << " [错误] " << update["message"].get_string() << "\n"; } } catch (const std::exception& e) { std::cout << " [异常] " << e.what() << "\n"; } // 测试不存在的版本 std::cout << "\n[测试] 检查不存在的版本...\n"; try { json update = client.checkUpdate("99.99.99"); if (update["code"].get_int() == 200) { std::cout << " [意外成功]\n"; } else { std::cout << " [预期错误] " << update["message"].get_string() << "\n"; } } catch (const std::exception& e) { std::cout << " [预期异常] " << e.what() << "\n"; } // 测试登录 std::cout << "\n[测试] 用户登录...\n"; try { // 使用测试用户 json loginResult = client.login("test_cpp_user", "test123456", "cpp_test_device"); if (loginResult["code"].get_int() == 200) { std::cout << " [成功] 用户ID: " << loginResult["data"]["user_id"].get_uint64() << "\n"; std::cout << " [成功] Token已获取\n"; uint64_t userId = loginResult["data"]["user_id"].get_uint64(); // 测试心跳 std::cout << "\n[测试] 心跳上报...\n"; json heartbeat = client.heartbeat(userId, "cpp_test_device", "instance_001"); if (heartbeat["code"].get_int() == 200) { std::cout << " [成功] 心跳成功\n"; if (heartbeat["data"].contains("balance")) { std::cout << " [信息] 余额: " << heartbeat["data"]["balance"].get_double() << "\n"; } } } else { std::cout << " [错误] " << loginResult["message"].get_string() << "\n"; } } catch (const std::exception& e) { std::cout << " [异常] " << e.what() << "\n"; } // 测试卡密充值(预期失败) std::cout << "\n[测试] 卡密充值(无效卡密)...\n"; try { json recharge = client.recharge("admin", "invalid_card_key", "cpp_test_device"); if (recharge["code"].get_int() == 200) { std::cout << " [意外成功] 充值成功\n"; } else { std::cout << " [预期错误] " << recharge["message"].get_string() << "\n"; } } catch (const std::exception& e) { std::cout << " [预期异常] " << e.what() << "\n"; } } // ============================================================================ // 主函数 // ============================================================================ int main(int argc, char* argv[]) { std::cout << R"( ╔════════════════════════════════════════════════════════════╗ ║ 验证平台 SDK C++ 独立测试 ║ ║ Verify Platform SDK C++ Test ║ ╚════════════════════════════════════════════════════════════╝ )" << "\n"; // 配置 std::string baseUrl = "https://gendan.xyz"; std::string appKey = "your_app_key"; // 替换为实际的appKey // 解析命令行参数 for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; if (arg == "--help" || arg == "-h") { std::cout << "用法: " << argv[0] << " [选项]\n"; std::cout << "选项:\n"; std::cout << " --help, -h 显示帮助信息\n"; std::cout << " --url 设置服务器URL\n"; std::cout << " --key 设置应用密钥\n"; std::cout << " --json-only 仅测试JSON功能\n"; return 0; } else if (arg == "--url" && i + 1 < argc) { baseUrl = argv[++i]; } else if (arg == "--key" && i + 1 < argc) { appKey = argv[++i]; } else if (arg == "--json-only") { testJson(); return 0; } } try { // JSON测试 testJson(); // API测试 testApi(baseUrl, appKey); std::cout << "\n========================================\n"; std::cout << "所有测试完成!\n"; std::cout << "========================================\n"; } catch (const std::exception& e) { std::cerr << "\n错误: " << e.what() << "\n"; return 1; } return 0; }