Прокси может успешно получить 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 полным файлом.

Держите строку живой, пока передача не завершится. Если асинхронная запись в сокет затем пересылает её содержимое, держите эти байты живыми, пока и эта запись не завершится. Для больших ответов ограниченная потоковая схема предпочтительнее накопления всего тела.

Похожие статьи