Проксі можа паспяхова атрымаць 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 поўным файлам.

Трымайце радок жывым, пакуль перадача не скончыцца. Калі асінхронны запіс у сокет потым перасылае яго змест, трымайце гэтыя байты жывымі, пакуль і гэты запіс не завершыцца. Для вялікіх адказаў абмежаваная паточная схема пераважней за назапашванне ўсяго цела.

Падобныя артыкулы