#pragma once#include <string>
#include <map>
#include <vector>
#include <functional>
#include <memory>
#include <future>
#include <chrono>namespace HttpRequestUtil {// 前向声明class Interceptor;class Request;class Response;class HttpRequestImpl;// 请求方法枚举enum class Method {GET,POST,PUT,DELETE_,PATCH,HEAD,OPTIONS};// 重试配置结构struct RetryConfig {int maxRetries = 3; // 最大重试次数int retryDelay = 1000; // 重试间隔(毫秒)bool retryOnTimeout = true; // 超时时是否重试bool retryOnConnectionError = true; // 连接错误时是否重试bool retryOnServerError = false; // 服务器错误时是否重试std::function<bool(const Response&)> shouldRetry = nullptr; // 自定义重试条件};// 请求配置结构struct RequestConfig {std::string url;Method method = Method::GET;std::map<std::string, std::string> headers;std::string data; // 请求体数据std::map<std::string, std::string> params; // URL参数int timeout = 30000; // 超时时间(毫秒)bool followRedirects = true;int maxRedirects = 5;std::string userAgent = "HttpRequest/1.0";bool verifySSL = true;std::string proxy;std::string proxyAuth;RetryConfig retryConfig; // 重试配置};// 响应结构struct Response {int statusCode = 0;std::wstring statusText;std::map<std::wstring, std::wstring> headers;std::wstring data;std::wstring url;bool success = false;std::wstring error;// 便捷方法bool isOk() const { return statusCode >= 200 && statusCode < 300; }bool isRedirect() const { return statusCode >= 300 && statusCode < 400; }bool isClientError() const { return statusCode >= 400 && statusCode < 500; }bool isServerError() const { return statusCode >= 500 && statusCode < 600; }};// 拦截器接口class Interceptor {public:virtual ~Interceptor() = default;// 请求拦截器virtual bool onRequest(RequestConfig& config) = 0;// 响应拦截器virtual bool onResponse(Response& response) = 0;// 错误拦截器virtual bool onError(const std::wstring& error) = 0;};// 业务拦截器基类class BusinessInterceptor : public Interceptor {public:virtual ~BusinessInterceptor() = default;};// 通用拦截器基类class CommonInterceptor : public Interceptor {public:virtual ~CommonInterceptor() = default;};// 主HttpRequest类class HttpRequest {public:HttpRequest();~HttpRequest();// 禁用拷贝HttpRequest(const HttpRequest&) = delete;HttpRequest& operator=(const HttpRequest&) = delete;// 允许移动HttpRequest(HttpRequest&&) noexcept;HttpRequest& operator=(HttpRequest&&) noexcept;// 同步请求方法Response get(const std::string& url, const std::map<std::string, std::string>& params = {});Response post(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});Response put(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});Response delete_(const std::string& url, const std::map<std::string, std::string>& headers = {});Response patch(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});// 通用请求方法Response request(const RequestConfig& config);// 异步请求方法std::future<Response> getAsync(const std::string& url, const std::map<std::string, std::string>& params = {});std::future<Response> postAsync(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});std::future<Response> putAsync(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});std::future<Response> deleteAsync(const std::string& url, const std::map<std::string, std::string>& headers = {});std::future<Response> patchAsync(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});std::future<Response> requestAsync(const RequestConfig& config);// 拦截器管理void addInterceptor(std::shared_ptr<Interceptor> interceptor);void addBusinessInterceptor(std::shared_ptr<BusinessInterceptor> interceptor);void addCommonInterceptor(std::shared_ptr<CommonInterceptor> interceptor);void removeInterceptor(std::shared_ptr<Interceptor> interceptor);void clearInterceptors();// 全局配置void setDefaultTimeout(int timeout);void setDefaultHeaders(const std::map<std::string, std::string>& headers);void setUserAgent(const std::string& userAgent);void setProxy(const std::string& proxy, const std::string& auth = "");void setSSLVerification(bool verify);void setDefaultRetryConfig(const RetryConfig& retryConfig);// 便捷方法static std::string methodToString(Method method);static Method stringToMethod(const std::string& method);private:std::unique_ptr<HttpRequestImpl> pImpl;};// 全局便捷函数namespace http {// 创建HttpRequest实例std::shared_ptr<HttpRequest> create();// 静态便捷方法Response get(const std::string& url, const std::map<std::string, std::string>& params = {});Response post(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});Response put(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});Response delete_(const std::string& url, const std::map<std::string, std::string>& headers = {});Response patch(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});// 异步便捷方法std::future<Response> getAsync(const std::string& url, const std::map<std::string, std::string>& params = {});std::future<Response> postAsync(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});std::future<Response> putAsync(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});std::future<Response> deleteAsync(const std::string& url, const std::map<std::string, std::string>& headers = {});std::future<Response> patchAsync(const std::string& url, const std::string& data = "", const std::map<std::string, std::string>& headers = {});}} // namespace HttpRequest
实现文件:
#include "HttpRequest.h"
#include <windows.h>
#include <winhttp.h>
#include <sstream>
#include <algorithm>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <atomic>#pragma comment(lib, "winhttp.lib")namespace HttpRequestUtil {// 内部实现类class HttpRequestImpl {public:HttpRequestImpl() : defaultTimeout(30000), verifySSL(true) {// 初始化默认头defaultHeaders["User-Agent"] = "HttpRequest/1.0";defaultHeaders["Accept"] = "*/*";defaultHeaders["Accept-Encoding"] = "gzip, deflate";// 初始化默认重试配置defaultRetryConfig.maxRetries = 3;defaultRetryConfig.retryDelay = 1000;defaultRetryConfig.retryOnTimeout = true;defaultRetryConfig.retryOnConnectionError = true;defaultRetryConfig.retryOnServerError = false;}~HttpRequestImpl() = default;// 同步请求实现Response request(const RequestConfig& config) {RequestConfig finalConfig = config;// 应用默认配置if (finalConfig.timeout == 30000) {finalConfig.timeout = defaultTimeout;}// 应用默认重试配置if (finalConfig.retryConfig.maxRetries == 3 &&finalConfig.retryConfig.retryDelay == 1000) {finalConfig.retryConfig = defaultRetryConfig;}// 合并默认头for (const auto& header : defaultHeaders) {if (finalConfig.headers.find(header.first) == finalConfig.headers.end()) {finalConfig.headers[header.first] = header.second;}}// 运行请求拦截器runRequestInterceptors(finalConfig);// 执行带重试的请求Response response = performRequestWithRetry(finalConfig);// 运行响应拦截器runResponseInterceptors(response);return response;}// 异步请求实现std::future<Response> requestAsync(const RequestConfig& config) {return std::async(std::launch::async, [this, config]() {return this->request(config);});}// 拦截器管理void addInterceptor(std::shared_ptr<Interceptor> interceptor) {std::lock_guard<std::mutex> lock(interceptorsMutex);interceptors.push_back(interceptor);}void removeInterceptor(std::shared_ptr<Interceptor> interceptor) {std::lock_guard<std::mutex> lock(interceptorsMutex);interceptors.erase(std::remove(interceptors.begin(), interceptors.end(), interceptor),interceptors.end());}void clearInterceptors() {std::lock_guard<std::mutex> lock(interceptorsMutex);interceptors.clear();}// 配置管理void setDefaultTimeout(int timeout) { defaultTimeout = timeout; }void setDefaultHeaders(const std::map<std::string, std::string>& headers) { defaultHeaders = headers; }void setUserAgent(const std::string& userAgent) { defaultHeaders["User-Agent"] = userAgent; }void setProxy(const std::string& proxy, const std::string& auth) {this->proxy = proxy;this->proxyAuth = auth;}void setSSLVerification(bool verify) { verifySSL = verify; }void setDefaultRetryConfig(const RetryConfig& retryConfig) { defaultRetryConfig = retryConfig; }private:// 执行HTTP请求的核心方法Response performRequest(const RequestConfig& config) {Response response;// 解析URLURL_COMPONENTS urlComp = { 0 };urlComp.dwStructSize = sizeof(URL_COMPONENTS);urlComp.dwSchemeLength = -1;urlComp.dwHostNameLength = -1;urlComp.dwUrlPathLength = -1;std::wstring wUrl = std::wstring(config.url.begin(), config.url.end());if (!WinHttpCrackUrl(wUrl.c_str(), 0, 0, &urlComp)) {throw std::runtime_error("Invalid URL");}// 构建完整URL(包含查询参数)std::string fullUrl = config.url;if (!config.params.empty()) {fullUrl += "?";bool first = true;for (const auto& param : config.params) {if (!first) fullUrl += "&";fullUrl += param.first + "=" + param.second;first = false;}}// 创建会话HINTERNET hSession = WinHttpOpen(L"HttpRequest/1.0",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);if (!hSession) {throw std::runtime_error("Failed to create WinHTTP session");}// 设置超时WinHttpSetTimeouts(hSession, config.timeout, config.timeout, config.timeout, config.timeout);// 设置SSL选项if (!verifySSL) {DWORD flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA |SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |SECURITY_FLAG_IGNORE_CERT_CN_INVALID;WinHttpSetOption(hSession, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));}// 连接服务器HINTERNET hConnect = WinHttpConnect(hSession,urlComp.lpszHostName,urlComp.nPort,0);if (!hConnect) {WinHttpCloseHandle(hSession);throw std::runtime_error("Failed to connect to server");}// 创建请求std::wstring methodStr;switch (config.method) {case Method::GET: methodStr = L"GET"; break;case Method::POST: methodStr = L"POST"; break;case Method::PUT: methodStr = L"PUT"; break;case Method::DELETE_: methodStr = L"DELETE"; break;case Method::PATCH: methodStr = L"PATCH"; break;case Method::HEAD: methodStr = L"HEAD"; break;case Method::OPTIONS: methodStr = L"OPTIONS"; break;default: methodStr = L"GET"; break;}HINTERNET hRequest = WinHttpOpenRequest(hConnect,methodStr.c_str(),urlComp.lpszUrlPath,nullptr,WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,(urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0);if (!hRequest) {WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);throw std::runtime_error("Failed to create request");}// 设置请求头for (const auto& header : config.headers) {std::wstring wHeader = std::wstring(header.first.begin(), header.first.end()) + L": " +std::wstring(header.second.begin(), header.second.end());WinHttpAddRequestHeaders(hRequest, wHeader.c_str(), -1, WINHTTP_ADDREQ_FLAG_ADD);}// 发送请求BOOL bResults = FALSE;if (config.method == Method::POST || config.method == Method::PUT || config.method == Method::PATCH) {bResults = WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS,0,(LPVOID)config.data.c_str(),config.data.length(),config.data.length(),0);}else {bResults = WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS,0,WINHTTP_NO_REQUEST_DATA,0,0,0);}if (!bResults) {WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);throw std::runtime_error("Failed to send request");}// 接收响应bResults = WinHttpReceiveResponse(hRequest, nullptr);if (!bResults) {WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);throw std::runtime_error("Failed to receive response");}// 获取状态码DWORD statusCode = 0;DWORD statusCodeSize = sizeof(statusCode);WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,WINHTTP_HEADER_NAME_BY_INDEX,&statusCode,&statusCodeSize,WINHTTP_NO_HEADER_INDEX);response.statusCode = statusCode;response.url = std::wstring(fullUrl.begin(), fullUrl.end());// 获取响应头DWORD headerSize = 0;WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_RAW_HEADERS_CRLF,WINHTTP_HEADER_NAME_BY_INDEX,WINHTTP_NO_OUTPUT_BUFFER,&headerSize,WINHTTP_NO_HEADER_INDEX);if (headerSize > 0) {std::vector<wchar_t> headerBuffer(headerSize / sizeof(wchar_t));WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_RAW_HEADERS_CRLF,WINHTTP_HEADER_NAME_BY_INDEX,headerBuffer.data(),&headerSize,WINHTTP_NO_HEADER_INDEX);// 解析响应头std::wstring headersStr(headerBuffer.data());parseHeaders(headersStr, response.headers);}// 读取响应体std::wstring responseData;DWORD bytesAvailable = 0;do {bytesAvailable = 0;WinHttpQueryDataAvailable(hRequest, &bytesAvailable);if (bytesAvailable > 0) {std::vector<char> buffer(bytesAvailable);DWORD bytesRead = 0;if (WinHttpReadData(hRequest, buffer.data(), bytesAvailable, &bytesRead)) {// 将字节数据转换为宽字符std::string tempData(buffer.data(), bytesRead);responseData += std::wstring(tempData.begin(), tempData.end());}}} while (bytesAvailable > 0);response.data = responseData;// 清理资源WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return response;}// 解析响应头void parseHeaders(const std::wstring& headersStr, std::map<std::wstring, std::wstring>& headers) {std::wistringstream stream(headersStr);std::wstring line;// 跳过状态行std::getline(stream, line);while (std::getline(stream, line)) {if (line.empty() || line == L"\r") break;size_t colonPos = line.find(L':');if (colonPos != std::wstring::npos) {std::wstring key = line.substr(0, colonPos);std::wstring value = line.substr(colonPos + 1);// 去除前后空格和\rkey.erase(0, key.find_first_not_of(L" \t\r"));key.erase(key.find_last_not_of(L" \t\r") + 1);value.erase(0, value.find_first_not_of(L" \t\r"));value.erase(value.find_last_not_of(L" \t\r") + 1);headers[key] = value;}}}// 运行请求拦截器void runRequestInterceptors(RequestConfig& config) {std::lock_guard<std::mutex> lock(interceptorsMutex);for (auto& interceptor : interceptors) {if (!interceptor->onRequest(config)) {break;}}}// 运行响应拦截器void runResponseInterceptors(Response& response) {std::lock_guard<std::mutex> lock(interceptorsMutex);for (auto& interceptor : interceptors) {if (!interceptor->onResponse(response)) {break;}}}// 运行错误拦截器void runErrorInterceptors(const std::wstring& error) {std::lock_guard<std::mutex> lock(interceptorsMutex);for (auto& interceptor : interceptors) {if (!interceptor->onError(error)) {break;}}}// 执行带重试的请求Response performRequestWithRetry(const RequestConfig& config) {Response response;int retryCount = 0;while (retryCount <= config.retryConfig.maxRetries) {try {response = performRequest(config);response.success = response.statusCode >= 200 && response.statusCode < 300;// 检查是否需要重试if (!shouldRetry(response, config.retryConfig, retryCount)) {break;}}catch (const std::exception& e) {response.success = false;response.error = std::wstring(e.what(), e.what() + strlen(e.what()));// 检查异常是否应该重试if (!shouldRetryOnException(e.what(), config.retryConfig, retryCount)) {runErrorInterceptors(response.error);break;}}retryCount++;if (retryCount <= config.retryConfig.maxRetries) {// 等待重试间隔std::this_thread::sleep_for(std::chrono::milliseconds(config.retryConfig.retryDelay));}}return response;}// 判断是否应该重试(基于响应)bool shouldRetry(const Response& response, const RetryConfig& retryConfig, int retryCount) {if (retryCount >= retryConfig.maxRetries) {return false;}// 检查自定义重试条件if (retryConfig.shouldRetry && retryConfig.shouldRetry(response)) {return true;}// 检查服务器错误if (retryConfig.retryOnServerError && response.isServerError()) {return true;}return false;}// 判断是否应该重试(基于异常)bool shouldRetryOnException(const std::string& error, const RetryConfig& retryConfig, int retryCount) {if (retryCount >= retryConfig.maxRetries) {return false;}// 检查连接错误if (retryConfig.retryOnConnectionError) {std::string lowerError = error;std::transform(lowerError.begin(), lowerError.end(), lowerError.begin(), ::tolower);if (lowerError.find("connection") != std::string::npos ||lowerError.find("timeout") != std::string::npos ||lowerError.find("network") != std::string::npos ||lowerError.find("failed to connect") != std::string::npos ||lowerError.find("invalid url") != std::string::npos) {return true;}}return false;}private:std::vector<std::shared_ptr<Interceptor>> interceptors;std::mutex interceptorsMutex;int defaultTimeout;std::map<std::string, std::string> defaultHeaders;std::string proxy;std::string proxyAuth;bool verifySSL;RetryConfig defaultRetryConfig;};// HttpRequest类实现HttpRequest::HttpRequest() : pImpl(std::make_unique<HttpRequestImpl>()) {}HttpRequest::~HttpRequest() = default;HttpRequest::HttpRequest(HttpRequest&&) noexcept = default;HttpRequest& HttpRequest::operator=(HttpRequest&&) noexcept = default;// 同步请求方法Response HttpRequest::get(const std::string& url, const std::map<std::string, std::string>& params) {RequestConfig config;config.url = url;config.method = Method::GET;config.params = params;return pImpl->request(config);}Response HttpRequest::post(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::POST;config.data = data;config.headers = headers;return pImpl->request(config);}Response HttpRequest::put(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::PUT;config.data = data;config.headers = headers;return pImpl->request(config);}Response HttpRequest::delete_(const std::string& url, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::DELETE_;config.headers = headers;return pImpl->request(config);}Response HttpRequest::patch(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::PATCH;config.data = data;config.headers = headers;return pImpl->request(config);}Response HttpRequest::request(const RequestConfig& config) {return pImpl->request(config);}// 异步请求方法std::future<Response> HttpRequest::getAsync(const std::string& url, const std::map<std::string, std::string>& params) {RequestConfig config;config.url = url;config.method = Method::GET;config.params = params;return pImpl->requestAsync(config);}std::future<Response> HttpRequest::postAsync(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::POST;config.data = data;config.headers = headers;return pImpl->requestAsync(config);}std::future<Response> HttpRequest::putAsync(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::PUT;config.data = data;config.headers = headers;return pImpl->requestAsync(config);}std::future<Response> HttpRequest::deleteAsync(const std::string& url, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::DELETE_;config.headers = headers;return pImpl->requestAsync(config);}std::future<Response> HttpRequest::patchAsync(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {RequestConfig config;config.url = url;config.method = Method::PATCH;config.data = data;config.headers = headers;return pImpl->requestAsync(config);}std::future<Response> HttpRequest::requestAsync(const RequestConfig& config) {return pImpl->requestAsync(config);}// 拦截器管理void HttpRequest::addInterceptor(std::shared_ptr<Interceptor> interceptor) {pImpl->addInterceptor(interceptor);}void HttpRequest::addBusinessInterceptor(std::shared_ptr<BusinessInterceptor> interceptor) {pImpl->addInterceptor(interceptor);}void HttpRequest::addCommonInterceptor(std::shared_ptr<CommonInterceptor> interceptor) {pImpl->addInterceptor(interceptor);}void HttpRequest::removeInterceptor(std::shared_ptr<Interceptor> interceptor) {pImpl->removeInterceptor(interceptor);}void HttpRequest::clearInterceptors() {pImpl->clearInterceptors();}// 配置管理void HttpRequest::setDefaultTimeout(int timeout) {pImpl->setDefaultTimeout(timeout);}void HttpRequest::setDefaultHeaders(const std::map<std::string, std::string>& headers) {pImpl->setDefaultHeaders(headers);}void HttpRequest::setUserAgent(const std::string& userAgent) {pImpl->setUserAgent(userAgent);}void HttpRequest::setProxy(const std::string& proxy, const std::string& auth) {pImpl->setProxy(proxy, auth);}void HttpRequest::setSSLVerification(bool verify) {pImpl->setSSLVerification(verify);}void HttpRequest::setDefaultRetryConfig(const RetryConfig& retryConfig) {pImpl->setDefaultRetryConfig(retryConfig);}// 便捷方法std::string HttpRequest::methodToString(Method method) {switch (method) {case Method::GET: return "GET";case Method::POST: return "POST";case Method::PUT: return "PUT";case Method::DELETE_: return "DELETE";case Method::PATCH: return "PATCH";case Method::HEAD: return "HEAD";case Method::OPTIONS: return "OPTIONS";default: return "GET";}}Method HttpRequest::stringToMethod(const std::string& method) {std::string upperMethod = method;std::transform(upperMethod.begin(), upperMethod.end(), upperMethod.begin(), ::toupper);if (upperMethod == "GET") return Method::GET;if (upperMethod == "POST") return Method::POST;if (upperMethod == "PUT") return Method::PUT;if (upperMethod == "DELETE") return Method::DELETE_;if (upperMethod == "PATCH") return Method::PATCH;if (upperMethod == "HEAD") return Method::HEAD;if (upperMethod == "OPTIONS") return Method::OPTIONS;return Method::GET;}// 全局便捷函数实现namespace http {static std::shared_ptr<HttpRequest> defaultInstance = std::make_shared<HttpRequest>();std::shared_ptr<HttpRequest> create() {return std::make_shared<HttpRequest>();}Response get(const std::string& url, const std::map<std::string, std::string>& params) {return defaultInstance->get(url, params);}Response post(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {return defaultInstance->post(url, data, headers);}Response put(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {return defaultInstance->put(url, data, headers);}Response delete_(const std::string& url, const std::map<std::string, std::string>& headers) {return defaultInstance->delete_(url, headers);}Response patch(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {return defaultInstance->patch(url, data, headers);}std::future<Response> getAsync(const std::string& url, const std::map<std::string, std::string>& params) {return defaultInstance->getAsync(url, params);}std::future<Response> postAsync(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {return defaultInstance->postAsync(url, data, headers);}std::future<Response> putAsync(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {return defaultInstance->putAsync(url, data, headers);}std::future<Response> deleteAsync(const std::string& url, const std::map<std::string, std::string>& headers) {return defaultInstance->deleteAsync(url, headers);}std::future<Response> patchAsync(const std::string& url, const std::string& data, const std::map<std::string, std::string>& headers) {return defaultInstance->patchAsync(url, data, headers);}}} // namespace HttpRequest
总结 很python的cpp