Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird Characters outputed whenever ptr from CURL_WRITEFUNCTION is printed.

Tags:

c

curl

libcurl

I'm having a bit of an issue, here is my code (I'm using C):

#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <json/json.h>

size_t callback_func(void *ptr, size_t size, size_t count, void *stream) {
//json_object *json_obj = json_tokener_parse(ptr);
printf ("%s",(char*)ptr);

return count;

}

int main(void)
{   
      CURL *curl;
          CURLcode res;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://stream.twitter.com/1/statuses/filter.json?track=http");
    curl_easy_setopt(curl, CURLOPT_USERPWD, "Firrus:password");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
    curl_easy_perform(curl);



    /* always cleanup */ 
    curl_easy_cleanup(curl);


  }

  return 0;
}

The problem is that, every time ptr is printed, three weird (seemingly random) characters are also outputted at the top, e.g. 77D or 6DA. What do these characters mean? How can I remove them?


1 Answers

In according with the documentation the callback functions works on this way:

Function pointer that should match the following prototype: size_t function( void *ptr, size_t size, size_t nmemb, void *userdata); This function gets called by libcurl as soon as there is data received that needs to be saved. The size of the data pointed to by ptr is size multiplied with nmemb, it will not be zero terminated. Return the number of bytes actually taken care of. If that amount differs from the amount passed to your function, it'll signal an error to the library. This will abort the transfer and return CURLE_WRITE_ERROR. From 7.18.0, the function can return CURL_WRITEFUNC_PAUSE which then will cause writing to this connection to become paused. See curl_easy_pause(3) for further details.

This function may be called with zero bytes data if the transferred file is empty.

.....

Set the userdata argument with the CURLOPT_WRITEDATA option.

The callback function will be passed as much data as possible in all invokes, but you cannot possibly make any assumptions. It may be one byte, it may be thousands. The maximum amount of data that can be passed to the write callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE.

So your callback could be called many times. You need to store the data into your own structure which will keep track about the data read so far.

Try this solution:

#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    size_t size;
    char *payload;
}srvresponse;

size_t callback_func(void *ptr, size_t size, size_t count, void *stream) {
    //printf("%s", (char*) ptr);

    size_t realsize = size * count;
    printf("Chuncksize:%lu\n",realsize);
    srvresponse *ret = (srvresponse*)stream;
    //Increase the payload size
    ret->payload = realloc(ret->payload,ret->size + realsize + 1);
    //Copy the new data
    memcpy(&(ret->payload[ret->size]),ptr,realsize);
    //Update the size
    ret->size += realsize;
    //Terminate the string
    ret->payload[ret->size] = 0;
    printf("Read so far:%s",ret->payload);
    return realsize;

}

int main(void) {
    CURL *curl;

    srvresponse retdata;
    retdata.payload = malloc(1);//We increase the capacity later
    retdata.size = 0;

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://stream.twitter.com/1/statuses/filter.json?track=http");
        curl_easy_setopt(curl, CURLOPT_USERPWD, "user:pass");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&retdata);
        curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        curl_global_cleanup();


        if (retdata.payload){
            puts(retdata.payload);
            free(retdata.payload);
        }
    }

    return 0;
}
like image 185
Francesco Laurita Avatar answered Mar 11 '26 14:03

Francesco Laurita



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!