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