[英]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; }
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 ) 在Windows中,您必須使用以下函數初始化winsock內容
curl_global_init(CURL_GLOBAL_ALL);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.