Как отправить длинные данные PUT в libcurl без использования файловых указателей?

Я пытаюсь взаимодействовать с Google Contact API, и чтобы обновить контакт на удаленной стороне, мне нужно использовать запрос PUT вместо POST.

Поскольку данные, которые я хочу поместить в PUT, уже находятся в памяти, я действительно не хочу иметь дело с файловыми указателями, которые, по-видимому, являются поведением по умолчанию CURLOPT_READDATA. Таким образом, я понимаю, что мне нужно использовать CURLOPT_READFUNCTION в дополнение к этому, но я не понимаю логику.

Вот соответствующий документ: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html

Печать переменных передается, я вижу nmemb=16372 а также size=1, Например, если мои данные будут иметь размер 100 КБ, какую логику мне необходимо реализовать?

Спасибо.

2 ответа

Решение

Вы все еще хотите использовать CURLOPT_READDATAОднако, если вы используете CURLOPT_READFUNCTION, это может быть любой указанный пользователем указатель. Вы можете создать простую структуру, такую ​​как:

struct put_data
{
  char *data;
  size_t len;
};

где data это данные PUT и len это длина (оставшаяся).

Затем установите CURLOPT_READDATA на указатель на инициализированный экземпляр этой структуры. Вы будете переданы в CURLOPT_READFUNCTION как userdata, В этой функции сделайте что-то вроде:

size_t curl_size = nmemb * size;
size_t to_copy = (userdata->len < curl_size) ? userdata->len : curl_size;
memcpy(ptr, userdata->data, to_copy);
userdata->len -= to_copy;
userdata->data += to_copy;
return to_copy;

Это в основном вычисляет сумму для копирования, копирует ее, затем обновляет длину и указатель. На to_copy В строке, мы вычисляем минимум, потому что были ограничены как оставшимся количеством, так и размером буфера curl. Наконец, мы возвращаем количество скопированных байтов, как того требует curl. Когда вы в конце контента user_data->len (и поэтому to_copy) будет 0. Ничего не будет скопировано, и возврат 0 завершает передачу.

Это правильный способ сделать это.

Еще одна вещь, которую нужно иметь в виду, это то, что вы ДОЛЖНЫ установить РАЗМЕР ФАЙЛА:

curl_easy_setopt(curlHandle, CURLOPT_INFILESIZE,(curl_off_t)putData.size);

В противном случае ваш сервер может выдать ошибку о том, что длина запроса не указана.

putData является экземпляром структуры put_data.

Другие вопросы по тегам