Un proxy poate obține HTML cu succes și totuși poate corupe o imagine în timp ce o copiază într-un buffer C++. Înainte de a schimba protocolul proxy-ului, verificați funcția de revenire pentru recepție și obiectul transmis ca context al acesteia.

CURLOPT_WRITEDATA furnizează un pointer către funcția de revenire pentru scriere. Fără o funcție de revenire personalizată, scriitorul implicit al libcurl așteaptă un FILE *. O adresă precum &response, unde response este un std::string, are sens doar când funcția de revenire convertește acel context înapoi la tipul dorit.

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;
}

Înregistrați ambele jumătăți pe handle-ul simplu folosit pentru transfer:

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

Apelul append folosește numărul de octeți livrat. Datele funcției de revenire nu sunt terminate cu zero, iar o imagine poate conține octeți zero; măsurarea cu strlen ar pierde o parte din corp. Un răspuns poate sosi și prin multe apeluri de dimensiuni diferite.

Returnarea numărului de octeți consumați acceptă fragmentul. Returnarea unui alt număr întrerupe transferul cu o eroare de scriere. Protecția la excepții împiedică o eroare de alocare să scape prin granița funcției de revenire C; apelantul trebuie totuși să verifice rezultatul transferului înainte de a trata response ca un fișier complet.

Păstrați șirul în viață până când transferul se termină. Dacă o scriere asincronă în socket îi transmite apoi conținutul, păstrați acei octeți în viață până când și acea scriere se termină. Pentru răspunsuri mari, o organizare de streaming limitată este preferabilă acumulării întregului corp.

Articole similare