结构顺序如下:
配置请求头->数据准备->初始化libcurl->设置libcurl属性->设置请求头->执行libcurl->释放libcurl
部分执行源码:
typedef struct _DUMP_PROCESS_INFO
{
WCHAR filePath[MAX_PATH];
WCHAR exeName[MAX_PATH];
WCHAR canonFolderName[MAX_PATH];
DWORD dwProcessId;
DWORD dwThreadId;
bool bMiniDump;
bool bUploadDump;
EXCEPTION_POINTERS *pException;
}DUMP_PROCESS_INFO, *PDUMP_PROCESS_INFO;
void uploadDump(DUMP_PROCESS_INFO *dumpInfo)
{
// get filename
std::string folderName = global::wstr2str(dumpInfo->canonFolderName);
std::string filePath = global::wstr2str(dumpInfo->filePath);
size_t pos = filePath.find_last_of("\\");
std::string fileName = filePath.substr(pos + 1);
std::string fileUrl;
std::ostringstream ss;
ss << "/" << BUCKET_DUMP_NAME << "/" << folderName << "/" << fileName;
std::string canonRes = ss.str();
ss.str("");
ss << "https://" << BUCKET_DUMP_NAME << "." << OSS_ENDPOINT << "/" << folderName <<
"/" << fileName;
fileUrl = ss.str();
//打开文件将需要上传的文件加载到内存
FILE* fd;
fopen_s(&fd, filePath.c_str(), "rb");
if (!fd)
{
global::outputDebugPrintf("sdcrash open file is error");
return;
}
// get the file size
struct _stat64i32 fileInfo;
if (_fstat(_fileno(fd), &fileInfo) != 0)
{
global::outputDebugPrintf("dumpfile size is null");
return;
}
//上传配置的请求头,时间戳,日期,token,authorization请求标头包含用于向服务器认证用户代理的凭证
std::string szDate = getGmTime();
std::string header_date = std::string("Date:") + szDate;
std::string header_content_type = getContentType();
std::string header_authorization = getOssAuthorization(szDate, canonRes);
std::string header_token = OSS_TOKEN";";
CURLcode res;
long responseCode = 0;
curl_off_t speed_upload, total_time;
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL* pCurl = curl_easy_init();
if (pCurl)
{
curl_easy_setopt(pCurl, CURLOPT_URL, fileUrl.c_str());//上传服务器路径
curl_easy_setopt(pCurl, CURLOPT_UPLOAD, 1L); //启用上传
curl_easy_setopt(pCurl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);//上传协议
curl_easy_setopt(pCurl, CURLOPT_CUSTOMREQUEST, "PUT");//请求方式
curl_easy_setopt(pCurl, CURLOPT_PUT, 1); //启用PUT请求方式
curl_easy_setopt(pCurl, CURLOPT_READFUNCTION, read_callback);//读取数据后返回callback
curl_easy_setopt(pCurl, CURLOPT_READDATA, (void*)fd); //需要上传的目标数据流
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE_LARGE, fileInfo.st_size);//需要上传目标数据的大小
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L);//关闭校验证书真实性
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0L);//关闭校验证书中主机名
curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L); //生产环境,默认关闭,使库显示有关其在此句柄上的操作的大量详细信息。 对 libcurl 和/或协议调试和理解很有用
curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 30L);//超时秒为单位
curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10L);//链接超时,秒为单位
std::string response = "";
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, write_callback);//写入数据回调
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &response);//传递给写回调数据指针,win32不写可能会crash
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, header_content_type.c_str());
headers = curl_slist_append(headers, header_date.c_str());
headers = curl_slist_append(headers, header_token.c_str());
headers = curl_slist_append(headers, header_authorization.c_str());
curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, headers);//自定义http请求头
res = curl_easy_perform(pCurl);//执行libcurl,并获取执行结果
if (res != CURLE_OK)
{
global::outputDebugPrintf("curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else
{
curl_easy_getinfo(pCurl, CURLINFO_SPEED_UPLOAD_T, &speed_upload);
curl_easy_getinfo(pCurl, CURLINFO_TOTAL_TIME_T, &total_time);
curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &responseCode);
//打印上传内容的附加信息
global::outputDebugPrintf("Speed: %" CURL_FORMAT_CURL_OFF_T " bytes/sec during %"
CURL_FORMAT_CURL_OFF_T ".%06ld seconds\n",
speed_upload,
(total_time / 1000000), (long)(total_time % 1000000));
}
/* always cleanup */
curl_easy_cleanup(pCurl);
}
fclose(fd);
}