libcurl: код состояния ответа http всегда NULL?

Я использую libcurl 7.29.0.

Все мои тестовые примеры работают нормально, когда сервер работает, но когда сервер недоступен, я получаю сообщение об ошибке CURLE_HTTP_RETURNED_ERROR.

В этом случае я всегда получаю ошибку curl CURLE_COULDNT_CONNECT, а код ответа HTTP — 0.

В соответствии с моим требованием мне нужен код ответа HTTP. Пожалуйста, предложите какое-то решение, спасибо заранее.

Ниже прикреплен API, который я использую для публикации данных.

int http_curl_post_response(char *url, char *post_data, char *response,
                            long int *responseCode) {
    CURL *ps_curl;
    CURLcode curl_status = CURLE_OK;
    struct curl_slist *headers = NULL; /* http headers to send with request */

    /* get a curl handle */
    ps_curl = curl_easy_init();
    if (ps_curl) {
        /* set content type */
        headers = curl_slist_append(headers, "Accept: application/json");
        headers = curl_slist_append(headers, "Content-Type: application/json");
        headers = curl_slist_append(headers, "charsets: utf-8");

        /* This is to intialize respone from curl */
        http_curl_respone ps_response;

        curl_easy_setopt(ps_curl, CURLOPT_URL, url);

        curl_easy_setopt(ps_curl, CURLOPT_HTTPHEADER, headers);

        curl_easy_setopt(ps_curl, CURLOPT_POSTFIELDS, post_data);

        curl_easy_setopt(ps_curl, CURLOPT_POSTFIELDSIZE, -1L);

        curl_easy_setopt(ps_curl, CURLOPT_FOLLOWLOCATION, 1L);

        /* This is to read response from curl */
        curl_easy_setopt(ps_curl, CURLOPT_WRITEFUNCTION, write_response_json);

        init_response(&ps_response);
        if (ps_response.pi1_response == NULL) {
            i4_curl_status = MEM_ALLOC_ERROR;
            goto HTTP_CURL_ERROR;
        }

        curl_easy_setopt(ps_curl, CURLOPT_WRITEDATA, &ps_response);

        curl_easy_setopt(ps_curl, CURLOPT_FAILONERROR, 1L);

        /* Perform the request, i4_curl_status will get the return code */
        curl_status = curl_easy_perform(ps_curl);
        if (curl_status != CURLE_OK) {
            if (curl_status == CURLE_HTTP_RETURNED_ERROR) {
                curl_easy_getinfo(ps_curl, CURLINFO_RESPONSE_CODE,
                                  responseCode);
                /* always cleanup */
                curl_easy_cleanup(ps_curl);
            }
            goto HTTP_CURL_ERROR;
        } else {
            memcpy(response, ps_response.pi1_response, ps_response.s_len);
            response[ps_response.s_len] = '\0';
        }

        /* always cleanup */
        curl_easy_cleanup(ps_curl);
        /* free headers */
        curl_slist_free_all(headers);

    HTTP_MEM_ERROR:
        if (ps_response.pi1_response) free(ps_response.pi1_response);
    } else {
        curl_status = CURLE_FAILED_INIT;
    }

HTTP_CURL_ERROR:

    return curl_status;
}

person Mehul patel    schedule 17.01.2019    source источник
comment
Вы назначаете i4_curl_status (кстати, я нигде не вижу, чтобы он объявлялся), но затем тестируете curl_status. Это опечатка?   -  person David Collins    schedule 17.01.2019
comment
Кстати: я бы предложил удалить теги node.js и c++ в этом вопросе и, возможно, попробовать более новую версию libcurl, если это возможно. (Версия 7.29 примерно шестилетней давности: curl.haxx.se/download .)   -  person David Collins    schedule 17.01.2019
comment
@DavidCollins, исправьте, это опечатка, с точки зрения функциональности проблем нет, работает нормально.   -  person Mehul patel    schedule 17.01.2019


Ответы (1)


... но когда сервер недоступен, я получаю сообщение об ошибке CURLE_HTTP_RETURNED_ERROR. В этом сценарии я всегда получаю ошибку curl CURLE_COULDNT_CONNECT, а код ответа HTTP равен 0.

Даже нет смысла проверять код ответа, если сервер недоступен и соединение не установлено. код ответа – это свойство ответа HTTP. Он записывается в части ответа HTTP (строка состояния), который HTTP-сервер отправляет обратно в ответ на HTTP-запрос, который libcurl отправляет от вашего имени. Если соединения нет, сервер не получил ваш запрос и ни о каком ответе не может быть и речи!

В соответствии с моим требованием мне нужен код ответа HTTP.

Если нет соединения, нет и ответа, а значит, и кода ответа.

В этом сценарии вы можете установить для переменной local responseCode значение -1, чтобы указать на сбой соединения:

*responseCode = -1;
person David Collins    schedule 17.01.2019
comment
есть ли возможность получить ошибку 404, когда сервер не работает или недоступен, потому что каждый почтовый запрос я использую новое соединение. - person Mehul patel; 17.01.2019
comment
@Mehulpatel: в отсутствие фактического ответа от сервера вы можете «подделать» код ответа, установив для локальной переменной responseCode какое-либо допустимое значение (например, 404 ). Но я думаю, что это вводит в заблуждение, так как это может обмануть пользователей вашего API, заставив их думать, что соединение действительно было установлено, даже если это не так. Вот почему я предложил использовать в данном случае -1: его нельзя спутать с законным кодом состояния. - person David Collins; 17.01.2019
comment
Я согласен с @DavidCollins в этом. В этом случае libcurl возвращает 0, так как ноль также нельзя спутать с законным статусом. Все правильные коды состояния HTTP имеют значение 100 или больше. - person Daniel Stenberg; 22.01.2019