【发布时间】:2016-05-13 17:03:24
【问题描述】:
我正在向 Cloudinary API 发送一个 POST 多部分,以上传我使用 openCV 捕获和缓冲的图像。 Cloudinary 给了我一个 HTTP 400。我已经测试了使用 chrome 应用程序 PostMan 上传图像并且可以正常工作,所以我的 POST 请求中一定有错误,或者我缓冲数据的方式有问题。
以下是他们如何描述对 API 的调用: http://cloudinary.com/documentation/upload_images#uploading_with_a_direct_call_to_the_api
我已经在这几天了,任何帮助将不胜感激。一旦弄清楚这一点,我将把这段代码提交给 Cloudinary,这样其他使用 C/C++ 的用户就可以轻松地上传到他们的平台,而不会像我经历过的那样痛苦。
//Clone frame and encode into buffer as JPEG
cv::Mat hand_roi = frame.clone();
std::vector<unsigned char> imgBuffer;
imencode(".jpg", hand_roi, imgBuffer);
//Buffer to String with pointer/length
std::string imgStrBuff = std::string(imgBuffer.begin(), imgBuffer.end());
char *imgBuffPtr = (char *)&imgStrBuff;
long imgBuffLength = static_cast<long>(imgStrBuff.size());
//Unix time in (s)
std::time_t t = std::time(0);
std::string unixTime = std::to_string(t);
//API_Secret:
std::string APISecret = "XXXXXXXXXXXXXXXXXXXXX";
//Create SHA1 signature required by cloudinary
std::string hashString = "timestamp=" + unixTime + APISecret;
std::string authSig = sha1(hashString);
//POST URL
std::string url = "https://api.cloudinary.com/v1_1/xxxxxxxxxxx/image/upload";
/*-----CURL SETUP-----*/
//Set headers as null
struct curl_slist *headers = NULL;
struct curl_httppost *formpost = NULL;
struct curl_httppost *lastptr = NULL;
//Data type
curl_slist_append(headers, "Content-Type: multipart/form-data");
curl_global_init(CURL_GLOBAL_ALL);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "api_key",
CURLFORM_COPYCONTENTS, "xxxAPIKeyxxx",
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "timestamp",
CURLFORM_COPYCONTENTS, unixT.c_str(),
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "signature",
CURLFORM_COPYCONTENTS, authSig.c_str(),
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "file",
CURLFORM_BUFFER, "random_img_name.jpg",
CURLFORM_BUFFERPTR, imgBuffPtr,
CURLFORM_BUFFERLENGTH, imgBuffLength,
CURLFORM_END);
//init easy_curl
CURL* curl = curl_easy_init();
if(!curl)
return false;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
res = curl_easy_perform(curl);
我基本上已经阅读了所有的 libcurl 文档,但我无法弄清楚为什么这些请求会被拒绝。
【问题讨论】:
-
没有语言“C/C++”。只有两种不同的语言 C 和 C++。
-
使用数据包嗅探器(如 Wireshark)查看 Chrome 实际发布的内容,然后将其与 libcurl 发布的内容进行比较。这将帮助您查明 libcurl 调用中的错误/缺失。
-
不需要 CURLOPT_HTTPHEADER,当您使用 CURLOPT_HTTPPOST 时,libcurl 会自行设置正确的内容类型。
-
除了@RemyLebeau 的评论,您可以只使用浏览器的开发工具,Chrome 和Firefox 都有内置工具,可以让您查看它发送的POST 请求。将其与您的 libcurl 帖子发送的内容进行比较。相应调整。