2010-08-25 14 views
3

J'essaie d'interagir avec l'API de Google Contact, et pour mettre à jour un contact sur le côté distant, j'ai besoin d'utiliser une requête PUT au lieu de POST.Comment envoyer des données PUT longues dans libcurl sans utiliser de pointeurs de fichier?

Étant donné que les données que je veux PUT est déjà en mémoire, je ne veux vraiment pas traiter de pointeurs de fichiers, ce qui semble être le comportement par défaut de CURLOPT_READDATA. Ainsi, je comprends que j'ai besoin d'utiliser CURLOPT_READFUNCTION en plus de cela, mais je n'arrive pas à comprendre la logique.

Voici la doc pertinente: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTREADFUNCTION

Impression des variables passées dans, je vois nmemb=16372 et size=1. Si mes données vont être de taille 100K, par exemple, quelle est la logique que je dois implémenter?

Merci.

Répondre

7

Vous devrez toujours utiliser CURLOPT_READDATA, cependant si vous utilisez CURLOPT_READFUNCTION, il peut s'agir de n'importe quel pointeur spécifié par l'utilisateur. Vous pouvez créer une structure simple comme:

struct put_data 
{ 
    char *data; 
    size_t len; 
}; 

data est les données PUT et len est la longueur (restant).

Ensuite, définissez CURLOPT_READDATA sur un pointeur vers une instance initialisée de cette structure. Vous serez passé en CURLOPT_READFUNCTION en tant que userdata. Dans cette fonction, faire quelque chose comme:

size_t curl_size = nmemb * size; 
size_t to_copy = (userdata->len < curl_size) ? userdata->len : curl_size; 
memcpy(ptr, userdata->data, to_copy); 
userdata->len -= to_copy; 
userdata->data += to_copy; 
return to_copy; 

Cette figure essentiellement le montant à copier, des copies, puis met à jour la longueur et pointeur. Sur la ligne to_copy, nous calculons le minimum car ils sont limités à la fois par la quantité restante et la taille du tampon de curl. Finalement, nous retournons le nombre d'octets copiés, comme requis par curl. Lorsque vous êtes à la fin du contenu user_data->len (et donc to_copy) sera 0. Rien ne sera copié et le retour 0 termine le transfert.

+0

Exactement ce que je cherchais. Les choses ont encore du sens. Merci d'avoir sauvé ma santé mentale. –

1

C'EST la bonne façon de le faire.

Une chose à garder à l'esprit est que vous devez définir la taille du fichier:

curl_easy_setopt(curlHandle, CURLOPT_INFILESIZE,(curl_off_t)putData.size); 

Sinon, votre serveur peut jeter une erreur indiquant que la longueur de la demande n'a pas été précisée. PutData est une instance de la structure put_data.