问题背景,新开的国产化项目客户端需要通过https上传文件至服务端,服务端采用nginx模块简易搭建的https服务。原本的Windows项目下已经有一套通过Libcurl库上报的代码了,正常来说只需要ctrl+c ctrl+v即可。
windows源代码如下:
// do upload, will overwrite existing file
bool HttpsUpload(string strRemoteUrl, string strFilePath, const char *szUser, const char *szPsw, long timeout)
{
printf("== start HttpsUpload: \n");
bool curl_state = 0;
std::string strRemoteFileName;
size_t nPos = strRemoteUrl.find_last_of("/");
if (nPos != string::npos) //拆分上报路径和上报文件名
{
strRemoteFileName = strRemoteUrl.substr(nPos + 1);
strRemoteUrl = strRemoteUrl.substr(0, nPos);
}
if (strRemoteFileName.empty())
{
printf("== ##===== HttpsUpload get remote file name failed !!\n");
return 0;
}
// get user_key pair
char user_key[1024] = {0};
sprintf(user_key, "%s:%s", szUser, szPsw);
int iRetry = 3;
for (; iRetry > 0; --iRetry)
{
// init curl handle
CURL *curlhandle = curl_easy_init();
if (curlhandle == NULL)
{
printf("== ##===== HttpsUpload curl_easy_init failed !!\n");
return 0;
}
CURLcode ret = CURLE_GOT_NOTHING;
curl_mime *form = NULL;
curl_mimepart *field = NULL;
/* Create the form */
form = curl_mime_init(curlhandle);
/* Fill in the file upload field */
field = curl_mime_addpart(form);
curl_mime_name(field, "file");
curl_mime_filedata(field, strFilePath.c_str());
curl_mime_filename(field, strRemoteFileName.c_str());
curl_easy_setopt(curlhandle, CURLOPT_URL, strRemoteUrl.c_str());
curl_easy_setopt(curlhandle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
curl_easy_setopt(curlhandle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curlhandle, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curlhandle, CURLOPT_USERPWD, user_key);
curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, timeout);
curl_easy_setopt(curlhandle, CURLOPT_MIMEPOST, form);
ret = curl_easy_perform(curlhandle);
if (ret == CURLE_OK)
{
curl_state = true;
}
else
{
printf(" Upload File Failed. ErrCode %s \n", curl_easy_strerror(ret));
curl_state = false;
}
curl_easy_cleanup(curlhandle);
curl_mime_free(form);
if (curl_state)
break; //上传成功就直接退出
else
sleep(1); //等待1秒钟重试
}
printf("== ##===== end HttpsUpload!! %d \n", curl_state);
return curl_state;
}
int main()
{
int res_status = 0;
res_status = HttpsUpload("https://127.0.0.1:30000/upload/test.txt", "test.txt", "admin", "123456");
printf("FtpUpload ... %d \n", res_status);
return 0;
}
问题:
移至到Linux之后,服务端返回总是500错误如下:
查看服务端nginx日志,发现Linux下发送的请求协议为HTTP2.0返回500请求失败,HTTP1.1就返回200成功
于是新增一行代码解决:
curl_easy_setopt(curlhandle, CURLOPT_HTTP_VERSION, 2L);
解决后打印日志:
不知道为什么该nginx模块不支持http2.0协议
好文链接
发表评论