#include "CurlHttp.h" #include #include "fmtlog.h" /* ================================================================================== * *********************************** 全局变量 ************************************* * ================================================================================== */ /* ================================================================================== * *********************************** 全局函数 ************************************* * ================================================================================== */ /** * @brief 写入回调函数 * * @param contents 接收到的内容 * @param size 内容大小,单位size_t * @param nmemb size_t的单位 * @param userp 用户传入的接收区指针 * @return size_t */ static size_t WriteStringCallback(void* contents, size_t size, size_t nmemb, std::string* userStr) { size_t newLength = size * nmemb; size_t oldLength = userStr->size(); try { userStr->resize(oldLength + newLength); } catch(std::bad_alloc &e) { FMTLOG_ERROR("{}", e.what()); return 0; } std::copy_n((char*)contents, newLength, userStr->begin() + oldLength); return size * nmemb; } /* ================================================================================== * *********************************** 成员函数 ************************************* * ================================================================================== */ CurlHttp::CurlHttp() { curl_global_init(CURL_GLOBAL_DEFAULT); } CurlHttp::~CurlHttp() { curl_global_cleanup(); } /** * @brief 获取信息 * * @param url 网址 * @param response 返回的数据 * @return true * @return false */ bool CurlHttp::Get(const std::string& url, std::string& response) { CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl == nullptr) { FMTLOG_ERROR("curl_easy_init() failed"); return false; } /* 设置为Get请求 */ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); /* 设置url */ curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); /* 设置重定向,遇到3xx返回值时自动重定向 */ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* 设置https协议 */ curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); /* 设置写入回调函数 */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); /* 设置超时 */ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); /* 发送请求 */ bool result = true; res = curl_easy_perform(curl); if(res != CURLE_OK) { FMTLOG_ERROR("Get failed: {}, Url: {}", curl_easy_strerror(res), url); result = false; } curl_easy_cleanup(curl); return true; } /* 获取信息,带有http头 */ bool CurlHttp::Get(const std::string& url, const std::vector& vecHeader, std::string& response) { CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl == nullptr) { FMTLOG_ERROR("curl_easy_init() failed"); return false; } /* 设置为Get请求 */ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); /* 设置url */ curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); /* 设置http头 */ struct curl_slist *headers = NULL; if(!vecHeader.empty()) { for(auto &header : vecHeader) { headers = curl_slist_append(headers, header.c_str()); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); } /* 设置重定向,遇到3xx返回值时自动重定向 */ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* 设置https协议 */ curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); /* 设置写入回调函数 */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); /* 设置超时 */ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); /* 发送请求 */ bool result = true; res = curl_easy_perform(curl); if(res != CURLE_OK) { FMTLOG_ERROR("Get failed: {}, Url:{}", curl_easy_strerror(res), url); result = false; } /* 清理内存 */ curl_slist_free_all(headers); curl_easy_cleanup(curl); return result; } /** * @brief 发送信息,不携带http头 * * @param url * @param postData * @param response * @return true * @return false */ bool CurlHttp::Post(const std::string& url, const std::string& postData, std::string& response) { CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl == nullptr) { FMTLOG_ERROR("curl_easy_init() failed"); return false; } /* 设置用户名密码,可能有的话 */ /* 设置动作功能和网址 */ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); /* 设置重定向,遇到3xx返回值时自动重定向 */ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* 设置https协议 */ curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); /* 设置包体 */ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postData.size()); /* 设置回调函数 */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); /* 设置连接超时和接收数据超时 */ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); /* 设置不发送任何信号,对于多线程有用 */ // curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); /* 发送请求 */ res = curl_easy_perform(curl); bool result = true; if(res != CURLE_OK) { FMTLOG_ERROR("Post failed: {}, Url: {}", curl_easy_strerror(res), url); result = false; } /* 清理curl */ curl_easy_cleanup(curl); return result; } /** * @brief 发送带有Http头和包体的信息 * * @param url 网址 * @param vecHeader http头,vector格式,每个元素为一行, * 如 User-Agent: Apifox/1.0.0 (https://apifox.com) * @param postData 发送的包体 * @param response 返回的数据 * @return true * @return false */ bool CurlHttp::Post(const std::string& url,const std::vector& vecHeader, const std::string& postData, std::string& response) { CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl == nullptr) { FMTLOG_ERROR("curl_easy_init() failed"); return false; } /* 设置动作功能和网址 */ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); /* 设置重定向,遇到3xx返回值时自动重定向 */ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* 设置https协议 */ curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); /* 设置http头 */ struct curl_slist *headers = NULL; if(!vecHeader.empty()) { for(auto &header : vecHeader) { headers = curl_slist_append(headers, header.c_str()); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); } /* 设置包体 */ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postData.size()); /* 设置回调函数 */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); /* 设置连接超时和接收数据超时 */ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); /* 设置不发送任何信号,对于多线程有用 */ // curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); /* 发送请求 */ res = curl_easy_perform(curl); bool result = true; if(res != CURLE_OK) { FMTLOG_ERROR("Post failed: {}, Url: {}", curl_easy_strerror(res), url); result = false; } curl_slist_free_all(headers); /* 清理curl */ curl_easy_cleanup(curl); return result; }