libcurl ja write_data callback

Oli vaja C’s progeda asi, mis postiks data etteantud urlile ja logida vastus. Javas oleks see 0.5h töö ja Pythonis 5 minuti töö. C on teine maailm. Libcurliga tuli kirjutada selline kood

[c]

/**
* Curl write callback
* @param stream is **char, where to write data
*/
size_t write_data(void *ptr, size_t size, size_t nmemb, void *data)
{
char** p = (char **)data;
*p = (char*)malloc(size*nmemb+1);
memcpy(*p, ptr, size*nmemb+1);
return size*nmemb;
}

int post(const char* url, const char* message, char** reply)
{
/* what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, url);

/* send all data to this function */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, reply);

curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, message);
int rcode = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);

retutrn rcode;
}
int main(){
char * tmp = NULL;
post(”http://localhost:8080/url”, “xml sodi”, &tmp);
printf(”reply \”%s\”\n”, tmp);
}

[/c]

Muidu isegi kood töötas, aga replys oli pidevalt kusagil lõpupoole, peale %s sisestatud märgid. write_data jaoks oli cppunit test olemas ja kõik paistis toimivat. Mitte ei saa aru, mis toimus. Kui peale %s oli ainult \n, siis oli tmp väärtus see, mis vaja.

Probleem lahenes, kui suunasin proge väljundi cat -v sisendisse. Lihtne: reaalses elus oli vastuse lõpus ^M ehk CR, mis liigutab kursori reaalgusse. Seega kõik, mis peale %s tuli, kirjutati POST vastuse viimase rea algusse. Sellest arusaamiseks läks muidugi pool päeva, lisaks write_data kirjutamine ei möödunud täiesti valutult - kokku päev.

2 Responses to “libcurl ja write_data callback”

  1. ak

    Noh, selle 34 rida koodi võiks ju ka poole tunniga kirjutada kui libcurli oskaks ;-) Samas muidugi on su point õige - Javas ja Pythonis __on__ seda lihtsam teha.

  2. janno

    Noh pool päeva läks debugimise peale, miks seal lõpus alati mingi sodi oli. Ja tegelikult on see kood veel vigane, sest write_data võidakse mitu korda välja kutsuda.

Leave a Reply