Атрыманне бінарных адказаў libcurl у C++ std::string
Перадайце std::string як кантэкст зваротнага выкліку і дадавайце яўныя лікі байтаў пры атрыманні бінарных даных праз libcurl.
Проксі можа паспяхова атрымаць 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 поўным файлам.
Трымайце радок жывым, пакуль перадача не скончыцца. Калі асінхронны запіс у сокет потым перасылае яго змест, трымайце гэтыя байты жывымі, пакуль і гэты запіс не завершыцца. Для вялікіх адказаў абмежаваная паточная схема пераважней за назапашванне ўсяго цела.