Настройка CURLOPT_FAILONERROR должна сделать это для ошибок 4xx и 5xx.
Когда эта опция используется и обнаружена ошибка, это приведет к закрытию соединения и CURLE_HTTP_RETURNED_ERROR возвращается
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
Закрытие соединения не очень хорошо для меня, важно его повторно использовать. Вы можете думать о чем-нибудь еще?
К сожалению, я не могу найти способ заставить CURLOPT_FAILONERROR
не закрывать соединение.
Другой вариант - сделать функцию записи осведомленной. ответа. К сожалению, дескриптор curl не передается в обратный вызов.
Мы можем сделать переменную curl
глобальной. Или же мы можем воспользоваться опцией void *userdata
для обратного вызова write и передать структуру, содержащую как дескриптор curl, так и буфер.
Вот примерный набросок, демонстрирующий, как обратный вызов write может получить доступ к ответу. код, а также сохранить тело ответа.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
typedef struct {
CURL *curl;
char *buf;
} curl_write_data;
size_t curlWriteHandler(char* chars, size_t size, size_t nmemb, void* userp) {
curl_write_data *curl_data = (curl_write_data*)userp;
long response_code;
curl_easy_getinfo(curl_data->curl, CURLINFO_RESPONSE_CODE, &response_code);
printf("Response: %ld\n", response_code);
// Now we can save if we like.
if( response_code < 300 ) {
curl_data->buf = malloc(size*(nmemb+1));
strcpy(curl_data->buf, chars);
strcat(curl_data->buf, "\0");
return size * nmemb;
}
else {
return 0;
}
}
int main() {
CURL *curl = curl_easy_init();
if(!curl) {
perror("Cant' init curl");
}
curl_write_data curl_data = { .curl = curl, .buf = NULL };
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/alsdfjalj");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteHandler);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &curl_data);
curl_easy_perform(curl);
if( curl_data.buf ) {
puts(curl_data.buf);
}
}
Я не уверен, что это лучшая идея, то, что я придумал.