1--- 2c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 3SPDX-License-Identifier: curl 4Title: curl_mime_data_cb 5Section: 3 6Source: libcurl 7See-also: 8 - curl_easy_duphandle (3) 9 - curl_mime_addpart (3) 10 - curl_mime_data (3) 11 - curl_mime_name (3) 12Protocol: 13 - HTTP 14 - IMAP 15 - SMTP 16--- 17 18# NAME 19 20curl_mime_data_cb - set a callback-based data source for a mime part's body 21 22# SYNOPSIS 23 24~~~c 25#include <curl/curl.h> 26 27size_t readfunc(char *buffer, size_t size, size_t nitems, void *arg); 28 29int seekfunc(void *arg, curl_off_t offset, int origin); 30 31void freefunc(void *arg); 32 33CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize, 34 curl_read_callback readfunc, 35 curl_seek_callback seekfunc, 36 curl_free_callback freefunc, void *arg); 37~~~ 38 39# DESCRIPTION 40 41curl_mime_data_cb(3) sets the data source of a mime part's body content 42from a data read callback function. 43 44*part* is the part's to assign contents to. 45 46*readfunc* is a pointer to a data read callback function, with a signature 47as shown by the above prototype. It may not be set to NULL. 48 49*seekfunc* is a pointer to a seek callback function, with a signature as 50shown by the above prototype. This function is used when resending data (i.e.: 51after a redirect); this pointer may be set to NULL, in which case a resend 52might not be not possible. 53 54*freefunc* is a pointer to a user resource freeing callback function, with 55a signature as shown by the above prototype. If no resource is to be freed, it 56may safely be set to NULL. This function is called upon mime structure 57freeing. 58 59*arg* is a user defined argument to callback functions. 60 61The read callback function gets called by libcurl as soon as it needs to 62read data in order to send it to the peer - like if you ask it to upload or 63post data to the server. The data area pointed at by the pointer *buffer* 64should be filled up with at most *size* multiplied with *nitems* number 65of bytes by your function. 66 67Your read function must then return the actual number of bytes that it stored 68in that memory area. Returning 0 signals end-of-file to the library and cause 69it to stop the current transfer. 70 71If you stop the current transfer by returning 0 "pre-maturely" (i.e. before 72the server expected it, like when you have said you intend to upload N bytes 73and yet you upload less than N bytes), you may experience that the server 74"hangs" waiting for the rest of the data that does not come. 75 76The read callback may return *CURL_READFUNC_ABORT* to stop the current 77operation immediately, resulting in a *CURLE_ABORTED_BY_CALLBACK* error 78code from the transfer. 79 80The callback can return *CURL_READFUNC_PAUSE* to cause reading from this 81connection to pause. See curl_easy_pause(3) for further details. 82 83The seek function gets called by libcurl to rewind input stream data or to 84seek to a certain position. The function shall work like fseek(3) or lseek(3) 85and it gets SEEK_SET, SEEK_CUR or SEEK_END as argument for *origin*, 86although libcurl currently only passes SEEK_SET. 87 88The callback function must return *CURL_SEEKFUNC_OK* on success, 89*CURL_SEEKFUNC_FAIL* to cause the upload operation to fail or 90*CURL_SEEKFUNC_CANTSEEK* to indicate that while the seek failed, libcurl 91is free to work around the problem if possible. The latter can sometimes be 92done by instead reading from the input or similar. 93 94Care must be taken if the part is bound to a curl easy handle that is later 95duplicated: the *arg* pointer argument is also duplicated, resulting in 96the pointed item to be shared between the original and the copied handle. In 97particular, special attention should be given to the *freefunc* procedure 98code since it then gets called twice with the same argument. 99 100# EXAMPLE 101 102Sending a huge data string causes the same amount of memory to be allocated: 103to avoid overhead resources consumption, one might want to use a callback 104source to avoid data duplication. In this case, original data must be retained 105until after the transfer terminates. 106~~~c 107#include <string.h> /* for memcpy */ 108char hugedata[512000]; 109 110struct ctl { 111 char *buffer; 112 curl_off_t size; 113 curl_off_t position; 114}; 115 116size_t read_callback(char *buffer, size_t size, size_t nitems, void *arg) 117{ 118 struct ctl *p = (struct ctl *) arg; 119 curl_off_t sz = p->size - p->position; 120 121 nitems *= size; 122 if(sz > nitems) 123 sz = nitems; 124 if(sz) 125 memcpy(buffer, p->buffer + p->position, sz); 126 p->position += sz; 127 return sz; 128} 129 130int seek_callback(void *arg, curl_off_t offset, int origin) 131{ 132 struct ctl *p = (struct ctl *) arg; 133 134 switch(origin) { 135 case SEEK_END: 136 offset += p->size; 137 break; 138 case SEEK_CUR: 139 offset += p->position; 140 break; 141 } 142 143 if(offset < 0) 144 return CURL_SEEKFUNC_FAIL; 145 p->position = offset; 146 return CURL_SEEKFUNC_OK; 147} 148 149int main(void) 150{ 151 CURL *curl = curl_easy_init(); 152 if(curl) { 153 curl_mime *mime = curl_mime_init(curl); 154 curl_mimepart *part = curl_mime_addpart(mime); 155 struct ctl hugectl; 156 157 hugectl.buffer = hugedata; 158 hugectl.size = sizeof(hugedata); 159 hugectl.position = 0; 160 curl_mime_data_cb(part, hugectl.size, read_callback, seek_callback, NULL, 161 &hugectl); 162 } 163} 164~~~ 165 166# AVAILABILITY 167 168As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. 169 170# RETURN VALUE 171 172CURLE_OK or a CURL error code upon failure. 173