0

I am trying to send http requests in C++. I have tried curl and cpr. In both of them I have some sort of connection reset which breaks the request and returns "NETWORK_RECEIVE_ERROR". I have checked the request with the WireShark and here is the output:

WireShark result

I am out of ideas what can the problem be.

Here is the code, using CPR library that I tried running:

{
    std::string url = "https://openapi.keycrm.app/v1/products/categories?limit=50";

    const int max_retries = 3;
    const int delay_seconds = 2;

    cpr::Header headers = {
        {"Content-type", "application/json"},
        {"Accept", "application/json"},
        {"Cache-Control", "no-cache"},
        {"Pragma", "no-cache"},
        {"Authorization", "Bearer " + token}
    };
    for (int i = 0; i < max_retries; i++) {
        auto categoriesResponse = cpr::Get(cpr::Url{ url }, headers);
        if (categoriesResponse.error) {
            std::cerr << "Error " << categoriesResponse.error.message << std::endl;
            if (i < max_retries - 1) {  // no need to sleep on last iteration
                std::this_thread::sleep_for(std::chrono::seconds(delay_seconds));
            }
            continue;
        }

        Json::Value value;
        Json::Reader reader;
        if (!reader.parse(categoriesResponse.text, value)) {
            std::cerr << "Failed to parse categories response: " << reader.getFormattedErrorMessages() << std::endl;
            continue;
        }
    }
}

And here is the code with CURL:

#include <curl/curl.h>
#include <json/json.h>
#include <thread>
#include <chrono>

// Callback function to collect the HTTP response data
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* out)
{
    size_t totalSize = size * nmemb;
    out->append((char*)contents, totalSize);
    return totalSize;
}

void BotHandler::loadCrmData()
{
    const std::string url = "https://openapi.keycrm.app/v1/products/categories?limit=50";
    const std::string url2 = "https://openapi.keycrm.app/v1/products?limit=50";

    const int max_retries = 3;
    const int delay_seconds = 2;

    // Initialize libcurl
    curl_global_init(CURL_GLOBAL_DEFAULT);
    CURL* curl = curl_easy_init();

    if(curl) {
        // Set common curl options
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        struct curl_slist* headers = NULL;
        headers = curl_slist_append(headers, "Content-type: application/json");
        headers = curl_slist_append(headers, "Accept: application/json");
        headers = curl_slist_append(headers, "Cache-Control: no-cache");
        headers = curl_slist_append(headers, "Pragma: no-cache");
        std::string auth = "Authorization: Bearer " + crmToken;
        headers = curl_slist_append(headers, auth.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // Make HTTP requests and parse responses in loop
        for (int i = 0; i < max_retries; i++) {
            // Categories Request
            curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
            std::string categoriesResponse;
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &categoriesResponse);
            CURLcode res = curl_easy_perform(curl);
            if(res != CURLE_OK) {
                std::cerr << "Error in Categories Request: " << curl_easy_strerror(res) << std::endl;
                std::this_thread::sleep_for(std::chrono::seconds(delay_seconds));
                continue;
            }
            Json::Value categoriesValue;
            Json::Reader categoriesReader;
            if (!categoriesReader.parse(categoriesResponse, categoriesValue)) {
                std::cerr << "Failed to parse categories response: " << categoriesReader.getFormattedErrorMessages() << std::endl;
                continue;
            }

            // Extract categories data from categoriesValue, populate your categories map

            // Products Request
            curl_easy_setopt(curl, CURLOPT_URL, url2.c_str());
            std::string productsResponse;
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &productsResponse);
            res = curl_easy_perform(curl);
            if(res != CURLE_OK) {
                std::cerr << "Error in Products Request: " << curl_easy_strerror(res) << std::endl;
                std::this_thread::sleep_for(std::chrono::seconds(delay_seconds));
                continue;
            }
            Json::Value productsValue;
            Json::Reader productsReader;
            if (!productsReader.parse(productsResponse, productsValue)) {
                std::cerr << "Failed to parse products response: " << productsReader.getFormattedErrorMessages() << std::endl;
                continue;
            }

            // Extract products data from productsValue, populate your products map

            // If both requests are successful, break the loop
            break;
        }

        // Clean up curl
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }

    curl_global_cleanup();
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • The wireshark image is useless. What is `NETWORK_RECEIVE_ERROR`? This is not a curl error code. – 273K Jun 23 '23 at 05:51

1 Answers1

0

The issue is related to Firewall settings. My firewall was blocking outbound HTTP requests.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 25 '23 at 15:09