Проксі може успішно отримати HTML і все ж пошкодити зображення, копіюючи його в буфер C++. Перш ніж змінювати протокол проксі, перевірте зворотний виклик отримання та об'єкт, переданий як його контекст.

CURLOPT_WRITEDATA надає вказівник на зворотний виклик запису. Без власного зворотного виклику стандартний записувач libcurl очікує FILE *. Адреса на кшталт &response, де response — це std::string, має сенс лише тоді, коли ваш зворотний виклик приводить цей контекст назад до потрібного типу.

static size_t receive(char* data, size_t size,
                      size_t count, void* context) {
    const size_t bytes = size * count;
    auto* body = static_cast<std::string*>(context);
    try {
        body->append(data, bytes);
    } catch (...) {
        return 0;
    }
    return bytes;
}

Зареєструйте обидві половини на простому дескрипторі, що використовується для передавання:

std::string response;
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);

Виклик append використовує передану кількість байтів. Дані зворотного виклику не завершуються нулем, і зображення може містити нульові байти; вимірювання через strlen втратило б частину тіла. Відповідь також може надходити через багато викликів різного розміру.

Повернення спожитої кількості байтів приймає фрагмент. Повернення іншої кількості перериває передавання з помилкою запису. Захист винятків не дає збою виділення пам'яті вийти за межі зворотного виклику C; викликач усе одно має перевірити результат передавання, перш ніж вважати response повним файлом.

Тримайте рядок живим, доки передавання не завершиться. Якщо асинхронний запис у сокет потім пересилає його вміст, тримайте ці байти живими, доки й цей запис не завершиться. Для великих відповідей обмежена потокова схема краща за накопичення всього тіла.

Схожі статті