簡體   English   中英

在 C/C++ 中制作 libcurl json 發布請求

[英]Making libcurl json post request in C/C++

我正在編寫一個 Qt 應用程序,並且我有一個應該注冊用戶的按鈕。 我正在使用以下庫:

  1. https://github.com/nlohmann/json <- 用於 json 序列化/反序列化
  2. 庫庫爾

我的目標是能夠向以下端點發出發布請求:http://localhost:8000/api/register

它期待 utf-8 的 Content-Type: application/json 的 POST,具有如下 json 主體:

{
    "username": "test", 
    "password": "test"
}

發布請求通過,但響應給出錯誤。 我試圖確定這是我的 libcurl 代碼的問題,還是我的 python django 應用程序的錯誤。

這是 libcurl 代碼的詳細 output :

E0125 08:52:00.886679  5816 API.h:43] {"password":"test2","username":"test"}
* STATE: INIT => CONNECT handle 0x2489d6b0bf8; line 1835 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* family0 == v4, family1 == v6
*   Trying 127.0.0.1:8000...
* STATE: CONNECT => CONNECTING handle 0x2489d6b0bf8; line 1896 (connection #0)
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
* STATE: CONNECTING => PROTOCONNECT handle 0x2489d6b0bf8; line 2030 (connection #0)
* STATE: PROTOCONNECT => DO handle 0x2489d6b0bf8; line 2051 (connection #0)
> POST /api/register HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Jellybean-Launcher
Content-Type: application/json; charset: utf-8
Accept: application/json
Content-Length: 8

* STATE: DO => DID handle 0x2489d6b0bf8; line 2147 (connection #0)
* STATE: DID => PERFORMING handle 0x2489d6b0bf8; line 2266 (connection #0)
* Mark bundle as not supporting multiuse
* HTTP 1.1 or later with persistent connection
< HTTP/1.1 400 Bad Request
< Date: Tue, 25 Jan 2022 16:52:00 GMT
< Server: WSGIServer/0.2 CPython/3.9.7
< Content-Type: application/json
< Vary: Accept, Cookie
< Allow: POST, OPTIONS
< X-Frame-Options: DENY
< Content-Length: 109
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
<
{"detail":"JSON parse error - 'utf-8' codec can't decode byte 0xdd in position 0: invalid continuation byte"}* STATE: PERFORMING => DONE handle 0x2489d6b0bf8; line 2465 (connection #0)
* multi_done: status: 0 prem: 0 done: 0
* Connection #0 to host 127.0.0.1 left intact
* Expire cleared (transfer 0x2489d6b0bf8)

這是 libcurl 代碼本身:

void RegisterUser(std::string username, std::string password)
{
    curl_global_init(CURL_GLOBAL_ALL);

    nlohmann::json json_data;
    json_data["username"] = "test";
    json_data["password"] = "test2";
    CURL* curl = curl_easy_init();
    CURLcode res;

    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, GetRegistrationURL().c_str());
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        
        struct curl_slist* chunk = NULL;
        chunk = curl_slist_append(chunk, "Content-Type: application/json; charset: utf-8");
        chunk = curl_slist_append(chunk, "Accept: application/json");

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
        curl_easy_setopt(curl, CURLOPT_POST, 1L);

        /* Set the expected POST size. */
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, sizeof(json_data.dump().c_str()));
        LOG(ERROR) << json_data.dump().c_str();
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.dump().c_str());
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "Jellybean-Launcher");


        res = curl_easy_perform(curl);
        if (res == CURLE_OK)
        {
            //res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
        }
        curl_easy_cleanup(curl);
        curl_slist_free_all(chunk);
    }

    curl_global_cleanup();

}

GetRegistrationURL()返回一個 std::string,其范圍取決於您是否處於開發構建中。 在開發構建期間,它總是通過 localhost,而在發布構建中,它通過實時 web url。

有誰知道我在這里可能做錯了什么?

第一個錯誤是curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, sizeof(json_data.dump().c_str())); . sizeof並沒有按照您的設想進行。

另一個錯誤是curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.dump().c_str()); 存儲指向臨時數據內部的指針json_data.dump() ,它會導致未定義的行為,可能會發送垃圾。 錯誤'utf-8' codec can't decode byte 0xdd提示。

curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)json_data.dump().size()));

curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, json_data.dump().c_str());

應該解決這個問題。 可以省略設置CURLOPT_POSTFIELDSIZE ,如果在CURLOPT_COPYPOSTFIELDS之前沒有設置大小,則假定數據是一個以空字符結尾的字符串 - 這是你的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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