Curl命令行有效,C++Curl库无效
Curl command line works, C++ curl library does not
我正试图通过C++的curl库进行一些请求。我可以成功地完成我的请求,并通过命令行获得正确的响应,但我无法通过C++代码得到正确的响应。我的命令行命令看起来像这个
curl -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'Authorization: <some_hash_value>' -k <my_full_url> -data '<my_json_string>'
这很好。现在我尝试在C++代码中执行同样的请求。我的代码看起来像这个
void performRequest(const std::string& json, const void* userData, CallbackFunction callback)
{
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, (std::string("Authorization: ") + m_authorization).c_str());
CURL* curlHandle = curl_easy_init();
if (!curlHandle)
{
std::cerr << "Curl handler initialization failed";
}
curl_easy_setopt(curlHandle, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, headers);
// specify target URL, and note that this URL should include a file name, not only a directory
curl_easy_setopt(curlHandle, CURLOPT_URL, m_url.c_str());
// enable uploading
curl_easy_setopt(curlHandle, CURLOPT_UPLOAD, 1L);
// set HTTP method to POST
curl_easy_setopt(curlHandle, CURLOPT_CUSTOMREQUEST, "POST");
// set json data; I use EXACTLY the same string as in command line
curl_easy_setopt(curlHandle, CURLOPT_COPYPOSTFIELDS, json.c_str());
// set data size
curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDSIZE_LARGE, json.size());
// set user data for getting it in response
curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, userData); // pointer to a custom struct
// set callback function for getting response
curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, callback); // some callback
// send request
curl_easy_perform(curlHandle);
curl_easy_cleanup(curlHandle);
curl_slist_free_all(headers);
}
然而,由于某种原因,我在来自服务器的响应中收到了一个错误,从中我可以假设我的代码的请求与命令行的命令不等价。尸体似乎没有被送来。当我使用CURLOPT_DEBUGFUNCTION转储调试信息时,我看不到我的请求Json主体。
这里有什么问题?我做错了什么?有什么想法吗?
以下是适用于您的示例代码。
注意我:
-
删除了
CURLOPT_UPLOAD
,因为看起来并不是在上传什么,而是在做一个简单的POST
。 -
将
CURLOPT_CUSTOMREQUEST
更改为CURLOPT_POST
(这并不重要),但我发现它更干净。 -
重新排序的
CURLOPT_POSTFIELDSIZE_LARGE
和CURLOPT_COPYPOSTFIELDS
-
为了这个示例代码,删除了
CURLOPT_WRITEDATA
行。
我只通过连接到nc -l localhost 80
的实例测试了以下内容
static size_t callback(char *ptr, size_t size, size_t nmemb, void *userdata) { string s(ptr); cout << s << endl; return size * nmemb; } int main(int argc, char** argv) { string m_authorization("PWNED"); string m_url("http://localhost"); string m_json("{}"); curl_global_init(CURL_GLOBAL_ALL); CURL* curlHandle = curl_easy_init(); struct curl_slist* headers = nullptr; headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, (std::string("Authorization: ") + m_authorization).c_str()); curl_easy_setopt(curlHandle, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, headers); // specify target URL, and note that this URL should include a file name, not only a directory curl_easy_setopt(curlHandle, CURLOPT_URL, m_url.c_str()); // <= You are not uploading anything actually, this is a simple POST with payload // enable uploading // curl_easy_setopt(curlHandle, CURLOPT_UPLOAD, 1L); // set HTTP method to POST curl_easy_setopt(curlHandle, CURLOPT_POST, 1L); // set data size before copy curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDSIZE_LARGE, m_json.size()); // set json data; I use EXACTLY the same string as in command line curl_easy_setopt(curlHandle, CURLOPT_COPYPOSTFIELDS, m_json.c_str()); // set user data for getting it in response // curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, userData); // pointer to a custom struct // set callback function for getting response curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, callback); // some callback // send request curl_easy_perform(curlHandle); curl_slist_free_all(headers); curl_easy_cleanup(curlHandle); curl_global_cleanup(); return 0; }
在windows中,您必须使用以下函数初始化winsock内容
curl_global_init(CURL_GLOBAL_ALL);
根据Rocki和drew010的意见,问题得到了解决。
- 我已经删除了
CURLOPT_CUSTOMREQUEST
、CURLOPT_UPLOAD
和CURLOPT_NOSIGNAL
设置语句,因为不需要它们 - 我还删除了用于设置
CURLOPT_POSTFIELDSIZE_LARGE
的行,尽管如果它是在设置CURLOPT_COPYPOSTFIELDS
之前设置的,它也可以正常工作。如果在CURLOPT_COPYPOSTFIELDS
之前没有设置大小,则假设数据是以零结尾的字符串;否则,存储的大小会通知库要复制的字节计数。在任何情况下,除非发出另一个CURLOPT_POSTFIELDS
或CURLOPT_COPYPOSTFIELDS
选项,否则不得在CURLOPT_COPYPOSTFIELDS
之后更改大小。(请参阅:curl.haxx.se/libcurl/c/CURLOPT_COPYPOSTFIELDS.html)
相关文章:
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 在C++中使用cURL和多线程
- 无法访问嵌套类.类的使用无效
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题
- FFMPEG配置文件级别id大小无效
- 错误:从"int"到枚举c++的转换无效
- 如何修复此错误:className::className的无效使用
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- C++-模板嵌套类的引用初始化无效
- 错误:无效的预处理指令 #i 的意思是 #if?
- 多维数组 C++ 中数组下标的类型"int[int]"无效
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- 从 'int' 到 'int*' CPP 的转换无效
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- C++ PTHREADS - 无效转换无效*(*)()到无效*(*)(无效*)
- 声明为无效的变量或字段'...' Ardunio 编译器上的错误
- Curl命令行有效,C++Curl库无效