簡體   English   中英

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_LARGECURLOPT_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; } 

這個問題解決了Rocki 's和drew010的評論。

  1. 我已經刪除了CURLOPT_CUSTOMREQUESTCURLOPT_UPLOADCURLOPT_NOSIGNAL設置語句,因為不需要它們。
  2. 我還刪除了用於設置CURLOPT_POSTFIELDSIZE_LARGE的行,但如果在設置CURLOPT_COPYPOSTFIELDS之前設置它,則它可以正常工作。 如果在CURLOPT_COPYPOSTFIELDS之前尚未設置大小,則假定數據為零終止字符串; 否則,存儲的大小會通知庫有關要復制的字節數。 在任何情況下,除非發出另一個CURLOPT_POSTFIELDSCURLOPT_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM